elementary_functions module.
[scilab.git] / scilab / modules / elementary_functions / sci_gateway / cpp / sci_int.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - DIGITEO - Cedric DELAMARRE
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 "elem_func_gw.hxx"
14 #include "function.hxx"
15 #include "double.hxx"
16 #include "overload.hxx"
17 #include "execvisitor.hxx"
18
19
20 extern "C"
21 {
22 #include "Scierror.h"
23 #include "localization.h"
24 #include "core_math.h"
25 }
26
27 /*--------------------------------------------------------------------------*/
28 types::Function::ReturnValue sci_int(types::typed_list &in, int _iRetCount, types::typed_list &out)
29 {
30     if (in.size() != 1)
31     {
32         ScierrorW(77, _W("%ls: Wrong number of input argument(s): %d expected.\n"), L"int", 1);
33         return types::Function::Error;
34     }
35
36     if (_iRetCount > 1)
37     {
38         ScierrorW(78, _W("%ls: Wrong number of output argument(s): %d expected.\n"), L"int", 1);
39         return types::Function::Error;
40     }
41
42     if (in[0]->isDouble())
43     {
44         types::Double* pDblIn = in[0]->getAs<types::Double>();
45         types::Double* pDblOut = new types::Double(pDblIn->getDims(), pDblIn->getDimsArray(), pDblIn->isComplex());
46
47         if (pDblIn->isComplex())
48         {
49             for (int i = 0 ; i < pDblIn->getSize() ; i++)
50             {
51                 if (finite(pDblIn->getImg(i)))
52                 {
53                     pDblOut->setImg(i, (double)(long long int)pDblIn->getImg(i));
54                 }
55                 else
56                 {
57                     pDblOut->setImg(i, pDblIn->getImg(i));
58                 }
59             }
60         }
61
62         for (int i = 0 ; i < pDblIn->getSize() ; i++)
63         {
64             if (finite(pDblIn->get(i)))
65             {
66                 pDblOut->set(i, (double)(long long int)pDblIn->get(i));
67             }
68             else
69             {
70                 pDblOut->set(i, pDblIn->get(i));
71             }
72         }
73
74         out.push_back(pDblOut);
75     }
76     else if (in[0]->isSparse())
77     {
78         types::Sparse* pSparseIn = in[0]->getAs<types::Sparse>();
79         types::Sparse* pSparseOut = new types::Sparse(pSparseIn->getRows(), pSparseIn->getCols(), pSparseIn->isComplex());
80
81         int const nonZeros = static_cast<int>(pSparseIn->nonZeros());
82         double* pRows = new double[nonZeros * 2];
83         pSparseIn->outputRowCol(pRows);
84         double* pCols = pRows + nonZeros;
85
86         double* pNonZeroR = new double[nonZeros];
87         double* pNonZeroI = new double[nonZeros];
88         pSparseIn->outputValues(pNonZeroR, pNonZeroI);
89
90         if (pSparseIn->isComplex())
91         {
92             for (int i = 0; i < nonZeros; i++)
93             {
94                 if (finite(pNonZeroR[i]))
95                 {
96                     pNonZeroR[i] = (double)(long long int)pNonZeroR[i];
97                 }
98
99                 if (finite(pNonZeroI[i]))
100                 {
101                     pNonZeroI[i] = (double)(long long int)pNonZeroI[i];
102                 }
103
104                 std::complex<double> cplx(pNonZeroR[i], pNonZeroI[i]);
105                 pSparseOut->set(pRows[i] - 1, pCols[i] - 1, cplx);
106             }
107         }
108         else
109         {
110             for (int i = 0; i < nonZeros; i++)
111             {
112                 if (finite(pNonZeroR[i]))
113                 {
114                     pNonZeroR[i] = (double)(long long int)pNonZeroR[i];
115                 }
116
117                 pSparseOut->set(pRows[i] - 1, pCols[i] - 1, pNonZeroR[i]);
118             }
119         }
120
121         delete[] pRows;
122         delete[] pNonZeroR;
123         delete[] pNonZeroI;
124
125         out.push_back(pSparseOut);
126     }
127     else if (in[0]->isPoly())
128     {
129         types::Polynom* pPolyIn = in[0]->getAs<types::Polynom>();
130         types::Polynom* pPolyOut = new types::Polynom(pPolyIn->getVariableName(), pPolyIn->getDims(), pPolyIn->getDimsArray());
131         pPolyOut->setComplex(pPolyIn->isComplex());
132
133         double* dataImg  = NULL;
134         double* dataReal = NULL;
135
136         if (pPolyIn->isComplex())
137         {
138             for (int i = 0; i < pPolyIn->getSize(); i++)
139             {
140                 int rank = pPolyIn->get(i)->getRank();
141                 types::SinglePoly* pSP = new types::SinglePoly(&dataReal, &dataImg, rank);
142
143                 for (int j = 0; j < rank; j++)
144                 {
145                     if (finite(pPolyIn->get(i)->getCoefReal()[j]))
146                     {
147                         dataReal[j] = (double)(long long int)pPolyIn->get(i)->getCoefReal()[j];
148                     }
149                     else
150                     {
151                         dataReal[j] = pPolyIn->get(i)->getCoefReal()[j];
152                     }
153
154                     if (finite(pPolyIn->get(i)->getCoefImg()[j]))
155                     {
156                         dataImg[j]  = (double)(long long int)pPolyIn->get(i)->getCoefImg()[j];
157                     }
158                     else
159                     {
160                         dataImg[j] = pPolyIn->get(i)->getCoefImg()[j];
161                     }
162                 }
163
164                 pPolyOut->set(i, pSP);
165                 delete pSP;
166                 pSP = NULL;
167             }
168         }
169         else
170         {
171             for (int i = 0; i < pPolyIn->getSize(); i++)
172             {
173                 int rank = pPolyIn->get(i)->getRank();
174                 types::SinglePoly* pSP = new types::SinglePoly(&dataReal, rank);
175
176                 for (int j = 0; j < rank; j++)
177                 {
178                     if (finite(pPolyIn->get(i)->getCoefReal()[j]))
179                     {
180                         dataReal[i] = (double)(long long int)pPolyIn->get(i)->getCoefReal()[j];
181                     }
182                     else
183                     {
184                         dataReal[j] = pPolyIn->get(i)->getCoefReal()[j];
185                     }
186                 }
187
188                 pPolyOut->set(i, pSP);
189                 delete pSP;
190                 pSP = NULL;
191             }
192         }
193
194         out.push_back(pPolyOut);
195     }
196     else
197     {
198         std::wstring wstFuncName = L"%"  + in[0]->getShortTypeStr() + L"_int";
199         return Overload::call(wstFuncName, in, _iRetCount, out, new ExecVisitor());
200     }
201
202     return types::Function::OK;
203 }
204 /*--------------------------------------------------------------------------*/