elementary_functions module.
[scilab.git] / scilab / modules / elementary_functions / sci_gateway / cpp / sci_dsearch.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 "string.hxx"
17
18
19 extern "C"
20 {
21 #include "Scierror.h"
22 #include "localization.h"
23 #include "basic_functions.h"
24 }
25
26 /*--------------------------------------------------------------------------*/
27 types::Function::ReturnValue sci_dsearch(types::typed_list &in, int _iRetCount, types::typed_list &out)
28 {
29     // input
30     types::Double* pDblIn       = NULL;
31     types::Double* pDblSearch   = NULL;
32
33     // output
34     types::Double* pDblInd      = NULL;
35     types::Double* pDblOcc      = NULL;
36
37     double* pdOcc               = NULL;
38     double dInfo                = 0;
39
40     int iTypeSearch = 1; // 1 = 'c' || 0 = 'd'
41
42     if (in.size() < 2 || in.size() > 3)
43     {
44         ScierrorW(77, _W("%ls: Wrong number of input argument(s): %d to %d expected.\n"), L"dsearch", 2, 3);
45         return types::Function::Error;
46     }
47
48     if (_iRetCount > 3)
49     {
50         ScierrorW(78, _W("%ls: Wrong number of output argument(s): At most %d expected.\n"), L"dsearch", 3);
51         return types::Function::Error;
52     }
53
54     /***** get data *****/
55     // input data
56     if (in[0]->isDouble() == false)
57     {
58         ScierrorW(999, _W("%ls: Wrong type for input argument #%d : A matrix expected.\n"), L"dsearch", 1);
59         return types::Function::Error;
60     }
61
62     pDblIn = in[0]->getAs<types::Double>();
63
64     if (pDblIn->isComplex())
65     {
66         ScierrorW(999, _W("%ls: Wrong type for input argument #%d : A real matrix expected.\n"), L"dsearch", 1);
67         return types::Function::Error;
68     }
69
70     // what to look for in input data
71     if (in[1]->isDouble() == false)
72     {
73         ScierrorW(999, _W("%ls: Wrong type for input argument #%d : A real vector expected.\n"), L"dsearch", 2);
74         return types::Function::Error;
75     }
76
77     pDblSearch = in[1]->getAs<types::Double>();
78
79     if ((pDblSearch->getCols() != 1 && pDblSearch->getRows() != 1) || pDblSearch->isComplex())
80     {
81         ScierrorW(999, _W("%ls: Wrong type for input argument #%d : A real vector expected.\n"), L"dsearch", 2);
82         return types::Function::Error;
83     }
84
85     for (int i = 1; i < pDblSearch->getSize(); i++)
86     {
87         if (pDblSearch->get(i - 1) >= pDblSearch->get(i))
88         {
89             ScierrorW(999, _W("%ls: Wrong value for input argument #%d : A strictly increasing order expected.\n"), L"dsearch", 2);
90             return types::Function::Error;
91         }
92     }
93
94     // search type
95     if (in.size() == 3)
96     {
97         if (in[2]->isString() == false)
98         {
99             ScierrorW(999, _W("%ls: Wrong type for input argument #%d : A string expected.\n"), L"dsearch", 3);
100             return types::Function::Error;
101         }
102
103         wchar_t* wcsString = in[2]->getAs<types::String>()->get(0);
104
105         if (wcscmp(wcsString, L"c") == 0)
106         {
107             iTypeSearch = 1;
108         }
109         else if (wcscmp(wcsString, L"d") == 0)
110         {
111             iTypeSearch = 0;
112         }
113         else
114         {
115             ScierrorW(999, _W("%ls: Wrong value for input argument #%d : It must be 'c' or 'd'.\n"), L"dsearch", 3);
116             return types::Function::Error;
117         }
118     }
119
120     /***** perform operation *****/
121     int iRowsOcc = pDblSearch->getRows();
122     int iColsOcc = pDblSearch->getCols();
123
124     // If iTypeSearch= 1 ("c") , a (n-1)-by-1 or 1-by-(n-1) of doubles. If iTypeSearch=0 ("d") (0), a n-by-1 or 1-by-n of doubles.
125     if (iTypeSearch)
126     {
127         if (pDblSearch->getCols() == 1)
128         {
129             iRowsOcc--;
130         }
131         else
132         {
133             iColsOcc--;
134         }
135     }
136
137     if ((iRowsOcc * iColsOcc) < 1)
138     {
139         ScierrorW(999, _W("%ls: Wrong size for input argument #%d : A vector of length > %d expected.\n"), L"dsearch", 2, iTypeSearch);
140         return types::Function::Error;
141     }
142
143     pDblInd = new types::Double(pDblIn->getDims(), pDblIn->getDimsArray());
144
145     if (_iRetCount > 1)
146     {
147         pDblOcc = new types::Double(iRowsOcc, iColsOcc);
148         pdOcc = pDblOcc->get();
149     }
150
151     if (iTypeSearch) // c
152     {
153         vDsearchC(pDblIn->get(), pDblIn->getSize(), pDblSearch->get(), pDblSearch->getSize() - 1, pDblInd->get(), pdOcc, &dInfo);
154     }
155     else
156     {
157         vDsearchD(pDblIn->get(), pDblIn->getSize(), pDblSearch->get(), pDblSearch->getSize(), pDblInd->get(), pdOcc, &dInfo);
158     }
159
160     /***** set result *****/
161     out.push_back(pDblInd);
162
163     if (_iRetCount > 1)
164     {
165         out.push_back(pDblOcc);
166     }
167
168     if (_iRetCount > 2)
169     {
170         out.push_back(new types::Double(dInfo));
171     }
172
173     return types::Function::OK;
174 }
175 /*--------------------------------------------------------------------------*/