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