* Bug 16323 fixed: now conj(sparse(x)) is real when x is real
[scilab.git] / scilab / modules / elementary_functions / sci_gateway / cpp / sci_conj.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - DIGITEO - Cedric DELAMARRE
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15 /*--------------------------------------------------------------------------*/
16 #include "elem_func_gw.hxx"
17 #include "function.hxx"
18 #include "double.hxx"
19 #include "overload.hxx"
20 #include "polynom.hxx"
21 #include "sparse.hxx"
22
23 extern "C"
24 {
25 #include "Scierror.h"
26 #include "localization.h"
27 #include "basic_functions.h"
28 }
29
30 /*--------------------------------------------------------------------------*/
31 types::Function::ReturnValue sci_conj(types::typed_list &in, int _iRetCount, types::typed_list &out)
32 {
33     types::Double* pDblOut      = NULL;
34     types::Polynom* pPolyOut    = NULL;
35
36     double dLeatOne = -1;
37     int iOne        = 1;
38     int iSize       = 0;
39
40     if (in.size() != 1)
41     {
42         Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), "conj", 1);
43         return types::Function::Error;
44     }
45
46     if (_iRetCount > 1)
47     {
48         Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "conj", 1);
49         return types::Function::Error;
50     }
51
52     if (in[0]->isDouble())
53     {
54         pDblOut = in[0]->clone()->getAs<types::Double>();
55     }
56     else if (in[0]->isPoly())
57     {
58         pPolyOut = in[0]->clone()->getAs<types::Polynom>();
59         pDblOut = pPolyOut->getCoef();
60     }
61     else if (in[0]->isSparse())
62     {
63         types::Sparse *pSparseOut = in[0]->clone()->getAs<types::Sparse>();
64         if (pSparseOut->isComplex() == true)
65         {
66             std::complex<double>* data = pSparseOut->getImg();
67             std::transform(data, data + pSparseOut->nonZeros(), data, [](const std::complex<double>& c) -> std::complex<double> { return std::conj(c); });
68         }
69         out.push_back(pSparseOut);
70         return types::Function::OK;
71     }
72     else
73     {
74         std::wstring wstFuncName = L"%" + in[0]->getShortTypeStr() + L"_conj";
75         return Overload::call(wstFuncName, in, _iRetCount, out);
76     }
77
78     iSize = pDblOut->getSize();
79     if (pDblOut->isComplex())
80     {
81         C2F(dscal)(&iSize, &dLeatOne, pDblOut->getImg(), &iOne);
82     }
83
84     if (in[0]->isDouble())
85     {
86         out.push_back(pDblOut);
87     }
88     else if (in[0]->isPoly())
89     {
90         pPolyOut->setCoef(pDblOut);
91         out.push_back(pPolyOut);
92         pDblOut->killMe();
93     }
94
95     return types::Function::OK;
96 }
97 /*--------------------------------------------------------------------------*/