Replace Min, Max and Abs by std::min, std::max and std::abs
[scilab.git] / scilab / modules / elementary_functions / sci_gateway / cpp / sci_clean.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - DIGITEO - Cedric DELAMARRE
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12 /*--------------------------------------------------------------------------*/
13 #include "elem_func_gw.hxx"
14 #include "function.hxx"
15 #include "double.hxx"
16 #include "overload.hxx"
17 #include "execvisitor.hxx"
18
19
20 extern "C"
21 {
22 #include "Scierror.h"
23 #include "localization.h"
24 #include "basic_functions.h"
25 }
26
27 /*--------------------------------------------------------------------------*/
28 types::Function::ReturnValue sci_clean(types::typed_list &in, int _iRetCount, types::typed_list &out)
29 {
30     types::Double* pDblOut      = NULL;
31     types::Polynom* pPolyOut    = NULL;
32     types::Sparse* pSparseOut   = NULL;
33
34     double* pdReal  = NULL;
35     double* pdImg   = NULL;
36
37     double dNorm    = 0;
38     double dEps     = 0;
39     double dEpsR    = 1E-10;
40     double dEpsA    = 1E-10;
41
42     bool bComplex   = false;
43     int iSize       = 0;
44
45     //Only for types::Sparse case
46     int* pRows = NULL;
47     int* pCols = NULL;
48
49     if (in.size() < 1 || in.size() > 3)
50     {
51         Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "clean", 1, 3);
52         return types::Function::Error;
53     }
54
55     if (_iRetCount > 1)
56     {
57         Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "clean", 1);
58         return types::Function::Error;
59     }
60
61     /***** get data *****/
62     if (in[0]->isDouble())
63     {
64         pDblOut = in[0]->getAs<types::Double>()->clone()->getAs<types::Double>();
65
66         iSize = pDblOut->getSize();
67         pdReal = pDblOut->get();
68         if (pDblOut->isComplex())
69         {
70             bComplex = true;
71             pdImg = pDblOut->getImg();
72         }
73     }
74     else if (in[0]->isPoly())
75     {
76         types::Polynom* pPolyIn = in[0]->getAs<types::Polynom>();
77         int* piRanks = new int[pPolyIn->getSize()];
78         pPolyIn->getRank(piRanks);
79         pPolyOut = new types::Polynom(pPolyIn->getVariableName(), pPolyIn->getDims(), pPolyIn->getDimsArray(), piRanks);
80
81         pDblOut = pPolyIn->getCoef();
82         iSize = pDblOut->getSize();
83         pdReal = pDblOut->get();
84         if (pDblOut->isComplex())
85         {
86             bComplex = true;
87             pdImg = pDblOut->getImg();
88         }
89
90         delete[] piRanks;
91     }
92     else if (in[0]->isSparse())
93     {
94         types::Sparse* pSparseIn = in[0]->getAs<types::Sparse>();
95         pSparseOut = new types::Sparse(pSparseIn->getRows(), pSparseIn->getCols());
96
97         iSize = static_cast<int>(pSparseIn->nonZeros());
98         pRows = new int[iSize * 2];
99         pSparseIn->outputRowCol(pRows);
100         pCols = pRows + iSize;
101
102         pdReal = new double[iSize];
103         pdImg  = new double[iSize];
104         pSparseIn->outputValues(pdReal, pdImg);
105
106         if (pSparseIn->isComplex())
107         {
108             bComplex = true;
109         }
110     }
111     else
112     {
113         std::wstring wstFuncName = L"%"  + in[0]->getShortTypeStr() + L"_clean";
114         return Overload::call(wstFuncName, in, _iRetCount, out, new ast::ExecVisitor());
115     }
116
117
118     if (in.size() == 3)
119     {
120         if (in[2]->isDouble() == false)
121         {
122             Scierror(999, _("%s: Wrong type for input argument #%d : A real scalar expected.\n"), "clean", 3);
123             return types::Function::Error;
124         }
125
126         types::Double* pDbl = in[2]->getAs<types::Double>();
127
128         if (pDbl->isScalar() == false || pDbl->isComplex())
129         {
130             Scierror(999, _("%s: Wrong type for input argument #%d : A real scalar expected.\n"), "clean", 3);
131             return types::Function::Error;
132         }
133
134         dEpsR = pDbl->get(0);
135     }
136
137     if (in.size() >= 2)
138     {
139         if (in[1]->isDouble() == false)
140         {
141             Scierror(999, _("%s: Wrong type for input argument #%d : A real scalar expected.\n"), "clean", 2);
142             return types::Function::Error;
143         }
144
145         types::Double* pDbl = in[1]->getAs<types::Double>();
146
147         if (pDbl->isScalar() == false || pDbl->isComplex())
148         {
149             Scierror(999, _("%s: Wrong type for input argument #%d : A real scalar expected.\n"), "clean", 2);
150             return types::Function::Error;
151         }
152
153         dEpsA = pDbl->get(0);
154     }
155
156     /***** perform operation *****/
157     if (bComplex)
158     {
159         dNorm = wasums(iSize, pdReal, pdImg);
160         dEps = std::max(dEpsA, dEpsR * dNorm);
161
162         for (int i = 0 ; i < iSize ; i++)
163         {
164             if (dabss(pdImg[i]) <= dEps)
165             {
166                 pdImg[i] = 0;
167             }
168         }
169     }
170     else
171     {
172         int iOne = 1;
173         dNorm = C2F(dasum)(&iSize, pdReal, &iOne);
174         dEps = std::max(dEpsA, dEpsR * dNorm);
175     }
176
177     for (int i = 0 ; i < iSize ; i++)
178     {
179         if (dabss(pdReal[i]) <= dEps)
180         {
181             pdReal[i] = 0;
182         }
183     }
184
185     /***** set result *****/
186     if (in[0]->isDouble())
187     {
188         out.push_back(pDblOut);
189     }
190     else if (in[0]->isPoly())
191     {
192         pPolyOut->setCoef(pDblOut);
193         pPolyOut->updateRank();
194         delete pDblOut;
195         pDblOut = NULL;
196         out.push_back(pPolyOut);
197     }
198     else if (in[0]->isSparse())
199     {
200         if (bComplex)
201         {
202             for (int i = 0 ; i < iSize ; i++)
203             {
204                 std::complex<double> cplx = complex<double>(pdReal[i], pdImg[i]);
205                 pSparseOut->set(pRows[i] - 1, pCols[i] - 1, cplx, false);
206             }
207         }
208         else
209         {
210             for (int i = 0 ; i < iSize ; i++)
211             {
212                 pSparseOut->set(pRows[i] - 1, pCols[i] - 1, pdReal[i], false);
213             }
214         }
215
216         pSparseOut->finalize();
217
218         delete[] pdReal;
219         delete[] pdImg;
220         delete[] pRows;
221         out.push_back(pSparseOut);
222     }
223
224     return types::Function::OK;
225 }
226 /*--------------------------------------------------------------------------*/