elementary_functions module.
[scilab.git] / scilab / modules / elementary_functions / sci_gateway / cpp / sci_isreal.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 }
25
26 /*--------------------------------------------------------------------------*/
27 types::Function::ReturnValue sci_isreal(types::typed_list &in, int _iRetCount, types::typed_list &out)
28 {
29     double dEps = 0;
30     bool bIsComplex = false;
31
32     if (in.size() < 1 || in.size() > 2)
33     {
34         ScierrorW(77, _W("%ls: Wrong number of input argument(s): %d to %d expected.\n"), L"isreal", 1, 2);
35         return types::Function::Error;
36     }
37
38     if (_iRetCount > 1)
39     {
40         ScierrorW(78, _W("%ls: Wrong number of output argument(s): %d expected.\n"), L"isreal", 1);
41         return types::Function::Error;
42     }
43
44     if (in.size() == 2)
45     {
46         if (in[1]->isDouble() == false)
47         {
48             ScierrorW(999, _W("%ls: Wrong type for input argument #%d: A real scalar expected.\n"), L"isreal", 2);
49             return types::Function::Error;
50         }
51
52         types::Double* pDblEps = in[1]->getAs<types::Double>();
53
54         if ((pDblEps->isScalar() == false) || pDblEps->isComplex())
55         {
56             ScierrorW(999, _W("%ls: Wrong type for input argument #%d: A real scalar expected.\n"), L"isreal", 2);
57             return types::Function::Error;
58         }
59
60         dEps = pDblEps->get(0);
61     }
62
63     if (in[0]->isDouble())
64     {
65         types::Double* pDblIn = in[0]->getAs<types::Double>();
66
67         if (pDblIn->isComplex() == false)
68         {
69             out.push_back(new types::Bool(true));
70             return types::Function::OK;
71         }
72         else if (pDblIn->isComplex() && in.size() == 1)
73         {
74             out.push_back(new types::Bool(false));
75             return types::Function::OK;
76         }
77
78         for (int i = 0; i < pDblIn->getSize(); i++)
79         {
80             if (fabs(pDblIn->getImg(i)) > dEps)
81             {
82                 out.push_back(new types::Bool(false));
83                 return types::Function::OK;
84             }
85         }
86
87         out.push_back(new types::Bool(true));
88         return types::Function::OK;
89     }
90     else if (in[0]->isSparse())
91     {
92         types::Sparse* pSparseIn = in[0]->getAs<types::Sparse>();
93
94         if (pSparseIn->isComplex() == false)
95         {
96             out.push_back(new types::Bool(true));
97             return types::Function::OK;
98         }
99         else if (pSparseIn->isComplex() && in.size() == 1)
100         {
101             out.push_back(new types::Bool(false));
102             return types::Function::OK;
103         }
104
105         int const nonZeros = static_cast<int>(pSparseIn->nonZeros());
106         double* pRows = new double[nonZeros * 2];
107         pSparseIn->outputRowCol(pRows);
108         double* pCols = pRows + nonZeros;
109
110         for (int i = 0 ; i < nonZeros ; i++)
111         {
112             std::complex<double> cplxIn = pSparseIn->getImg(pRows[i] - 1, pCols[i] - 1);
113             if (fabs(cplxIn.imag()) > dEps)
114             {
115                 delete[] pRows;
116                 out.push_back(new types::Bool(false));
117                 return types::Function::OK;
118             }
119         }
120
121         delete[] pRows;
122         out.push_back(new types::Bool(true));
123         return types::Function::OK;
124     }
125     else if (in[0]->isPoly())
126     {
127         types::Polynom* pPolyIn = in[0]->getAs<types::Polynom>();
128
129         if (pPolyIn->isComplex() == false)
130         {
131             out.push_back(new types::Bool(true));
132             return types::Function::OK;
133         }
134         else if (pPolyIn->isComplex() && in.size() == 1)
135         {
136             out.push_back(new types::Bool(false));
137             return types::Function::OK;
138         }
139
140         for (int i = 0; i < pPolyIn->getSize(); i++)
141         {
142             int rank = pPolyIn->get(i)->getRank();
143             for (int j = 0; j < rank; j++)
144             {
145                 if (fabs(pPolyIn->get(i)->getCoefImg()[j]) > dEps)
146                 {
147                     out.push_back(new types::Bool(false));
148                     return types::Function::OK;
149                 }
150             }
151         }
152
153         out.push_back(new types::Bool(true));
154         return types::Function::OK;
155     }
156     else
157     {
158         std::wstring wstFuncName = L"%"  + in[0]->getShortTypeStr() + L"_isreal";
159         return Overload::call(wstFuncName, in, _iRetCount, out, new ExecVisitor());
160     }
161
162     return types::Function::OK;
163 }
164 /*--------------------------------------------------------------------------*/