utf: module signal_processing
[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::string& callerName)
45 {
46
47     m_strCaller = 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 == "corr")
60     {
61         m_staticFunctionMap["corexx"] = (void*)C2F(corexx);
62         m_staticFunctionMap["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         const char* pstrName = m_pCallDgety->getName().c_str();
215         sprintf(errorMsg, _("%s: Wrong number of input argument(s): %d expected.\n"), pstrName, iRetCount);
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         const char* pstrName = m_pCallDgety->getName().c_str();
240         sprintf(errorMsg, _("%s: Wrong type for output argument #%d: Real matrix expected.\n"), pstrName, 1);
241         throw ast::InternalError(errorMsg);
242     }
243     types::Double* pDblOut = out[0]->getAs<types::Double>();
244     if (pDblOut->isComplex())
245     {
246         const char* pstrName = m_pCallDgety->getName().c_str();
247         sprintf(errorMsg, _("%s: Wrong type for output argument #%d: Real matrix expected.\n"), pstrName, 1);
248         throw ast::InternalError(errorMsg);
249     }
250
251     C2F(dcopy)(siz, pDblOut->get(), &one, y, &one);
252
253
254     if (out[0]->isDeletable())
255     {
256         delete out[0];
257     }
258 }
259 //call external
260 void Signalprocessingfunctions::callDgetx(double* x, int* siz, int* iss)
261 {
262     char errorMsg[256];
263     int one         = 1;
264     int iRetCount   = 1;
265
266     types::typed_list in;
267     types::typed_list out;
268     types::optional_list opt;
269
270     types::Double* pDblX    = new types::Double(*siz);
271
272     // create input args
273     types::Double* pDblT = new types::Double(*iss);
274     pDblT->IncreaseRef();
275     pDblX->IncreaseRef();
276
277     // push_back
278     in.push_back(pDblX);
279     in.push_back(pDblT);
280
281
282
283     for (int i = 0; i < (int)m_FArgs.size(); i++)
284     {
285         m_FArgs[i]->IncreaseRef();
286         in.push_back(m_FArgs[i]);
287     }
288
289     bool bOk = m_pCallDgetx->call(in, opt, iRetCount, out) == types::Function::OK;
290
291     for (int i = 0; i < (int)m_FArgs.size(); i++)
292     {
293         m_FArgs[i]->DecreaseRef();
294     }
295
296     if (bOk == false)
297     {
298         sprintf(errorMsg, _("%ls: error while calling user function.\n"), m_pCallDgetx->getName().c_str());
299         throw ast::InternalError(errorMsg);
300     }
301
302     if (out.size() != iRetCount)
303     {
304         const char* pstrName = m_pCallDgetx->getName().c_str();
305         sprintf(errorMsg, _("%s: Wrong number of input argument(s): %d expected.\n"), pstrName, iRetCount);
306         throw ast::InternalError(errorMsg);
307     }
308
309     out[0]->IncreaseRef();
310
311     pDblT->DecreaseRef();
312     if (pDblT->isDeletable())
313     {
314         delete pDblT;
315     }
316
317
318     pDblX->DecreaseRef();
319     if (pDblX->isDeletable())
320     {
321         delete pDblX;
322     }
323
324
325     out[0]->DecreaseRef();
326
327     if (out[0]->isDouble() == false)
328     {
329         const char* pstrName = m_pCallDgetx->getName().c_str();
330         sprintf(errorMsg, _("%s: Wrong type for output argument #%d: Real matrix expected.\n"), pstrName, 1);
331         throw ast::InternalError(errorMsg);
332     }
333     types::Double* pDblOut = out[0]->getAs<types::Double>();
334     if (pDblOut->isComplex())
335     {
336         const char* pstrName = m_pCallDgetx->getName().c_str();
337         sprintf(errorMsg, _("%s: Wrong type for output argument #%d: Real matrix expected.\n"), pstrName, 1);
338         throw ast::InternalError(errorMsg);
339     }
340
341     C2F(dcopy)(siz, pDblOut->get(), &one, x, &one);
342
343
344     if (out[0]->isDeletable())
345     {
346         delete out[0];
347     }
348 }