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