* Bug 16654 fixed: interp1 was leaking memory
[scilab.git] / scilab / modules / interpolation / sci_gateway / cpp / sci_interp.cpp
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2011 - 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
17 #include "interpolation_gw.hxx"
18 #include "function.hxx"
19 #include "double.hxx"
20 #include "string.hxx"
21
22 extern "C"
23 {
24 #include "localization.h"
25 #include "Scierror.h"
26 #include "interpolation_functions.h"
27 }
28 /*--------------------------------------------------------------------------*/
29
30 types::Function::ReturnValue sci_interp(types::typed_list &in, int _iRetCount, types::typed_list &out)
31 {
32     // input
33     types::Double* pDblXp       = NULL;
34     types::Double* pDblX        = NULL;
35     types::Double* pDblY        = NULL;
36     types::Double* pDblD        = NULL;
37
38     // output
39     types::Double* pDblYp  = NULL;
40     types::Double* pDblYp1 = NULL;
41     types::Double* pDblYp2 = NULL;
42     types::Double* pDblYp3 = NULL;
43
44     int iType       = 8; // default C0
45     int sizeOfXp    = 0;
46     int sizeOfX     = 0;
47
48     // *** check the minimal number of input args. ***
49     if (in.size() < 4 || in.size() > 5)
50     {
51         Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "interp", 4, 5);
52         return types::Function::Error;
53     }
54
55     // *** check number of output args according the methode. ***
56     if (_iRetCount > 4)
57     {
58         Scierror(78, _("%s: Wrong number of output argument(s): %d to %d expected.\n"), "interp", 1, 4);
59         return types::Function::Error;
60     }
61
62     // *** check type of input args and get it. ***
63     // xp
64     if (in[0]->isDouble() == false)
65     {
66         Scierror(999, _("%s: Wrong type for input argument #%d : A matrix expected.\n"), "interp", 1);
67         return types::Function::Error;
68     }
69
70     pDblXp = in[0]->getAs<types::Double>();
71     sizeOfXp = pDblXp->getSize();
72
73     if (pDblXp->isComplex())
74     {
75         Scierror(999, _("%s: Wrong type for argument #%d: Real matrix expected.\n"), "interp", 1);
76         return types::Function::Error;
77     }
78
79     // x
80     if (in[1]->isDouble() == false)
81     {
82         Scierror(999, _("%s: Wrong type for input argument #%d : A matrix expected.\n"), "interp", 2);
83         return types::Function::Error;
84     }
85
86     pDblX = in[1]->getAs<types::Double>();
87     if ((pDblX->getCols() != 1 && pDblX->getRows() != 1) || pDblX->getSize() < 2)
88     {
89         Scierror(999, _("%s: Wrong size for input arguments #%d: A vector of size at least 2 expected.\n"), "interp", 2);
90         return types::Function::Error;
91     }
92     sizeOfX = pDblX->getSize();
93
94     if (pDblX->isComplex())
95     {
96         Scierror(999, _("%s: Wrong type for argument #%d: Real matrix expected.\n"), "interp", 2);
97         return types::Function::Error;
98     }
99
100     // y
101     if (in[2]->isDouble() == false)
102     {
103         Scierror(999, _("%s: Wrong type for input argument #%d : A matrix expected.\n"), "interp", 3);
104         return types::Function::Error;
105     }
106     pDblY = in[2]->getAs<types::Double>();
107
108     if (pDblY->isComplex())
109     {
110         Scierror(999, _("%s: Wrong type for argument #%d: Real matrix expected.\n"), "interp", 3);
111         return types::Function::Error;
112     }
113
114     // d
115     if (in[3]->isDouble() == false)
116     {
117         Scierror(999, _("%s: Wrong type for input argument #%d : A matrix expected.\n"), "interp", 4);
118         return types::Function::Error;
119     }
120     pDblD = in[3]->getAs<types::Double>();
121
122     if (pDblD->isComplex())
123     {
124         Scierror(999, _("%s: Wrong type for argument #%d: Real matrix expected.\n"), "interp", 4);
125         return types::Function::Error;
126     }
127
128     if ( pDblX->getRows() != pDblY->getRows() ||
129             pDblX->getCols() != pDblY->getCols() ||
130             pDblX->getRows() != pDblD->getRows() ||
131             pDblX->getCols() != pDblD->getCols())
132     {
133         Scierror(999, _("%s: Wrong size for input arguments #%d to #%d: Same sizes expected.\n"), "interp", 2, 4);
134         return types::Function::Error;
135     }
136
137     // out mode
138     if (in.size() == 5)
139     {
140         if (in[4]->isString() == false)
141         {
142             Scierror(999, _("%s: Wrong type for input argument #%d : string expected.\n"), "interp", 5);
143             return types::Function::Error;
144         }
145
146         wchar_t* wcsType = in[4]->getAs<types::String>()->get(0);
147
148         if (wcscmp(wcsType, L"C0") == 0)
149         {
150             iType = 8;
151         }
152         else if (wcscmp(wcsType, L"by_zero") == 0)
153         {
154             iType = 7;
155         }
156         else if (wcscmp(wcsType, L"natural") == 0)
157         {
158             iType = 1;
159         }
160         else if (wcscmp(wcsType, L"periodic") == 0)
161         {
162             iType = 3;
163         }
164         else if (wcscmp(wcsType, L"by_nan") == 0)
165         {
166             iType = 10;
167         }
168         else if (wcscmp(wcsType, L"linear") == 0)
169         {
170             iType = 9;
171         }
172         else // undefined
173         {
174             Scierror(999, _("%s: Wrong values for input argument #%d : '%s' is an unknown '%s' type.\n"), "interp", 5, wcsType, "outmode");
175             return types::Function::Error;
176         }
177     }
178
179     // *** Perform operation. ***
180     pDblYp  = new types::Double(pDblXp->getRows(), pDblXp->getCols());
181     pDblYp1 = new types::Double(pDblXp->getRows(), pDblXp->getCols());
182     pDblYp2 = new types::Double(pDblXp->getRows(), pDblXp->getCols());
183     pDblYp3 = new types::Double(pDblXp->getRows(), pDblXp->getCols());
184
185     C2F(evalpwhermite)(pDblXp->get(), pDblYp->get(), pDblYp1->get(), pDblYp2->get(), pDblYp3->get(), &sizeOfXp, pDblX->get(), pDblY->get(), pDblD->get(), &sizeOfX, &iType);
186
187     // *** Return result in Scilab. ***
188     out.push_back(pDblYp);
189     if (_iRetCount > 1)
190     {
191         out.push_back(pDblYp1);
192     }
193     else
194     {
195         pDblYp1->killMe();
196     }
197
198     if (_iRetCount > 2)
199     {
200         out.push_back(pDblYp2);
201     }
202     else
203     {
204         pDblYp2->killMe();
205     }
206
207     if (_iRetCount > 3)
208     {
209         out.push_back(pDblYp3);
210     }
211     else
212     {
213         pDblYp3->killMe();
214     }
215
216     return types::Function::OK;
217 }
218