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 * Copyright (C) 2018 - Stéphane MOTTELET
6 * Copyright (C) 2012 - 2016 - Scilab Enterprises
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.
16 //for Visual Leak Detector in debug compilation mode
18 #if defined(DEBUG_VLD) && defined(_DEBUG)
22 #include "elem_func_gw.hxx"
23 #include "function.hxx"
24 #include "context.hxx"
25 #include "overload.hxx"
27 #include "localization.h"
28 #include "charEncoding.h"
35 #define MODULE_NAME L"elementary_functions"
38 #include "gw_elementary_functions.h"
41 int ElemFuncModule::Load()
43 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"abs", &sci_abs, MODULE_NAME));
44 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"acos", &sci_acos, MODULE_NAME));
45 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"asin", &sci_asin, MODULE_NAME));
46 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"atan", &sci_atan, MODULE_NAME));
47 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"bitstring", &sci_bitstring, MODULE_NAME));
48 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"ceil", &sci_ceil, MODULE_NAME));
49 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"clean", &sci_clean, MODULE_NAME));
50 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"conj", &sci_conj, MODULE_NAME));
51 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"cos", &sci_cos, MODULE_NAME));
52 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"cumprod", &sci_cumprod, MODULE_NAME));
53 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"cumsum", &sci_cumsum, MODULE_NAME));
54 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"diag", &sci_diag, MODULE_NAME));
55 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"dsearch", &sci_dsearch, MODULE_NAME));
56 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"exp", &sci_exp, MODULE_NAME));
57 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"expm", &sci_expm, MODULE_NAME));
58 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"eye", &sci_eye, MODULE_NAME));
59 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"floor", &sci_floor, MODULE_NAME));
60 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"frexp", &sci_frexp, MODULE_NAME));
61 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"gsort", &sci_gsort, MODULE_NAME));
62 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"imag", &sci_imag, MODULE_NAME));
63 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"imult", &sci_imult, MODULE_NAME));
64 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"int", &sci_int, MODULE_NAME));
65 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"isreal", &sci_isreal, MODULE_NAME));
66 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"isequal", &sci_isequal, MODULE_NAME));
67 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"isvector", &sci_isvector, MODULE_NAME));
68 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"kron", &sci_kron, MODULE_NAME));
69 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"linspace", &sci_linspace, MODULE_NAME));
70 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"log", &sci_log, MODULE_NAME));
71 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"log1p", &sci_log1p, MODULE_NAME));
72 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"matrix", &sci_matrix, MODULE_NAME));
73 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"max", &sci_max, MODULE_NAME));
74 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"min", &sci_min, MODULE_NAME));
75 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"nearfloat", &sci_nearfloat, MODULE_NAME));
76 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"number_properties", &sci_number_properties, MODULE_NAME));
77 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"ones", &sci_ones, MODULE_NAME));
78 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"prod", &sci_prod, MODULE_NAME));
79 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"permute", &sci_permute, MODULE_NAME));
80 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"rand", &sci_rand, MODULE_NAME));
81 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"real", &sci_real, MODULE_NAME));
82 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"round", &sci_round, MODULE_NAME));
83 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"sign", &sci_sign, MODULE_NAME));
84 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"sin", &sci_sin, MODULE_NAME));
85 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"size", &sci_size, MODULE_NAME));
86 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"sqrt", &sci_sqrt, MODULE_NAME));
87 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"sum", &sci_sum, MODULE_NAME));
88 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"tan", &sci_tan, MODULE_NAME));
89 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"testmatrix", &sci_testmatrix, MODULE_NAME));
90 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"tril", &sci_tril, MODULE_NAME));
91 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"triu", &sci_triu, MODULE_NAME));
92 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"zeros", &sci_zeros, MODULE_NAME));
93 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"rat", &sci_rat, MODULE_NAME));
94 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"base2dec", &sci_base2dec, MODULE_NAME));
95 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"dec2base", &sci_dec2base, MODULE_NAME));
96 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"log10", &sci_log10, MODULE_NAME));
97 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"cosh", &sci_cosh, MODULE_NAME));
98 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"sinh", &sci_sinh, MODULE_NAME));
99 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"tanh", &sci_tanh, MODULE_NAME));
100 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"acosh", &sci_acosh, MODULE_NAME));
101 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"asinh", &sci_asinh, MODULE_NAME));
102 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"atanh", &sci_atanh, MODULE_NAME));
103 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"isvector", &sci_isvector, MODULE_NAME));
104 symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"issquare", &sci_issquare, MODULE_NAME));
109 bool getDimsFromArguments(types::typed_list& in, const std::string& _pstName, int* _iDims, int** _piDims, bool* _alloc)
111 types::Double* pOut = 0;
120 *_piDims = new int[*_iDims];
126 else if (in.size() == 1)
130 if (in[0]->isColon())
136 if (in[0]->isArrayOf() == false)
138 if (in[0]->isSparse())
140 types::Sparse* sp = in[0]->getAs<types::Sparse>();
141 *_iDims = sp->getDims();
142 *_piDims = sp->getDimsArray();
145 else if (in[0]->isSparseBool())
147 types::SparseBool* sp = in[0]->getAs<types::SparseBool>();
148 *_iDims = sp->getDims();
149 *_piDims = sp->getDimsArray();
155 types::GenericType* pIn = in[0]->getAs<types::GenericType>();
156 *_iDims = pIn->getDims();
157 *_piDims = pIn->getDimsArray();
163 *_iDims = static_cast<int>(in.size());
164 *_piDims = new int[*_iDims];
166 for (int i = 0; i < *_iDims; i++)
168 if (in[i]->isArrayOf() == false)
170 Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), _pstName.c_str(), i + 1);
175 types::GenericType* pGTIn = in[i]->getAs<types::GenericType>();
176 if (pGTIn->isScalar() == false || pGTIn->isComplex())
178 Scierror(999, _("%s: Wrong size for input argument #%d: A scalar expected.\n"), _pstName.c_str(), i + 1);
183 switch (in[i]->getType())
185 case types::InternalType::ScilabDouble:
187 double dValue = in[i]->getAs<types::Double>()->get(0);
188 if (dValue >= INT_MAX)
190 Scierror(999, _("%s: variable size exceeded : less than %d expected.\n"), _pstName.c_str(), INT_MAX);
194 (*_piDims)[i] = static_cast<int>(dValue);
197 case types::InternalType::ScilabInt8:
198 (*_piDims)[i] = static_cast<int>(in[i]->getAs<types::Int8>()->get()[0]);
200 case types::InternalType::ScilabUInt8:
201 (*_piDims)[i] = static_cast<int>(in[i]->getAs<types::UInt8>()->get()[0]);
203 case types::InternalType::ScilabInt16:
204 (*_piDims)[i] = static_cast<int>(in[i]->getAs<types::Int16>()->get()[0]);
206 case types::InternalType::ScilabUInt16:
207 (*_piDims)[i] = static_cast<int>(in[i]->getAs<types::UInt16>()->get()[0]);
209 case types::InternalType::ScilabInt32:
210 (*_piDims)[i] = in[i]->getAs<types::Int32>()->get()[0];
212 case types::InternalType::ScilabUInt32:
213 (*_piDims)[i] = static_cast<int>(in[i]->getAs<types::UInt32>()->get()[0]);
215 case types::InternalType::ScilabInt64:
217 long long llValue = in[i]->getAs<types::Int64>()->get(0);
218 if (llValue >= INT_MAX)
220 Scierror(999, _("%s: variable size exceeded : less than %d expected.\n"), _pstName.c_str(), INT_MAX);
224 (*_piDims)[i] = static_cast<int>(llValue);
227 case types::InternalType::ScilabUInt64:
229 unsigned long long ullValue = in[i]->getAs<types::UInt64>()->get(0);
230 if (ullValue >= INT_MAX)
232 Scierror(999, _("%s: variable size exceeded : less than %d expected.\n"), _pstName.c_str(), INT_MAX);
236 (*_piDims)[i] = static_cast<int>(ullValue);
240 Scierror(999, _("%s: Wrong size for input argument #%d: A scalar expected.\n"), _pstName.c_str(), i + 1);
252 types::Double* trigo(types::Double* in, func_real func_r, func_complex func_c, bool forceComplex)
254 bool isComplex = in->isComplex() || forceComplex;
255 types::Double* out = new types::Double(in->getDims(), in->getDimsArray(), isComplex);
257 int size = in->getSize();
258 double* pInR = in->get();
259 double* pOutR = out->get();
263 double* pInI = in->getImg();
264 double* pOutI = out->getImg();
265 std::complex<double> d;
266 for (int i = 0; i < size; ++i)
270 std::complex<double> res = func_c(d);
271 pOutR[i] = res.real();
272 pOutI[i] = res.imag();
277 for (int i = 0; i < size; ++i)
279 pOutR[i] = func_r(pInR[i]);
286 types::Function::ReturnValue zerosOrOnesFromValue(types::typed_list& in, int _iRetCount, types::typed_list& out, bool value)
291 static std::map<std::wstring, types::InternalType::ScilabType> mapOfTypes = {
292 {L"double", types::InternalType::ScilabDouble},
293 {L"constant", types::InternalType::ScilabDouble},
294 {L"boolean", types::InternalType::ScilabBool},
295 {L"uint8", types::InternalType::ScilabUInt8},
296 {L"int8", types::InternalType::ScilabInt8},
297 {L"uint16", types::InternalType::ScilabUInt16},
298 {L"int16", types::InternalType::ScilabInt16},
299 {L"uint32", types::InternalType::ScilabUInt32},
300 {L"int32", types::InternalType::ScilabInt32},
301 {L"uint64", types::InternalType::ScilabUInt64},
302 {L"int64", types::InternalType::ScilabInt64}
305 types::InternalType::ScilabType reftype = types::InternalType::ScilabDouble;
308 int size = (int)in.size();
309 types::InternalType* it = in[size - 1];
310 if (size > 1 && it->isString())
312 // get optional type string
313 wchar_t* pType = it->getAs<types::String>()->get()[0];
314 auto f = mapOfTypes.find(pType);
315 if (f == mapOfTypes.end())
317 Scierror(999, _("%s: Wrong value for input argument #%d: Must be in the set {%s}"),
318 value ? "ones" : "zeros", in.size(), "double, boolean, (u)int(8|16|32|64) ");
319 return types::Function::Error;
326 bool ret = getDimsFromArguments(in, value ? "ones" : "zeros", &iDims, &piDims, &alloc);
332 Scierror(21, _("Invalid index.\n"));
337 return Overload::generateNameAndCall(value ? L"ones" : L"zeros", in, _iRetCount, out);
341 return types::Function::Error;
344 if (std::find(piDims, piDims+iDims, 0) != piDims+iDims)
346 // in Scilab, empty matrix is always a Double
347 reftype = types::InternalType::ScilabDouble;
352 case types::InternalType::ScilabInt8:
354 types::Int8* pOut = new types::Int8(iDims, piDims);
355 std::fill(pOut->get(), pOut->get() + pOut->getSize(), value);
359 case types::InternalType::ScilabInt16:
361 types::Int16* pOut = new types::Int16(iDims, piDims);
362 std::fill(pOut->get(), pOut->get() + pOut->getSize(), value);
366 case types::InternalType::ScilabInt32:
368 types::Int32* pOut = new types::Int32(iDims, piDims);
369 std::fill(pOut->get(), pOut->get() + pOut->getSize(), value);
373 case types::InternalType::ScilabInt64:
375 types::Int64* pOut = new types::Int64(iDims, piDims);
376 std::fill(pOut->get(), pOut->get() + pOut->getSize(), value);
380 case types::InternalType::ScilabUInt8:
382 types::UInt8* pOut = new types::UInt8(iDims, piDims);
383 std::fill(pOut->get(), pOut->get() + pOut->getSize(), value);
387 case types::InternalType::ScilabUInt16:
389 types::UInt16* pOut = new types::UInt16(iDims, piDims);
390 std::fill(pOut->get(), pOut->get() + pOut->getSize(), value);
394 case types::InternalType::ScilabUInt32:
396 types::UInt32* pOut = new types::UInt32(iDims, piDims);
397 std::fill(pOut->get(), pOut->get() + pOut->getSize(), value);
401 case types::InternalType::ScilabUInt64:
403 types::UInt64* pOut = new types::UInt64(iDims, piDims);
404 std::fill(pOut->get(), pOut->get() + pOut->getSize(), value);
408 case types::InternalType::ScilabBool:
410 types::Bool* pOut = new types::Bool(iDims, piDims);
411 std::fill(pOut->get(), pOut->get() + pOut->getSize(), value);
415 default: // other cases: create double with inherited dimensions only (not type)
416 case types::InternalType::ScilabDouble:
418 types::Double* pOut = new types::Double(iDims, piDims);
419 std::fill(pOut->get(), pOut->get() + pOut->getSize(), value);
430 return types::Function::OK;