elementary_functions module.
[scilab.git] / scilab / modules / elementary_functions / sci_gateway / cpp / sci_diag.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 #include "diag.hxx"
19
20 extern "C"
21 {
22 #include "Scierror.h"
23 #include "localization.h"
24 }
25
26 /*--------------------------------------------------------------------------*/
27 types::Function::ReturnValue sci_diag(types::typed_list &in, int _iRetCount, types::typed_list &out)
28 {
29     types::Double* pDblIn       = NULL;
30     types::Polynom* pPolyIn     = NULL;
31     types::String* pStrIn       = NULL;
32
33     types::Double* pDblOut      = NULL;
34     types::Polynom* pPolyOut    = NULL;
35     types::String* pStrOut      = NULL;
36
37     int iStartPos = 0;
38
39     if (in.size() < 1 || in.size() > 2)
40     {
41         ScierrorW(77, _W("%ls: Wrong number of input argument(s): %d to %d expected.\n"), L"diag", 1, 2);
42         return types::Function::Error;
43     }
44
45     if (_iRetCount > 1)
46     {
47         ScierrorW(78, _W("%ls: Wrong number of output argument(s): %d expected.\n"), L"diag", 1);
48         return types::Function::Error;
49     }
50
51     /***** get data *****/
52     if (in[0]->isDouble())
53     {
54         pDblIn = in[0]->getAs<types::Double>();
55
56         if (pDblIn->getDims() > 2)
57         {
58             std::wstring wstFuncName = L"%hm_diag";
59             return Overload::call(wstFuncName, in, _iRetCount, out, new ExecVisitor());
60         }
61     }
62     else if (in[0]->isString())
63     {
64         pStrIn = in[0]->getAs<types::String>();
65
66         if (pStrIn->getDims() > 2)
67         {
68             std::wstring wstFuncName = L"%hm_diag";
69             return Overload::call(wstFuncName, in, _iRetCount, out, new ExecVisitor());
70         }
71     }
72     else if (in[0]->isBool()) // bool
73     {
74         types::Bool* pBIn = in[0]->getAs<types::Bool>();
75         pDblIn = new types::Double(pBIn->getDims(), pBIn->getDimsArray());
76         for (int i = 0; i < pBIn->getSize(); i++)
77         {
78             pBIn->get(i) ? pDblIn->set(i, 1) : pDblIn->set(i, 0);
79         }
80     }
81     else if (in[0]->isPoly())
82     {
83         pPolyIn = in[0]->getAs<types::Polynom>();
84         if (pPolyIn->getDims() > 2)
85         {
86             std::wstring wstFuncName = L"%hm_diag";
87             return Overload::call(wstFuncName, in, _iRetCount, out, new ExecVisitor());
88         }
89     }
90     else if (in[0]->isInt8()) // int
91     {
92         types::Int8* pIIn = in[0]->getAs<types::Int8>();
93         pDblIn = new types::Double(pIIn->getDims(), pIIn->getDimsArray());
94         for (int i = 0; i < pIIn->getSize(); i++)
95         {
96             pDblIn->set(i, static_cast<double>(pIIn->get(i)));
97         }
98     }
99     else if (in[0]->isInt16())
100     {
101         types::Int16* pIIn = in[0]->getAs<types::Int16>();
102         pDblIn = new types::Double(pIIn->getDims(), pIIn->getDimsArray());
103         for (int i = 0; i < pIIn->getSize(); i++)
104         {
105             pDblIn->set(i, static_cast<double>(pIIn->get(i)));
106         }
107     }
108     else if (in[0]->isInt32())
109     {
110         types::Int32* pIIn = in[0]->getAs<types::Int32>();
111         pDblIn = new types::Double(pIIn->getDims(), pIIn->getDimsArray());
112         for (int i = 0; i < pIIn->getSize(); i++)
113         {
114             pDblIn->set(i, static_cast<double>(pIIn->get(i)));
115         }
116     }
117     else if (in[0]->isInt64()) // uint
118     {
119         types::Int64* pIIn = in[0]->getAs<types::Int64>();
120         pDblIn = new types::Double(pIIn->getDims(), pIIn->getDimsArray());
121         for (int i = 0; i < pIIn->getSize(); i++)
122         {
123             pDblIn->set(i, static_cast<double>(pIIn->get(i)));
124         }
125     }
126     else if (in[0]->isUInt8())
127     {
128         types::Int8* pIIn = in[0]->getAs<types::Int8>();
129         pDblIn = new types::Double(pIIn->getDims(), pIIn->getDimsArray());
130         for (int i = 0; i < pIIn->getSize(); i++)
131         {
132             pDblIn->set(i, static_cast<double>(pIIn->get(i)));
133         }
134     }
135     else if (in[0]->isUInt16())
136     {
137         types::Int16* pIIn = in[0]->getAs<types::Int16>();
138         pDblIn = new types::Double(pIIn->getDims(), pIIn->getDimsArray());
139         for (int i = 0; i < pIIn->getSize(); i++)
140         {
141             pDblIn->set(i, static_cast<double>(pIIn->get(i)));
142         }
143     }
144     else if (in[0]->isUInt32())
145     {
146         types::Int32* pIIn = in[0]->getAs<types::Int32>();
147         pDblIn = new types::Double(pIIn->getDims(), pIIn->getDimsArray());
148         for (int i = 0; i < pIIn->getSize(); i++)
149         {
150             pDblIn->set(i, static_cast<double>(pIIn->get(i)));
151         }
152     }
153     else if (in[0]->isUInt64())
154     {
155         types::Int64* pIIn = in[0]->getAs<types::Int64>();
156         pDblIn = new types::Double(pIIn->getDims(), pIIn->getDimsArray());
157         for (int i = 0; i < pIIn->getSize(); i++)
158         {
159             pDblIn->set(i, static_cast<double>(pIIn->get(i)));
160         }
161     }
162     else
163     {
164         std::wstring wstFuncName = L"%"  + in[0]->getShortTypeStr() + L"_diag";
165         return Overload::call(wstFuncName, in, _iRetCount, out, new ExecVisitor());
166     }
167
168     if (in.size() == 2)
169     {
170         if (in[1]->isDouble() == false)
171         {
172             ScierrorW(999, _W("%ls: Wrong type for input argument #%d : A real scalar expected.\n"), L"diag", 2);
173             return types::Function::Error;
174         }
175
176         types::Double* pDbl = in[1]->getAs<types::Double>();
177
178         if (pDbl->isScalar() == false || pDbl->isComplex())
179         {
180             ScierrorW(999, _W("%ls: Wrong type for input argument #%d : A real scalar expected.\n"), L"diag", 2);
181             return types::Function::Error;
182         }
183
184         iStartPos = static_cast<int>(pDbl->get(0));
185     }
186
187     /***** perform operation *****/
188     if (pDblIn)
189     {
190         pDblOut = diag(pDblIn, iStartPos);
191     }
192     else if (pPolyIn)
193     {
194         pPolyOut = diag(pPolyIn, iStartPos);
195         if (pPolyOut == NULL)
196         {
197             out.push_back(types::Double::Empty());
198             return types::Function::OK;
199         }
200     }
201     else if (pStrIn)
202     {
203         pStrOut = diag(pStrIn, iStartPos);
204         if (pStrOut == NULL)
205         {
206             out.push_back(types::Double::Empty());
207             return types::Function::OK;
208         }
209     }
210
211     /***** set result *****/
212     if (in[0]->isDouble())
213     {
214         out.push_back(pDblOut);
215     }
216     else if (in[0]->isBool())
217     {
218         types::Bool* pBOut = new types::Bool(pDblOut->getDims(), pDblOut->getDimsArray());
219         for (int i = 0; i < pDblOut->getSize(); i++)
220         {
221             pDblOut->get(i) ? pBOut->set(i, 1) : pBOut->set(i, 0);
222         }
223         out.push_back(pBOut);
224         delete pDblOut;
225     }
226     else if (in[0]->isPoly())
227     {
228         out.push_back(pPolyOut);
229     }
230     else if (in[0]->isString())
231     {
232         out.push_back(pStrOut);
233     }
234     else if (in[0]->isInt8())
235     {
236         types::Int8* pIOut = new types::Int8(pDblOut->getDims(), pDblOut->getDimsArray());
237         for (int i = 0; i < pIOut->getSize(); i++)
238         {
239             pIOut->set(i, static_cast<char>(pDblOut->get(i)));
240         }
241         out.push_back(pIOut);
242         delete pDblOut;
243     }
244     else if (in[0]->isInt16())
245     {
246         types::Int16* pIOut = new types::Int16(pDblOut->getDims(), pDblOut->getDimsArray());
247         for (int i = 0; i < pIOut->getSize(); i++)
248         {
249             pIOut->set(i, static_cast<short int>(pDblOut->get(i)));
250         }
251         out.push_back(pIOut);
252         delete pDblOut;
253     }
254     else if (in[0]->isInt32())
255     {
256         types::Int32* pIOut = new types::Int32(pDblOut->getDims(), pDblOut->getDimsArray());
257         for (int i = 0; i < pIOut->getSize(); i++)
258         {
259             pIOut->set(i, static_cast<int>(pDblOut->get(i)));
260         }
261         out.push_back(pIOut);
262         delete pDblOut;
263     }
264     else if (in[0]->isInt64())
265     {
266         types::Int64* pIOut = new types::Int64(pDblOut->getDims(), pDblOut->getDimsArray());
267         for (int i = 0; i < pIOut->getSize(); i++)
268         {
269             pIOut->set(i, static_cast<long long int>(pDblOut->get(i)));
270         }
271         out.push_back(pIOut);
272         delete pDblOut;
273     }
274     else if (in[0]->isUInt8())
275     {
276         types::UInt8* pIOut = new types::UInt8(pDblOut->getDims(), pDblOut->getDimsArray());
277         for (int i = 0; i < pIOut->getSize(); i++)
278         {
279             pIOut->set(i, static_cast<unsigned char>(pDblOut->get(i)));
280         }
281         out.push_back(pIOut);
282         delete pDblOut;
283     }
284     else if (in[0]->isUInt16())
285     {
286         types::UInt16* pIOut = new types::UInt16(pDblOut->getDims(), pDblOut->getDimsArray());
287         for (int i = 0; i < pIOut->getSize(); i++)
288         {
289             pIOut->set(i, static_cast<unsigned short int>(pDblOut->get(i)));
290         }
291         out.push_back(pIOut);
292         delete pDblOut;
293     }
294     else if (in[0]->isUInt32())
295     {
296         types::UInt32* pIOut = new types::UInt32(pDblOut->getDims(), pDblOut->getDimsArray());
297         for (int i = 0; i < pIOut->getSize(); i++)
298         {
299             pIOut->set(i, static_cast<unsigned int>(pDblOut->get(i)));
300         }
301         out.push_back(pIOut);
302         delete pDblOut;
303     }
304     else if (in[0]->isUInt64())
305     {
306         types::UInt64* pIOut = new types::UInt64(pDblOut->getDims(), pDblOut->getDimsArray());
307         for (int i = 0; i < pIOut->getSize(); i++)
308         {
309             pIOut->set(i, static_cast<unsigned long long int>(pDblOut->get(i)));
310         }
311         out.push_back(pIOut);
312         delete pDblOut;
313     }
314
315     return types::Function::OK;
316 }
317 /*--------------------------------------------------------------------------*/