refactoring polynom.
[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 = NULL;
95
96         if (pPolyIn->isComplex())
97         {
98             pPolyOut = new types::Polynom(pPolyIn->getVariableName(), pPolyIn->getDims(), pPolyIn->getDimsArray());
99             for (int i = 0; i < pPolyIn->getSize(); i++)
100             {
101                 int rank = pPolyIn->get(i)->getRank();
102                 int iNewRank = rank;
103
104                 // Reduce the rank of output polynom if the last ranks are null
105                 for (int j = rank ; j > 0 ; j--)
106                 {
107                     if (pPolyIn->get(i)->getImg()[j] == 0.0)
108                     {
109                         iNewRank--;
110                     }
111                     else
112                     {
113                         break;
114                     }
115                 }
116
117                 double* dataReal = NULL;
118                 types::SinglePoly* pSP = new types::SinglePoly(&dataReal, iNewRank);
119
120                 for (int j = 0; j < iNewRank + 1; j++)
121                 {
122                     dataReal[j] = pPolyIn->get(i)->getImg()[j];
123                 }
124
125                 pPolyOut->set(i, pSP);
126                 delete pSP;
127                 pSP = NULL;
128             }
129         }
130         else
131         {
132             int iSize = pPolyIn->getSize();
133             int* piRanks = new int[iSize];
134             memset(piRanks, 0x00, iSize * sizeof(int));
135             pPolyOut = new types::Polynom(pPolyIn->getVariableName(), pPolyIn->getDims(), pPolyIn->getDimsArray(), piRanks);
136             pPolyOut->setZeros();
137             delete[] piRanks;
138         }
139
140         out.push_back(pPolyOut);
141     }
142     else
143     {
144         std::wstring wstFuncName = L"%"  + in[0]->getShortTypeStr() + L"_imag";
145         return Overload::call(wstFuncName, in, _iRetCount, out, new ast::ExecVisitor());
146     }
147
148     return types::Function::OK;
149 }
150 /*--------------------------------------------------------------------------*/