ba88c2b81bcfdc6b69d263ce3d73ea331d06618c
[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
14 #include "execvisitor.hxx"
15 #include "double.hxx"
16 #include "signalprocessingfunctions.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 std::map<__threadId, Signalprocessingfunctions*> Signalprocessing::m_mapSignalprocessingfunctions;
28
29 void Signalprocessing::addSignalprocessingfunctions(Signalprocessingfunctions* _spFunction)
30 {
31     types::ThreadId* pThread = ConfigVariable::getLastRunningThread();
32     m_mapSignalprocessingfunctions[pThread->getThreadId()] = _spFunction;
33 }
34
35 void Signalprocessing::removeSignalprocessingfunctions()
36 {
37     types::ThreadId* pThread = ConfigVariable::getLastRunningThread();
38     m_mapSignalprocessingfunctions.erase(pThread->getThreadId());
39 }
40
41 Signalprocessingfunctions* Signalprocessing::getSignalprocessingfunctions()
42 {
43     types::ThreadId* pThread = ConfigVariable::getLastRunningThread();
44     return m_mapSignalprocessingfunctions[pThread->getThreadId()];
45 }
46
47 Signalprocessingfunctions::Signalprocessingfunctions(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 fonction '%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 setted.\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 fonction '%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 setted.\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     typed_list in;
180     typed_list out;
181     types::optional_list opt;
182     ast::ExecVisitor execFunc;
183
184     types::Double* pDblY    = new types::Double(*siz);
185
186     // create input args
187     types::Double* pDblT = new types::Double(*iss);
188     pDblT->IncreaseRef();
189     pDblY->IncreaseRef();
190
191     // push_back
192     in.push_back(pDblY);
193     in.push_back(pDblT);
194
195
196
197     for (int i = 0; i < (int)m_FArgs.size(); i++)
198     {
199         m_FArgs[i]->IncreaseRef();
200         in.push_back(m_FArgs[i]);
201     }
202
203     bool bOk = m_pCallDgety->call(in, opt, iRetCount, out, &execFunc) == types::Function::OK;
204
205     for (int i = 0; i < (int)m_FArgs.size(); i++)
206     {
207         m_FArgs[i]->DecreaseRef();
208     }
209
210     if (bOk == false)
211     {
212         sprintf(errorMsg, _("%ls: error while calling user function.\n"), m_pCallDgety->getName().c_str());
213         throw ast::InternalError(errorMsg);
214     }
215
216     if (out.size() != iRetCount)
217     {
218         char* pstrName = wide_string_to_UTF8(m_pCallDgety->getName().c_str());
219         sprintf(errorMsg, _("%s: Wrong number of input argument(s): %d expected.\n"), pstrName, iRetCount);
220         FREE(pstrName);
221         throw ast::InternalError(errorMsg);
222     }
223
224     out[0]->IncreaseRef();
225
226     pDblT->DecreaseRef();
227     if (pDblT->isDeletable())
228     {
229         delete pDblT;
230     }
231
232
233     pDblY->DecreaseRef();
234     if (pDblY->isDeletable())
235     {
236         delete pDblY;
237     }
238
239
240     out[0]->DecreaseRef();
241
242     if (out[0]->isDouble() == false)
243     {
244         char* pstrName = wide_string_to_UTF8(m_pCallDgety->getName().c_str());
245         sprintf(errorMsg, _("%s: Wrong type for output argument #%d: Real matrix expected.\n"), pstrName, 1);
246         FREE(pstrName);
247         throw ast::InternalError(errorMsg);
248     }
249     types::Double* pDblOut = out[0]->getAs<types::Double>();
250     if (pDblOut->isComplex())
251     {
252         char* pstrName = wide_string_to_UTF8(m_pCallDgety->getName().c_str());
253         sprintf(errorMsg, _("%s: Wrong type for output argument #%d: Real matrix expected.\n"), pstrName, 1);
254         FREE(pstrName);
255         throw ast::InternalError(errorMsg);
256     }
257
258     C2F(dcopy)(siz, pDblOut->get(), &one, y, &one);
259
260
261     if (out[0]->isDeletable())
262     {
263         delete out[0];
264     }
265 }
266 //call external
267 void Signalprocessingfunctions::callDgetx(double* x, int* siz, int* iss)
268 {
269     char errorMsg[256];
270     int one         = 1;
271     int iRetCount   = 1;
272
273     typed_list in;
274     typed_list out;
275     types::optional_list opt;
276     ast::ExecVisitor execFunc;
277
278     types::Double* pDblX    = new types::Double(*siz);
279
280     // create input args
281     types::Double* pDblT = new types::Double(*iss);
282     pDblT->IncreaseRef();
283     pDblX->IncreaseRef();
284
285     // push_back
286     in.push_back(pDblX);
287     in.push_back(pDblT);
288
289
290
291     for (int i = 0; i < (int)m_FArgs.size(); i++)
292     {
293         m_FArgs[i]->IncreaseRef();
294         in.push_back(m_FArgs[i]);
295     }
296
297     bool bOk = m_pCallDgetx->call(in, opt, iRetCount, out, &execFunc) == types::Function::OK;
298
299     for (int i = 0; i < (int)m_FArgs.size(); i++)
300     {
301         m_FArgs[i]->DecreaseRef();
302     }
303
304     if (bOk == false)
305     {
306         sprintf(errorMsg, _("%ls: error while calling user function.\n"), m_pCallDgetx->getName().c_str());
307         throw ast::InternalError(errorMsg);
308     }
309
310     if (out.size() != iRetCount)
311     {
312         char* pstrName = wide_string_to_UTF8(m_pCallDgetx->getName().c_str());
313         sprintf(errorMsg, _("%s: Wrong number of input argument(s): %d expected.\n"), pstrName, iRetCount);
314         FREE(pstrName);
315         throw ast::InternalError(errorMsg);
316     }
317
318     out[0]->IncreaseRef();
319
320     pDblT->DecreaseRef();
321     if (pDblT->isDeletable())
322     {
323         delete pDblT;
324     }
325
326
327     pDblX->DecreaseRef();
328     if (pDblX->isDeletable())
329     {
330         delete pDblX;
331     }
332
333
334     out[0]->DecreaseRef();
335
336     if (out[0]->isDouble() == false)
337     {
338         char* pstrName = wide_string_to_UTF8(m_pCallDgetx->getName().c_str());
339         sprintf(errorMsg, _("%s: Wrong type for output argument #%d: Real matrix expected.\n"), pstrName, 1);
340         FREE(pstrName);
341         throw ast::InternalError(errorMsg);
342     }
343     types::Double* pDblOut = out[0]->getAs<types::Double>();
344     if (pDblOut->isComplex())
345     {
346         char* pstrName = wide_string_to_UTF8(m_pCallDgetx->getName().c_str());
347         sprintf(errorMsg, _("%s: Wrong type for output argument #%d: Real matrix expected.\n"), pstrName, 1);
348         FREE(pstrName);
349         throw ast::InternalError(errorMsg);
350     }
351
352     C2F(dcopy)(siz, pDblOut->get(), &one, x, &one);
353
354
355     if (out[0]->isDeletable())
356     {
357         delete out[0];
358     }
359 }