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 /*--------------------------------------------------------------------------*/
sci_clean(types::typed_list & in,int _iRetCount,types::typed_list & out)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 pSparseOut->toComplex();
96 pdImg = new double[iSize];
97 }
98
99 pSparseIn->outputValues(pdReal, pdImg);
100 }
101 else
102 {
103 std::wstring wstFuncName = L"%" + in[0]->getShortTypeStr() + L"_clean";
104 return Overload::call(wstFuncName, in, _iRetCount, out);
105 }
106
107
108 if (in.size() == 3)
109 {
110 if (in[2]->isDouble() == false)
111 {
112 Scierror(999, _("%s: Wrong type for input argument #%d : A real scalar expected.\n"), "clean", 3);
113 if (in[0]->isSparse())
114 {
115 delete pSparseOut;
116 delete[] pdReal;
117 delete[] pRows;
118 if (pdImg)
119 {
120 delete[] pdImg;
121 }
122 }
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 if (in[0]->isSparse())
132 {
133 delete pSparseOut;
134 delete[] pdReal;
135 delete[] pRows;
136 if (pdImg)
137 {
138 delete[] pdImg;
139 }
140 }
141 return types::Function::Error;
142 }
143
144 dEpsR = pDbl->get(0);
145 }
146
147 if (in.size() >= 2)
148 {
149 if (in[1]->isDouble() == false)
150 {
151 Scierror(999, _("%s: Wrong type for input argument #%d : A real scalar expected.\n"), "clean", 2);
152 if (in[0]->isSparse())
153 {
154 delete pSparseOut;
155 delete[] pdReal;
156 delete[] pRows;
157 if (pdImg)
158 {
159 delete[] pdImg;
160 }
161 }
162 return types::Function::Error;
163 }
164
165 types::Double* pDbl = in[1]->getAs<types::Double>();
166
167 if (pDbl->isScalar() == false || pDbl->isComplex())
168 {
169 Scierror(999, _("%s: Wrong type for input argument #%d : A real scalar expected.\n"), "clean", 2);
170 if (in[0]->isSparse())
171 {
172 delete pSparseOut;
173 delete[] pdReal;
174 delete[] pRows;
175 if (pdImg)
176 {
177 delete[] pdImg;
178 }
179 }
180 return types::Function::Error;
181 }
182
183 dEpsA = pDbl->get(0);
184 }
185
186 /***** perform operation *****/
187 if (in[0]->isPoly())
188 {
189 for (int i = 0 ; i < iSize ; i++)
190 {
191 types::SinglePoly* pSP = pPolyOut->get(i);
192 clean(pSP->get(), pSP->getImg(), pSP->getSize(), dEpsA, dEpsR);
193 }
194 }
195 else
196 {
197 clean(pdReal, pdImg, iSize, dEpsA, dEpsR);
198 }
199
200 /***** set result *****/
201 if (in[0]->isDouble())
202 {
203 out.push_back(pDblOut);
204 }
205 else if (in[0]->isPoly())
206 {
207 pPolyOut->updateRank();
208 out.push_back(pPolyOut);
209 }
210 else if (in[0]->isSparse())
211 {
212 if (pdImg)
213 {
214 for (int i = 0 ; i < iSize ; i++)
215 {
216 std::complex<double> cplx = std::complex<double>(pdReal[i], pdImg[i]);
217 pSparseOut->set(pRows[i] - 1, pCols[i] - 1, cplx, false);
218 }
219
220 delete[] pdImg;
221 }
222 else
223 {
224 for (int i = 0 ; i < iSize ; i++)
225 {
226 pSparseOut->set(pRows[i] - 1, pCols[i] - 1, pdReal[i], false);
227 }
228 }
229
230 pSparseOut->finalize();
231
232 delete[] pdReal;
233 delete[] pRows;
234 out.push_back(pSparseOut);
235 }
236
237 return types::Function::OK;
238 }
239 /*--------------------------------------------------------------------------*/
240