refactoring polynom.
[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 #include "clean.hxx"
19
20 extern "C"
21 {
22 #include "Scierror.h"
23 #include "localization.h"
24 }
25
26 /*--------------------------------------------------------------------------*/
27 types::Function::ReturnValue sci_clean(types::typed_list &in, int _iRetCount, types::typed_list &out)
28 {
29     types::Double* pDblOut      = NULL;
30     types::Polynom* pPolyOut    = NULL;
31     types::Sparse* pSparseOut   = NULL;
32
33     double* pdReal  = NULL;
34     double* pdImg   = NULL;
35
36     double dEpsR    = 1E-10;
37     double dEpsA    = 1E-10;
38
39     int iSize       = 0;
40
41     //Only for types::Sparse case
42     int* pRows = NULL;
43     int* pCols = NULL;
44
45     if (in.size() < 1 || in.size() > 3)
46     {
47         Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "clean", 1, 3);
48         return types::Function::Error;
49     }
50
51     if (_iRetCount > 1)
52     {
53         Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "clean", 1);
54         return types::Function::Error;
55     }
56
57     /***** get data *****/
58     if (in[0]->isDouble())
59     {
60         pDblOut = in[0]->getAs<types::Double>()->clone()->getAs<types::Double>();
61
62         iSize = pDblOut->getSize();
63         pdReal = pDblOut->get();
64         if (pDblOut->isComplex())
65         {
66             pdImg = pDblOut->getImg();
67         }
68     }
69     else if (in[0]->isPoly())
70     {
71         types::Polynom* pPolyIn = in[0]->getAs<types::Polynom>();
72         iSize = pPolyIn->getSize();
73         pPolyOut = pPolyIn->clone()->getAs<types::Polynom>();
74     }
75     else if (in[0]->isSparse())
76     {
77         types::Sparse* pSparseIn = in[0]->getAs<types::Sparse>();
78         pSparseOut = new types::Sparse(pSparseIn->getRows(), pSparseIn->getCols());
79
80         iSize = static_cast<int>(pSparseIn->nonZeros());
81         pRows = new int[iSize * 2];
82         pSparseIn->outputRowCol(pRows);
83         pCols = pRows + iSize;
84
85         pdReal = new double[iSize];
86         if (pSparseIn->isComplex())
87         {
88             pdImg  = new double[iSize];
89         }
90
91         pSparseIn->outputValues(pdReal, pdImg);
92     }
93     else
94     {
95         std::wstring wstFuncName = L"%"  + in[0]->getShortTypeStr() + L"_clean";
96         return Overload::call(wstFuncName, in, _iRetCount, out, new ast::ExecVisitor());
97     }
98
99
100     if (in.size() == 3)
101     {
102         if (in[2]->isDouble() == false)
103         {
104             Scierror(999, _("%s: Wrong type for input argument #%d : A real scalar expected.\n"), "clean", 3);
105             return types::Function::Error;
106         }
107
108         types::Double* pDbl = in[2]->getAs<types::Double>();
109
110         if (pDbl->isScalar() == false || pDbl->isComplex())
111         {
112             Scierror(999, _("%s: Wrong type for input argument #%d : A real scalar expected.\n"), "clean", 3);
113             return types::Function::Error;
114         }
115
116         dEpsR = pDbl->get(0);
117     }
118
119     if (in.size() >= 2)
120     {
121         if (in[1]->isDouble() == false)
122         {
123             Scierror(999, _("%s: Wrong type for input argument #%d : A real scalar expected.\n"), "clean", 2);
124             return types::Function::Error;
125         }
126
127         types::Double* pDbl = in[1]->getAs<types::Double>();
128
129         if (pDbl->isScalar() == false || pDbl->isComplex())
130         {
131             Scierror(999, _("%s: Wrong type for input argument #%d : A real scalar expected.\n"), "clean", 2);
132             return types::Function::Error;
133         }
134
135         dEpsA = pDbl->get(0);
136     }
137
138     /***** perform operation *****/
139     if (in[0]->isPoly())
140     {
141         for (int i = 0 ; i < iSize ; i++)
142         {
143             types::SinglePoly* pSP = pPolyOut->get(i);
144             clean(pSP->get(), pSP->getImg(), pSP->getSize(), dEpsA, dEpsR);
145         }
146     }
147     else
148     {
149         clean(pdReal, pdImg, iSize, dEpsA, dEpsR);
150     }
151
152     /***** set result *****/
153     if (in[0]->isDouble())
154     {
155         out.push_back(pDblOut);
156     }
157     else if (in[0]->isPoly())
158     {
159         pPolyOut->updateRank();
160         out.push_back(pPolyOut);
161     }
162     else if (in[0]->isSparse())
163     {
164         if (pdImg)
165         {
166             for (int i = 0 ; i < iSize ; i++)
167             {
168                 std::complex<double> cplx = complex<double>(pdReal[i], pdImg[i]);
169                 pSparseOut->set(pRows[i] - 1, pCols[i] - 1, cplx, false);
170             }
171
172             delete[] pdImg;
173         }
174         else
175         {
176             for (int i = 0 ; i < iSize ; i++)
177             {
178                 pSparseOut->set(pRows[i] - 1, pCols[i] - 1, pdReal[i], false);
179             }
180         }
181
182         pSparseOut->finalize();
183
184         delete[] pdReal;
185         delete[] pRows;
186         out.push_back(pSparseOut);
187     }
188
189     return types::Function::OK;
190 }
191 /*--------------------------------------------------------------------------*/