1a754cebe738d38eb3346251d204c64d10ac5197
[scilab.git] / scilab / modules / interpolation / sci_gateway / cpp / sci_splin2d.cpp
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2011 - 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
14 #include "interpolation_gw.hxx"
15 #include "function.hxx"
16 #include "double.hxx"
17 #include "string.hxx"
18
19 extern "C"
20 {
21 #include "sci_malloc.h"
22 #include "localization.h"
23 #include "Scierror.h"
24 #include "interpolation_functions.h"
25 #include "interpolation.h"
26 }
27 /*--------------------------------------------------------------------------*/
28
29 types::Function::ReturnValue sci_splin2d(types::typed_list &in, int _iRetCount, types::typed_list &out)
30 {
31     // input
32     types::Double* pDblX    = NULL;
33     types::Double* pDblY    = NULL;
34     types::Double* pDblZ    = NULL;
35
36     // output
37     types::Double* pDblOut  = NULL;
38
39     int iType   = 0; // default value = not_a_knot
40     int sizeOfX = 0;
41     int sizeOfY = 0;
42
43     // *** check the minimal number of input args. ***
44     if (in.size() < 3 || in.size() > 4)
45     {
46         Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "splin2d", 3, 4);
47         return types::Function::Error;
48     }
49
50     // *** check number of output args according the methode. ***
51     if (_iRetCount > 1)
52     {
53         Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "splin2d", 1);
54         return types::Function::Error;
55     }
56
57     // *** check type of input args and get it. ***
58     // x
59     if (in[0]->isDouble() == false)
60     {
61         Scierror(999, _("%s: Wrong type for input argument #%d : A vector expected.\n"), "splin2d", 1);
62         return types::Function::Error;
63     }
64
65     pDblX = in[0]->getAs<types::Double>();
66     sizeOfX = pDblX->getSize();
67
68     if (pDblX->isComplex())
69     {
70         Scierror(999, _("%s: Wrong type for argument #%d: Real matrix expected.\n"), "splin2d", 1);
71         return types::Function::Error;
72     }
73
74     if (pDblX->getRows() != 1 || pDblX->getSize() < 2)
75     {
76         Scierror(999, _("%s: Wrong size for input argument #%d : A row vector of size at least 2 expected.\n"), "splin2d", 1);
77         return types::Function::Error;
78     }
79
80     if (good_order(pDblX->get(), pDblX->getSize()) == false) /* verify strict increasing abscissae */
81     {
82         Scierror(999, _("%s: Wrong value for input argument #%d: Not (strictly) increasing or +-inf detected.\n"), "splin2d", 1);
83         return types::Function::Error;
84     }
85
86     // y
87     if (in[1]->isDouble() == false)
88     {
89         Scierror(999, _("%s: Wrong type for input argument #%d : A vector expected.\n"), "splin2d", 2);
90         return types::Function::Error;
91     }
92
93     pDblY = in[1]->getAs<types::Double>();
94     sizeOfY = pDblY->getSize();
95
96     if (pDblY->isComplex())
97     {
98         Scierror(999, _("%s: Wrong type for argument #%d: Real matrix expected.\n"), "splin2d", 2);
99         return types::Function::Error;
100     }
101
102     if (pDblY->getRows() != 1 || pDblY->getSize() < 2)
103     {
104         Scierror(999, _("%s: Wrong size for input argument #%d : A row vector of size at least 2 expected.\n"), "splin2d", 2);
105         return types::Function::Error;
106     }
107
108     if (good_order(pDblY->get(), pDblY->getSize()) == false) /* verify strict increasing abscissae */
109     {
110         Scierror(999, _("%s: Wrong value for input argument #%d: Not (strictly) increasing or +-inf detected.\n"), "splin2d", 2);
111         return types::Function::Error;
112     }
113
114     // z
115     if (in[2]->isDouble() == false)
116     {
117         Scierror(999, _("%s: Wrong type for input argument #%d : A matrix expected.\n"), "splin2d", 3);
118         return types::Function::Error;
119     }
120
121     pDblZ = in[2]->getAs<types::Double>();
122
123     if (pDblZ->isComplex())
124     {
125         Scierror(999, _("%s: Wrong type for argument #%d: Real matrix expected.\n"), "splin2d", 3);
126         return types::Function::Error;
127     }
128
129     if (pDblZ->getRows() != pDblX->getCols() || pDblZ->getCols() != pDblY->getCols())
130     {
131         Scierror(999, _("%s: Wrong size for input argument #%d : A matrix of size %d * %d expected.\n"), "splin2d", 3, pDblX->getCols(), pDblY->getCols());
132         return types::Function::Error;
133     }
134
135     // type
136     if (in.size() == 4)
137     {
138         if (in[3]->isString() == false)
139         {
140             Scierror(999, _("%s: Wrong type for input argument #%d : A string expected.\n"), "splin2d", 4);
141             return types::Function::Error;
142         }
143
144         wchar_t* wcsType = in[3]->getAs<types::String>()->get(0);
145
146         if (wcscmp(wcsType, L"not_a_knot") == 0)
147         {
148             iType = 0;
149         }
150         else if (wcscmp(wcsType, L"natural") == 0)
151         {
152             iType = 1;
153         }
154         else if (wcscmp(wcsType, L"clamped") == 0)
155         {
156             iType = 2;
157         }
158         else if (wcscmp(wcsType, L"periodic") == 0)
159         {
160             iType = 3;
161         }
162         else if (wcscmp(wcsType, L"fast") == 0)
163         {
164             iType = 4;
165         }
166         else if (wcscmp(wcsType, L"fast_periodic") == 0)
167         {
168             iType = 5;
169         }
170         else if (wcscmp(wcsType, L"monotone") == 0)
171         {
172             iType = 6;
173         }
174         else // undefined
175         {
176             char* pstType = wide_string_to_UTF8(wcsType);
177             Scierror(999, _("%s: Wrong values for input argument #%d : '%s' is a unknow '%s' type.\n"), "splin2d", 4, pstType, "spline");
178             FREE(pstType);
179             return types::Function::Error;
180         }
181     }
182
183     // *** Perform operation. ***
184     int outSize = 16 * (pDblX->getSize() - 1) * (pDblY->getSize() - 1);
185     pDblOut = new types::Double(outSize, 1);
186
187     double* p = new double[pDblZ->getSize()];
188     double* q = new double[pDblZ->getSize()];
189     double* r = new double[pDblZ->getSize()];
190
191     if (iType > 3)
192     {
193         C2F(bicubicsubspline)(pDblX->get(), pDblY->get(), pDblZ->get(), &sizeOfX, &sizeOfY, pDblOut->get(), p, q, r, &iType);
194     }
195     else
196     {
197         int nxy = Max(pDblX->getSize(), pDblY->getSize());
198         double* lA_d    = new double[nxy    ];
199         double* lA_sd   = new double[nxy - 1];
200         double* ld      = new double[sizeOfY];
201         double* lqdu    = new double[nxy    ];
202         double* lutemp  = new double[sizeOfY];
203         double* lll = NULL;
204
205         if (iType == 3)
206         {
207             lll = new double[nxy - 1];
208         }
209
210         C2F(bicubicspline)(pDblX->get(), pDblY->get(), pDblZ->get(), &sizeOfX, &sizeOfY, pDblOut->get(),
211                            p, q, r, lA_d, lA_sd, ld, lll, lqdu, lutemp, &iType);
212
213         delete[] lA_d;
214         delete[] lA_sd;
215         delete[] ld;
216         delete[] lqdu;
217         delete[] lutemp;
218
219         if (iType == 3)
220         {
221             delete[] lll;
222         }
223     }
224
225     delete[] p;
226     delete[] q;
227     delete[] r;
228
229     // *** Return result in Scilab. ***
230     out.push_back(pDblOut);
231
232     return types::Function::OK;
233 }
234