elementary_functions module.
[scilab.git] / scilab / modules / elementary_functions / sci_gateway / cpp / sci_abs.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2011 - DIGITEO - Antoine ELIAS
4  * Copyright (C) 2012 - DIGITEO - Cedric DELAMARRE
5  *
6  * This file must be used under the terms of the CeCILL.
7  * This source file is licensed as described in the file COPYING, which
8  * you should have received as part of this distribution.  The terms
9  * are also available at
10  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
11  *
12  */
13 /*--------------------------------------------------------------------------*/
14 #include "elem_func_gw.hxx"
15 #include "function.hxx"
16 #include "double.hxx"
17 #include "overload.hxx"
18 #include "execvisitor.hxx"
19
20
21 extern "C"
22 {
23 #include "Scierror.h"
24 #include "localization.h"
25 #include "abs.h"
26 }
27
28 /*--------------------------------------------------------------------------*/
29 types::Function::ReturnValue sci_abs(types::typed_list &in, int _iRetCount, types::typed_list &out)
30 {
31     if (in.size() != 1)
32     {
33         ScierrorW(77, _W("%ls: Wrong number of input argument(s): %d expected.\n"), L"abs", 1);
34         return types::Function::Error;
35     }
36
37     if (_iRetCount > 1)
38     {
39         ScierrorW(78, _W("%ls: Wrong number of output argument(s): %d expected.\n"), L"abs", 1);
40         return types::Function::Error;
41     }
42
43     if (in[0]->isDouble())
44     {
45         types::Double* pDblIn = in[0]->getAs<types::Double>();
46         types::Double* pDblOut = new types::Double(pDblIn->getDims(), pDblIn->getDimsArray());
47
48         if (pDblIn->isComplex())
49         {
50             for (int i = 0 ; i < pDblIn->getSize() ; i++)
51             {
52                 pDblOut->set(i, dabsz(pDblIn->get(i), pDblIn->getImg(i)));
53             }
54         }
55         else
56         {
57             for (int i = 0 ; i < pDblIn->getSize() ; i++)
58             {
59                 pDblOut->set(i, dabss(pDblIn->get(i)));
60             }
61         }
62
63         out.push_back(pDblOut);
64     }
65     else if (in[0]->isPoly())
66     {
67         types::Polynom* pPolyIn = in[0]->getAs<types::Polynom>();
68         types::Polynom* pPolyOut = new types::Polynom(pPolyIn->getVariableName(), pPolyIn->getDims(), pPolyIn->getDimsArray());
69         double* data = NULL;
70
71         if (pPolyIn->isComplex())
72         {
73             for (int i = 0; i < pPolyIn->getSize(); i++)
74             {
75                 int rank = pPolyIn->get(i)->getRank();
76                 types::SinglePoly* pSP = new types::SinglePoly(&data, rank);
77
78                 for (int j = 0; j < rank; j++)
79                 {
80                     data[j] = dabsz(pPolyIn->get(i)->getCoefReal()[j], pPolyIn->get(i)->getCoefImg()[j]);
81                 }
82
83                 pPolyOut->set(i, pSP);
84                 delete pSP;
85                 pSP = NULL;
86             }
87         }
88         else
89         {
90             for (int i = 0; i < pPolyIn->getSize(); i++)
91             {
92                 int rank = pPolyIn->get(i)->getRank();
93                 types::SinglePoly* pSP = new types::SinglePoly(&data, rank);
94
95                 for (int j = 0; j < rank; j++)
96                 {
97                     data[j] = dabss(pPolyIn->get(i)->getCoefReal()[j]);
98                 }
99
100                 pPolyOut->set(i, pSP);
101                 delete pSP;
102                 pSP = NULL;
103             }
104         }
105
106         out.push_back(pPolyOut);
107     }
108     else if (in[0]->isSparse())
109     {
110         types::Sparse* pSparseIn = in[0]->getAs<types::Sparse>();
111         types::Sparse* pSparseOut = new types::Sparse(pSparseIn->getRows(), pSparseIn->getCols());
112
113         int const nonZeros = static_cast<int>(pSparseIn->nonZeros());
114         double* pRows = new double[nonZeros * 2];
115         pSparseIn->outputRowCol(pRows);
116         double* pCols = pRows + nonZeros;
117
118         double* pNonZeroR = new double[nonZeros];
119         double* pNonZeroI = new double[nonZeros];
120         pSparseIn->outputValues(pNonZeroR, pNonZeroI);
121
122         if (pSparseIn->isComplex())
123         {
124             for (int i = 0 ; i < nonZeros ; i++)
125             {
126                 pSparseOut->set(pRows[i] - 1, pCols[i] - 1, dabsz(pNonZeroR[i], pNonZeroI[i]));
127             }
128         }
129         else
130         {
131             for (int i = 0 ; i < nonZeros ; i++)
132             {
133                 pSparseOut->set(pRows[i] - 1, pCols[i] - 1, dabss(pNonZeroR[i]));
134             }
135         }
136
137         delete[] pRows;
138         delete[] pNonZeroR;
139         delete[] pNonZeroI;
140
141         out.push_back(pSparseOut);
142     }
143     else if (in[0]->isInt8())
144     {
145         types::Int8* pIntIn = in[0]->getAs<types::Int8>();
146         types::Int8* pIntOut = new types::Int8(pIntIn->getDims(), pIntIn->getDimsArray());
147
148         for (int i = 0 ; i < pIntIn->getSize() ; i++)
149         {
150             char cInput = pIntIn->get(i);
151             pIntOut->set(i, cInput < 0 ? -cInput : cInput);
152         }
153         out.push_back(pIntOut);
154     }
155     else if (in[0]->isInt16())
156     {
157         types::Int16* pIntIn = in[0]->getAs<types::Int16>();
158         types::Int16* pIntOut = new types::Int16(pIntIn->getDims(), pIntIn->getDimsArray());
159
160         for (int i = 0 ; i < pIntIn->getSize() ; i++)
161         {
162             pIntOut->set(i, abs(pIntIn->get(i)));
163         }
164         out.push_back(pIntOut);
165     }
166     else if (in[0]->isInt32())
167     {
168         types::Int32* pIntIn = in[0]->getAs<types::Int32>();
169         types::Int32* pIntOut = new types::Int32(pIntIn->getDims(), pIntIn->getDimsArray());
170
171         for (int i = 0 ; i < pIntIn->getSize() ; i++)
172         {
173             pIntOut->set(i, abs(pIntIn->get(i)));
174         }
175         out.push_back(pIntOut);
176     }
177     else if (in[0]->isInt64())
178     {
179         types::Int64* pIntIn = in[0]->getAs<types::Int64>();
180         types::Int64* pIntOut = new types::Int64(pIntIn->getDims(), pIntIn->getDimsArray());
181
182         for (int i = 0 ; i < pIntIn->getSize() ; i++)
183         {
184             pIntOut->set(i, llabs(pIntIn->get(i)));
185         }
186         out.push_back(pIntOut);
187     }
188     else if (in[0]->isUInt8())
189     {
190         out.push_back(in[0]->getAs<types::UInt8>()->clone());
191     }
192     else if (in[0]->isUInt16())
193     {
194         out.push_back(in[0]->getAs<types::UInt16>()->clone());
195     }
196     else if (in[0]->isUInt32())
197     {
198         out.push_back(in[0]->getAs<types::UInt32>()->clone());
199     }
200     else if (in[0]->isUInt64())
201     {
202         out.push_back(in[0]->getAs<types::UInt64>()->clone());
203     }
204     else
205     {
206         std::wstring wstFuncName = L"%"  + in[0]->getShortTypeStr() + L"_abs";
207         return Overload::call(wstFuncName, in, _iRetCount, out, new ExecVisitor());
208     }
209
210     return types::Function::OK;
211 }
212 /*--------------------------------------------------------------------------*/