3f57f807afc3138410395ffe66adb14ed4de95f4
[scilab.git] / scilab / modules / elementary_functions / sci_gateway / cpp / sci_imag.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 "elem_common.h"
25 }
26
27 /*--------------------------------------------------------------------------*/
28 types::Function::ReturnValue sci_imag(types::typed_list &in, int _iRetCount, types::typed_list &out)
29 {
30     if (in.size() != 1)
31     {
32         Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), "imag", 1);
33         return types::Function::Error;
34     }
35
36     if (_iRetCount > 1)
37     {
38         Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "imag", 1);
39         return types::Function::Error;
40     }
41
42     if (in[0]->isDouble())
43     {
44         types::Double* pDblIn = in[0]->getAs<types::Double>();
45
46         int iSize = pDblIn->getSize();
47         int iOne = 1;
48
49         types::Double* pDblOut = new types::Double(pDblIn->getDims(), pDblIn->getDimsArray());
50
51         if (pDblIn->isComplex() == false)
52         {
53             memset(pDblOut->get(), 0x00, iSize * sizeof(double));
54         }
55         else
56         {
57             C2F(dcopy)(&iSize, pDblIn->getImg(), &iOne, pDblOut->getReal(), &iOne);
58         }
59
60
61         out.push_back(pDblOut);
62     }
63     else if (in[0]->isSparse())
64     {
65         types::Sparse* pSparseIn = in[0]->getAs<types::Sparse>();
66         types::Sparse* pSparseOut = new types::Sparse(pSparseIn->getRows(), pSparseIn->getCols());
67
68         if (pSparseIn->isComplex() == false)
69         {
70             out.push_back(pSparseOut);
71             return types::Function::OK;
72         }
73
74         int const nonZeros = static_cast<int>(pSparseIn->nonZeros());
75         int* pRows = new int[nonZeros * 2];
76         pSparseIn->outputRowCol(pRows);
77         int* pCols = pRows + nonZeros;
78
79         for (int i = 0 ; i < nonZeros ; i++)
80         {
81             std::complex<double> cplx = pSparseIn->getImg(pRows[i] - 1, pCols[i] - 1);
82             pSparseOut->set(pRows[i] - 1, pCols[i] - 1, cplx.imag(), false);
83         }
84
85         pSparseOut->finalize();
86
87         delete[] pRows;
88
89         out.push_back(pSparseOut);
90     }
91     else if (in[0]->isPoly())
92     {
93         types::Polynom* pPolyIn = in[0]->getAs<types::Polynom>();
94         types::Polynom* pPolyOut = new types::Polynom(pPolyIn->getVariableName(), pPolyIn->getDims(), pPolyIn->getDimsArray());
95
96         double* dataReal = NULL;
97
98         if (pPolyIn->isComplex() == false)
99         {
100             // Create a polynom null of size of input polynom
101             for (int i = 0; i < pPolyIn->getSize(); i++)
102             {
103                 types::SinglePoly* pSP = new types::SinglePoly(&dataReal, 1);
104                 dataReal[0]  = 0;
105                 pPolyOut->set(i, pSP);
106                 delete pSP;
107                 pSP = NULL;
108             }
109         }
110         else
111         {
112             for (int i = 0; i < pPolyIn->getSize(); i++)
113             {
114                 int rank = pPolyIn->get(i)->getRank();
115                 int iNewRank = rank;
116
117                 // Reduce the rank of output polynom if the last ranks are null
118                 for (int j = rank - 1 ; j > 0 ; j--)
119                 {
120                     if (pPolyIn->get(i)->getCoefImg()[j] == 0.0)
121                     {
122                         iNewRank--;
123                     }
124                     else
125                     {
126                         break;
127                     }
128                 }
129
130                 types::SinglePoly* pSP = new types::SinglePoly(&dataReal, iNewRank);
131
132                 for (int j = 0; j < iNewRank; j++)
133                 {
134                     dataReal[j]  = pPolyIn->get(i)->getCoefImg()[j];
135                 }
136
137                 pPolyOut->set(i, pSP);
138                 delete pSP;
139                 pSP = NULL;
140             }
141         }
142         out.push_back(pPolyOut);
143     }
144     else
145     {
146         std::wstring wstFuncName = L"%"  + in[0]->getShortTypeStr() + L"_imag";
147         return Overload::call(wstFuncName, in, _iRetCount, out, new ast::ExecVisitor());
148     }
149
150     return types::Function::OK;
151 }
152 /*--------------------------------------------------------------------------*/