Merge remote-tracking branch 'origin/6.1'
[scilab.git] / scilab / modules / signal_processing / src / cpp / signalprocessingfunctions.cpp
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2014 - Scilab Enterprises - Anais AUBERT
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 #include "double.hxx"
17 #include "signalprocessingfunctions.hxx"
18 #include "configvariable.hxx"
19 #include "function.hxx"
20
21 extern "C"
22 {
23 #include "elem_common.h"
24 #include "Ex-corr.h"
25 #include "localization.h"
26 }
27
28 /*--------------------------------------------------------------------------*/
29
30 Signalprocessingfunctions* Signalprocessing::m_Signalprocessingfunctions;
31
32 void Signalprocessing::addSignalprocessingfunctions(Signalprocessingfunctions* _spFunction)
33 {
34     m_Signalprocessingfunctions = _spFunction;
35 }
36
37 void Signalprocessing::removeSignalprocessingfunctions()
38 {
39     m_Signalprocessingfunctions = NULL;
40 }
41
42 Signalprocessingfunctions* Signalprocessing::getSignalprocessingfunctions()
43 {
44     return m_Signalprocessingfunctions;
45 }
46
47 Signalprocessingfunctions::Signalprocessingfunctions(const std::wstring& callerName)
48 {
49
50     m_wstrCaller = callerName;
51
52     m_pCallDgetx = NULL;
53     m_pCallDgety = NULL;
54
55     m_pStringDgetxDyn = NULL;
56     m_pStringDgetyDyn = NULL;
57
58     m_pStringDgetxStatic = NULL;
59     m_pStringDgetyStatic = NULL;
60
61     // init static functions
62     if (callerName == L"corr")
63     {
64         m_staticFunctionMap[L"corexx"] = (void*)C2F(corexx);
65         m_staticFunctionMap[L"corexy"] = (void*)C2F(corexy);
66
67     }
68 }
69
70 void Signalprocessingfunctions::execFunctionDgetx(double* x, int* siz, int* iss)
71 {
72     char errorMsg[256];
73     if (m_pCallDgetx)
74     {
75         callDgetx(x, siz, iss);
76     }
77     else if (m_pStringDgetxDyn)
78     {
79         ConfigVariable::EntryPointStr* func = ConfigVariable::getEntryPoint(m_pStringDgetxDyn->get(0));
80         if (func == NULL)
81         {
82             sprintf(errorMsg, _("Undefined function '%ls'.\n"), m_pStringDgetxDyn->get(0));
83             throw ast::InternalError(errorMsg);
84         }
85         ((dgetx_f_t)(func->functionPtr))(x, siz, iss);
86     }
87     else if (m_pStringDgetxStatic)// function static
88     {
89         ((dgetx_f_t)m_staticFunctionMap[m_pStringDgetxStatic->get(0)])(x, siz, iss);
90     }
91     else
92     {
93         sprintf(errorMsg, _("User function '%s' have not been set.\n"), "g");
94         throw ast::InternalError(errorMsg);
95     }
96 }
97
98 void Signalprocessingfunctions::setDgetx(types::Callable* _dgetx)
99 {
100     m_pCallDgetx = _dgetx;
101 }
102
103 void Signalprocessingfunctions::setDgetx(types::String* _dgetx)
104 {
105     m_pStringDgetxStatic = _dgetx;
106 }
107 void Signalprocessingfunctions::setDgety(types::Callable* _dgety)
108 {
109     m_pCallDgety = _dgety;
110 }
111 void Signalprocessingfunctions::setDgety(types::String* _dgety)
112 {
113     m_pStringDgetyStatic = _dgety;
114 }
115
116 //param for fortran call
117 void dgetx_f(double* x, int* siz, int* iss)
118 {
119     Signalprocessingfunctions* spFunction = NULL;
120     spFunction = Signalprocessing::getSignalprocessingfunctions();
121
122     if (spFunction == NULL)
123     {
124         throw ast::InternalError(_("An error occurred while getting Signalprocessingfunctions object.\n"));
125     }
126
127     spFunction->execFunctionDgetx(x, siz, iss);
128 }
129
130 void Signalprocessingfunctions::execFunctionDgety(double* y, int* siz, int* iss)
131 {
132     char errorMsg[256];
133     if (m_pCallDgety)
134     {
135         callDgety(y, siz, iss);
136
137     }
138     else if (m_pStringDgetxDyn)
139     {
140         ConfigVariable::EntryPointStr* func = ConfigVariable::getEntryPoint(m_pStringDgetyDyn->get(0));
141         if (func == NULL)
142         {
143             sprintf(errorMsg, _("Undefined function '%ls'.\n"), m_pStringDgetyDyn->get(0));
144             throw ast::InternalError(errorMsg);
145         }
146         ((dgety_f_t)(func->functionPtr))(y, siz, iss);
147     }
148     else if (m_pStringDgetyStatic)// function static
149     {
150         ((dgety_f_t)m_staticFunctionMap[m_pStringDgetyStatic->get(0)])(y, siz, iss);
151     }
152     else
153     {
154         sprintf(errorMsg, _("User function '%s' have not been set.\n"), "g");
155         throw ast::InternalError(errorMsg);
156     }
157 }
158
159 //param for fortran call
160 void dgety_f(double* y, int* siz, int* iss)
161 {
162     Signalprocessingfunctions* spFunction = NULL;
163     spFunction = Signalprocessing::getSignalprocessingfunctions();
164
165     if (spFunction == NULL)
166     {
167         throw ast::InternalError(_("An error occurred while getting Signalprocessingfunctions object.\n"));
168     }
169
170     spFunction->execFunctionDgety(y, siz, iss);
171 }
172
173 void Signalprocessingfunctions::callDgety(double* y, int* siz, int* iss)
174 {
175     char errorMsg[256];
176     int one         = 1;
177     int iRetCount   = 1;
178
179     types::typed_list in;
180     types::typed_list out;
181     types::optional_list opt;
182
183     types::Double* pDblY    = new types::Double(*siz);
184
185     // create input args
186     types::Double* pDblT = new types::Double(*iss);
187     pDblT->IncreaseRef();
188     pDblY->IncreaseRef();
189
190     // push_back
191     in.push_back(pDblY);
192     in.push_back(pDblT);
193
194
195
196     for (int i = 0; i < (int)m_FArgs.size(); i++)
197     {
198         m_FArgs[i]->IncreaseRef();
199         in.push_back(m_FArgs[i]);
200     }
201
202     bool bOk = m_pCallDgety->call(in, opt, iRetCount, out) == types::Function::OK;
203
204     for (int i = 0; i < (int)m_FArgs.size(); i++)
205     {
206         m_FArgs[i]->DecreaseRef();
207     }
208
209     if (bOk == false)
210     {
211         sprintf(errorMsg, _("%ls: error while calling user function.\n"), m_pCallDgety->getName().c_str());
212         throw ast::InternalError(errorMsg);
213     }
214
215     if (out.size() != iRetCount)
216     {
217         char* pstrName = wide_string_to_UTF8(m_pCallDgety->getName().c_str());
218         sprintf(errorMsg, _("%s: Wrong number of input argument(s): %d expected.\n"), pstrName, iRetCount);
219         FREE(pstrName);
220         throw ast::InternalError(errorMsg);
221     }
222
223     out[0]->IncreaseRef();
224
225     pDblT->DecreaseRef();
226     if (pDblT->isDeletable())
227     {
228         delete pDblT;
229     }
230
231
232     pDblY->DecreaseRef();
233     if (pDblY->isDeletable())
234     {
235         delete pDblY;
236     }
237
238
239     out[0]->DecreaseRef();
240
241     if (out[0]->isDouble() == false)
242     {
243         char* pstrName = wide_string_to_UTF8(m_pCallDgety->getName().c_str());
244         sprintf(errorMsg, _("%s: Wrong type for output argument #%d: Real matrix expected.\n"), pstrName, 1);
245         FREE(pstrName);
246         throw ast::InternalError(errorMsg);
247     }
248     types::Double* pDblOut = out[0]->getAs<types::Double>();
249     if (pDblOut->isComplex())
250     {
251         char* pstrName = wide_string_to_UTF8(m_pCallDgety->getName().c_str());
252         sprintf(errorMsg, _("%s: Wrong type for output argument #%d: Real matrix expected.\n"), pstrName, 1);
253         FREE(pstrName);
254         throw ast::InternalError(errorMsg);
255     }
256
257     C2F(dcopy)(siz, pDblOut->get(), &one, y, &one);
258
259
260     if (out[0]->isDeletable())
261     {
262         delete out[0];
263     }
264 }
265 //call external
266 void Signalprocessingfunctions::callDgetx(double* x, int* siz, int* iss)
267 {
268     char errorMsg[256];
269     int one         = 1;
270     int iRetCount   = 1;
271
272     types::typed_list in;
273     types::typed_list out;
274     types::optional_list opt;
275
276     types::Double* pDblX    = new types::Double(*siz);
277
278     // create input args
279     types::Double* pDblT = new types::Double(*iss);
280     pDblT->IncreaseRef();
281     pDblX->IncreaseRef();
282
283     // push_back
284     in.push_back(pDblX);
285     in.push_back(pDblT);
286
287
288
289     for (int i = 0; i < (int)m_FArgs.size(); i++)
290     {
291         m_FArgs[i]->IncreaseRef();
292         in.push_back(m_FArgs[i]);
293     }
294
295     bool bOk = m_pCallDgetx->call(in, opt, iRetCount, out) == types::Function::OK;
296
297     for (int i = 0; i < (int)m_FArgs.size(); i++)
298     {
299         m_FArgs[i]->DecreaseRef();
300     }
301
302     if (bOk == false)
303     {
304         sprintf(errorMsg, _("%ls: error while calling user function.\n"), m_pCallDgetx->getName().c_str());
305         throw ast::InternalError(errorMsg);
306     }
307
308     if (out.size() != iRetCount)
309     {
310         char* pstrName = wide_string_to_UTF8(m_pCallDgetx->getName().c_str());
311         sprintf(errorMsg, _("%s: Wrong number of input argument(s): %d expected.\n"), pstrName, iRetCount);
312         FREE(pstrName);
313         throw ast::InternalError(errorMsg);
314     }
315
316     out[0]->IncreaseRef();
317
318     pDblT->DecreaseRef();
319     if (pDblT->isDeletable())
320     {
321         delete pDblT;
322     }
323
324
325     pDblX->DecreaseRef();
326     if (pDblX->isDeletable())
327     {
328         delete pDblX;
329     }
330
331
332     out[0]->DecreaseRef();
333
334     if (out[0]->isDouble() == false)
335     {
336         char* pstrName = wide_string_to_UTF8(m_pCallDgetx->getName().c_str());
337         sprintf(errorMsg, _("%s: Wrong type for output argument #%d: Real matrix expected.\n"), pstrName, 1);
338         FREE(pstrName);
339         throw ast::InternalError(errorMsg);
340     }
341     types::Double* pDblOut = out[0]->getAs<types::Double>();
342     if (pDblOut->isComplex())
343     {
344         char* pstrName = wide_string_to_UTF8(m_pCallDgetx->getName().c_str());
345         sprintf(errorMsg, _("%s: Wrong type for output argument #%d: Real matrix expected.\n"), pstrName, 1);
346         FREE(pstrName);
347         throw ast::InternalError(errorMsg);
348     }
349
350     C2F(dcopy)(siz, pDblOut->get(), &one, x, &one);
351
352
353     if (out[0]->isDeletable())
354     {
355         delete out[0];
356     }
357 }