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