elementary_functions module.
[scilab.git] / scilab / modules / elementary_functions / sci_gateway / cpp / sci_log.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 #include "log.h"
26 }
27
28 /*--------------------------------------------------------------------------*/
29 types::Function::ReturnValue sci_log(types::typed_list &in, int _iRetCount, types::typed_list &out)
30 {
31     int iAlert = 1;
32
33     if (in.size() != 1)
34     {
35         ScierrorW(77, _W("%ls: Wrong number of input argument(s): %d to %d expected.\n"), L"log", 1);
36         return types::Function::Error;
37     }
38
39     if (_iRetCount > 1)
40     {
41         ScierrorW(78, _W("%ls: Wrong number of output argument(s): %d expected.\n"), L"log", 1);
42         return types::Function::Error;
43     }
44
45     if (in[0]->isDouble() == false)
46     {
47         std::wstring wstFuncName = L"%"  + in[0]->getShortTypeStr() + L"_log";
48         return Overload::call(wstFuncName, in, _iRetCount, out, new ExecVisitor());
49     }
50
51     types::Double* pDblIn = in[0]->getAs<types::Double>();
52     types::Double* pDblOut = new types::Double(pDblIn->getDims(), pDblIn->getDimsArray(), pDblIn->isComplex());
53
54     if (pDblIn->isComplex())
55     {
56         for (int i = 0; i < pDblIn->getSize(); i++)
57         {
58             //If the value is less than precision (eps).
59             if (iAlert && pDblIn->get(i) == 0 && pDblIn->getImg(i) == 0)
60             {
61                 // if ieee == 0 => error && return
62                 // else if ieee == 1 => warning
63                 iAlert = 0;
64             }
65
66             wlog(pDblIn->get(i), pDblIn->getImg(i), pDblOut->get() + i, pDblOut->getImg() + i);
67         }
68     }
69     else
70     {
71         bool bIsLessZero = false;
72         for (int i = 0; i < pDblIn->getSize(); i++)
73         {
74             if (iAlert && pDblIn->get(i) == 0)
75             {
76                 iAlert = 0;
77                 // if ieee == 0 => error && return
78                 // else if ieee == 1 => warning
79             }
80             else if (pDblIn->get(i) < 0)
81             {
82                 bIsLessZero = true;
83             }
84         }
85
86         if (bIsLessZero)
87         {
88             pDblOut->setComplex(true);
89             for (int i = 0; i < pDblIn->getSize(); i++)
90             {
91                 wlog(pDblIn->get(i), 0, pDblOut->get() + i, pDblOut->getImg() + i);
92             }
93         }
94         else
95         {
96             for (int i = 0; i < pDblIn->getSize(); i++)
97             {
98                 pDblOut->set(i, dlogs(pDblIn->get(i)));
99             }
100         }
101     }
102
103     out.push_back(pDblOut);
104     return types::Function::OK;
105 }
106 /*--------------------------------------------------------------------------*/