[elementary_functions] linspace() c++ gateway gives tremendous speedup
[scilab.git] / scilab / modules / elementary_functions / sci_gateway / cpp / elem_func_gw.cpp
1 /*
2 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *  Copyright (C) 2008-2008 - DIGITEO - Antoine ELIAS
4 *  Copyright (C) 2011-2011 - DIGITEO - Bruno JOFRET
5 *
6  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14 *
15 */
16 //for Visual Leak Detector in debug compilation mode
17 //#define DEBUG_VLD
18 #if defined(DEBUG_VLD) && defined(_DEBUG)
19 #include <vld.h>
20 #endif
21
22 #include "elem_func_gw.hxx"
23 #include "context.hxx"
24 #include "overload.hxx"
25 #include "Scierror.h"
26 #include "localization.h"
27 #include "charEncoding.h"
28 #include "sparse.hxx"
29 #include "int.hxx"
30
31 #define MODULE_NAME L"elementary_functions"
32 extern "C"
33 {
34 #include "gw_elementary_functions.h"
35 }
36
37 int ElemFuncModule::Load()
38 {
39     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"abs", &sci_abs, MODULE_NAME));
40     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"acos", &sci_acos, MODULE_NAME));
41     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"asin", &sci_asin, MODULE_NAME));
42     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"atan", &sci_atan, MODULE_NAME));
43     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"bitstring", &sci_bitstring, MODULE_NAME));
44     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"ceil", &sci_ceil, MODULE_NAME));
45     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"clean", &sci_clean, MODULE_NAME));
46     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"conj", &sci_conj, MODULE_NAME));
47     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"cos", &sci_cos, MODULE_NAME));
48     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"cumprod", &sci_cumprod, MODULE_NAME));
49     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"cumsum", &sci_cumsum, MODULE_NAME));
50     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"diag", &sci_diag, MODULE_NAME));
51     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"dsearch", &sci_dsearch, MODULE_NAME));
52     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"exp", &sci_exp, MODULE_NAME));
53     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"expm", &sci_expm, MODULE_NAME));
54     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"eye", &sci_eye, MODULE_NAME));
55     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"floor", &sci_floor, MODULE_NAME));
56     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"frexp", &sci_frexp, MODULE_NAME));
57     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"gsort", &sci_gsort, MODULE_NAME));
58     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"imag", &sci_imag, MODULE_NAME));
59     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"imult", &sci_imult, MODULE_NAME));
60     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"int", &sci_int, MODULE_NAME));
61     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"isreal", &sci_isreal, MODULE_NAME));
62     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"isequal", &sci_isequal, MODULE_NAME));
63     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"kron", &sci_kron, MODULE_NAME));
64     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"linspace", &sci_linspace, MODULE_NAME));
65     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"log", &sci_log, MODULE_NAME));
66     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"log1p", &sci_log1p, MODULE_NAME));
67     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"matrix", &sci_matrix, MODULE_NAME));
68     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"max", &sci_max, MODULE_NAME));
69     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"min", &sci_min, MODULE_NAME));
70     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"nearfloat", &sci_nearfloat, MODULE_NAME));
71     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"number_properties", &sci_number_properties, MODULE_NAME));
72     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"ones", &sci_ones, MODULE_NAME));
73     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"prod", &sci_prod, MODULE_NAME));
74     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"permute", &sci_permute, MODULE_NAME));
75     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"rand", &sci_rand, MODULE_NAME));
76     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"real", &sci_real, MODULE_NAME));
77     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"round", &sci_round, MODULE_NAME));
78     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"sign", &sci_sign, MODULE_NAME));
79     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"sin", &sci_sin, MODULE_NAME));
80     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"size", &sci_size, MODULE_NAME));
81     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"sqrt", &sci_sqrt, MODULE_NAME));
82     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"sum", &sci_sum, MODULE_NAME));
83     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"tan", &sci_tan, MODULE_NAME));
84     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"testmatrix", &sci_testmatrix, MODULE_NAME));
85     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"tril", &sci_tril, MODULE_NAME));
86     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"triu", &sci_triu, MODULE_NAME));
87     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"zeros", &sci_zeros, MODULE_NAME));
88     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"rat", &sci_rat, MODULE_NAME));
89     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"base2dec", &sci_base2dec, MODULE_NAME));
90     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"dec2base", &sci_dec2base, MODULE_NAME));
91     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"log10", &sci_log10, MODULE_NAME));
92     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"cosh", &sci_cosh, MODULE_NAME));
93     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"sinh", &sci_sinh, MODULE_NAME));
94     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"tanh", &sci_tanh, MODULE_NAME));
95     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"acosh", &sci_acosh, MODULE_NAME));
96     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"asinh", &sci_asinh, MODULE_NAME));
97     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"atanh", &sci_atanh, MODULE_NAME));
98     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"isvector", &sci_isvector, MODULE_NAME));
99     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"issquare", &sci_issquare, MODULE_NAME));
100     return 1;
101 }
102
103
104 bool getDimsFromArguments(types::typed_list& in, const std::string& _pstName, int* _iDims, int** _piDims, bool* _alloc)
105 {
106     types::Double* pOut = 0;
107
108     *_alloc = false;
109     *_iDims = 0;
110     *_piDims = NULL;
111
112     if (in.size() == 0)
113     {
114         *_iDims = 2;
115         *_piDims = new int[*_iDims];
116         (*_piDims)[0] = 1;
117         (*_piDims)[1] = 1;
118         *_alloc = true;
119         return true;
120     }
121     else if (in.size() == 1)
122     {
123         *_iDims = 1;
124         // :
125         if (in[0]->isColon())
126         {
127             *_iDims = -1;
128             return false;
129         }
130
131         if (in[0]->isArrayOf() == false)
132         {
133             if (in[0]->isSparse())
134             {
135                 types::Sparse* sp = in[0]->getAs<types::Sparse>();
136                 *_iDims = sp->getDims();
137                 *_piDims = sp->getDimsArray();
138                 return true;
139             }
140             else if (in[0]->isSparseBool())
141             {
142                 types::SparseBool* sp = in[0]->getAs<types::SparseBool>();
143                 *_iDims = sp->getDims();
144                 *_piDims = sp->getDimsArray();
145                 return true;
146             }
147             return false;
148         }
149
150         types::GenericType* pIn = in[0]->getAs<types::GenericType>();
151         *_iDims = pIn->getDims();
152         *_piDims = pIn->getDimsArray();
153
154         return true;
155     }
156     else
157     {
158         *_iDims = static_cast<int>(in.size());
159         *_piDims = new int[*_iDims];
160         *_alloc = true;
161         for (int i = 0; i < *_iDims; i++)
162         {
163             if (in[i]->isArrayOf() == false)
164             {
165                 Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), _pstName.c_str(), i + 1);
166                 delete[] * _piDims;
167                 return false;
168             }
169
170             types::GenericType* pGTIn = in[i]->getAs<types::GenericType>();
171             if (pGTIn->isScalar() == false || pGTIn->isComplex())
172             {
173                 Scierror(999, _("%s: Wrong size for input argument #%d: A scalar expected.\n"), _pstName.c_str(), i + 1);
174                 delete[] * _piDims;
175                 return false;
176             }
177
178             switch (in[i]->getType())
179             {
180                 case types::InternalType::ScilabDouble:
181                 {
182                     double dValue = in[i]->getAs<types::Double>()->get(0);
183                     if (dValue >= INT_MAX)
184                     {
185                         Scierror(999, _("%s: variable size exceeded : less than %d expected.\n"), _pstName.c_str(), INT_MAX);
186                         delete[] * _piDims;
187                         return false;
188                     }
189                     (*_piDims)[i] = static_cast<int>(dValue);
190                 }
191                 break;
192                 case types::InternalType::ScilabInt8:
193                     (*_piDims)[i] = static_cast<int>(in[i]->getAs<types::Int8>()->get()[0]);
194                     break;
195                 case types::InternalType::ScilabUInt8:
196                     (*_piDims)[i] = static_cast<int>(in[i]->getAs<types::UInt8>()->get()[0]);
197                     break;
198                 case types::InternalType::ScilabInt16:
199                     (*_piDims)[i] = static_cast<int>(in[i]->getAs<types::Int16>()->get()[0]);
200                     break;
201                 case types::InternalType::ScilabUInt16:
202                     (*_piDims)[i] = static_cast<int>(in[i]->getAs<types::UInt16>()->get()[0]);
203                     break;
204                 case types::InternalType::ScilabInt32:
205                     (*_piDims)[i] = in[i]->getAs<types::Int32>()->get()[0];
206                     break;
207                 case types::InternalType::ScilabUInt32:
208                     (*_piDims)[i] = static_cast<int>(in[i]->getAs<types::UInt32>()->get()[0]);
209                     break;
210                 case types::InternalType::ScilabInt64:
211                 {
212                     long long llValue = in[i]->getAs<types::Int64>()->get(0);
213                     if (llValue >= INT_MAX)
214                     {
215                         Scierror(999, _("%s: variable size exceeded : less than %d expected.\n"), _pstName.c_str(), INT_MAX);
216                         delete[] * _piDims;
217                         return false;
218                     }
219                     (*_piDims)[i] = static_cast<int>(llValue);
220                     break;
221                 }
222                 case types::InternalType::ScilabUInt64:
223                 {
224                     unsigned long long ullValue = in[i]->getAs<types::UInt64>()->get(0);
225                     if (ullValue >= INT_MAX)
226                     {
227                         Scierror(999, _("%s: variable size exceeded : less than %d expected.\n"), _pstName.c_str(), INT_MAX);
228                         delete[] * _piDims;
229                         return false;
230                     }
231                     (*_piDims)[i] = static_cast<int>(ullValue);
232                     break;
233                 }
234                 default:
235                     Scierror(999, _("%s: Wrong size for input argument #%d: A scalar expected.\n"), _pstName.c_str(), i + 1);
236                     delete[] * _piDims;
237                     return false;
238             }
239         }
240
241         return true;
242     }
243
244     return false;
245 }
246
247 types::Double* trigo(types::Double* in, func_real func_r, func_complex func_c, bool forceComplex)
248 {
249     bool isComplex = in->isComplex() || forceComplex;
250     types::Double* out = new types::Double(in->getDims(), in->getDimsArray(), isComplex);
251
252     int size = in->getSize();
253     double* pInR = in->get();
254     double* pOutR = out->get();
255
256     if (isComplex)
257     {
258         double* pInI = in->getImg();
259         double* pOutI = out->getImg();
260         std::complex<double> d;
261         for (int i = 0; i < size; ++i)
262         {
263             d.real(pInR[i]);
264             d.imag(pInI[i]);
265             std::complex<double> res = func_c(d);
266             pOutR[i] = res.real();
267             pOutI[i] = res.imag();
268         }
269     }
270     else
271     {
272         for (int i = 0; i < size; ++i)
273         {
274             pOutR[i] = func_r(pInR[i]);
275         }
276     }
277
278     return out;
279 }