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