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
sci_interp2d(types::typed_list & in,int _iRetCount,types::typed_list & out)30 types::Function::ReturnValue sci_interp2d(types::typed_list &in, int _iRetCount, types::typed_list &out)
31 {
32 // input
33 types::Double* pDblXp = NULL;
34 types::Double* pDblYp = NULL;
35 types::Double* pDblX = NULL;
36 types::Double* pDblY = NULL;
37 types::Double* pDblC = NULL;
38
39 // output
40 types::Double* pDblZp = NULL;
41 types::Double* pDblDzpdx = NULL;
42 types::Double* pDblDzpdy = NULL;
43 types::Double* pDblD2zdx2p = NULL;
44 types::Double* pDblD2zdxyp = NULL;
45 types::Double* pDblD2zdy2p = NULL;
46
47 int iType = 8; // default C0
48 int sizeOfX = 0;
49 int sizeOfXp = 0;
50 int sizeOfY = 0;
51 int sizeOfC = 0;
52
53 // *** check the minimal number of input args. ***
54 if (in.size() < 5 || in.size() > 6)
55 {
56 Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "interp2d", 5, 6);
57 return types::Function::Error;
58 }
59
60 // *** check number of output args according the methode. ***
61 if (_iRetCount > 6)
62 {
63 Scierror(78, _("%s: Wrong number of output argument(s): %d to %d expected.\n"), "interp2d", 1, 6);
64 return types::Function::Error;
65 }
66
67 // *** check type of input args and get it. ***
68 // xp
69 if (in[0]->isDouble() == false)
70 {
71 Scierror(999, _("%s: Wrong type for input argument #%d : A matrix expected.\n"), "interp2d", 1);
72 return types::Function::Error;
73 }
74
75 pDblXp = in[0]->getAs<types::Double>();
76 sizeOfXp = pDblXp->getSize();
77
78 if (pDblXp->isComplex())
79 {
80 Scierror(999, _("%s: Wrong type for argument #%d: Real matrix expected.\n"), "interp2d", 1);
81 return types::Function::Error;
82 }
83
84 // yp
85 if (in[1]->isDouble() == false)
86 {
87 Scierror(999, _("%s: Wrong type for input argument #%d : A matrix expected.\n"), "interp2d", 2);
88 return types::Function::Error;
89 }
90 pDblYp = in[1]->getAs<types::Double>();
91
92 if (pDblXp->getRows() != pDblYp->getRows() || pDblXp->getCols() != pDblYp->getCols())
93 {
94 Scierror(999, _("%s: Wrong size for input arguments #%d and #%d: Same size expected.\n"), "interp2d", 1, 2);
95 return types::Function::Error;
96 }
97
98 if (pDblYp->isComplex())
99 {
100 Scierror(999, _("%s: Wrong type for argument #%d: Real matrix expected.\n"), "interp2d", 2);
101 return types::Function::Error;
102 }
103
104 // x
105 if (in[2]->isDouble() == false)
106 {
107 Scierror(999, _("%s: Wrong type for input argument #%d : A matrix expected.\n"), "interp2d", 3);
108 return types::Function::Error;
109 }
110
111 pDblX = in[2]->getAs<types::Double>();
112 sizeOfX = pDblX->getSize();
113
114 if (pDblX->getRows() != 1 || pDblX->getSize() < 2)
115 {
116 Scierror(999, _("%s: Wrong size for input arguments #%d: A row vector of size at least 2 expected.\n"), "interp2d", 3);
117 return types::Function::Error;
118 }
119
120 if (pDblX->isComplex())
121 {
122 Scierror(999, _("%s: Wrong type for argument #%d: Real matrix expected.\n"), "interp2d", 3);
123 return types::Function::Error;
124 }
125
126 // y
127 if (in[3]->isDouble() == false)
128 {
129 Scierror(999, _("%s: Wrong type for input argument #%d : A matrix expected.\n"), "interp2d", 4);
130 return types::Function::Error;
131 }
132
133 pDblY = in[3]->getAs<types::Double>();
134 sizeOfY = pDblY->getSize();
135
136 if (pDblY->getRows() != 1 || pDblY->getSize() < 2)
137 {
138 Scierror(999, _("%s: Wrong size for input arguments #%d: A row vector of size at least 2 expected.\n"), "interp2d", 4);
139 return types::Function::Error;
140 }
141
142 // c
143 if (in[4]->isDouble() == false)
144 {
145 Scierror(999, _("%s: Wrong type for input argument #%d : A matrix expected.\n"), "interp2d", 5);
146 return types::Function::Error;
147 }
148
149 pDblC = in[4]->getAs<types::Double>();
150 sizeOfC = 16 * (sizeOfX - 1) * (sizeOfY - 1);
151 if (pDblC->getCols() != 1 || pDblC->getSize() != sizeOfC)
152 {
153 Scierror(999, _("%s: Wrong size for input arguments #%d: A column vector of size %d expected.\n"), "interp2d", 5, sizeOfC);
154 return types::Function::Error;
155 }
156
157 // out mode
158 if (in.size() == 6)
159 {
160 if (in[5]->isString() == false)
161 {
162 Scierror(999, _("%s: Wrong type for input argument #%d : string expected.\n"), "interp2d", 6);
163 return types::Function::Error;
164 }
165
166 wchar_t* wcsType = in[5]->getAs<types::String>()->get(0);
167
168 if (wcscmp(wcsType, L"C0") == 0)
169 {
170 iType = 8;
171 }
172 else if (wcscmp(wcsType, L"by_zero") == 0)
173 {
174 iType = 7;
175 }
176 else if (wcscmp(wcsType, L"natural") == 0)
177 {
178 iType = 1;
179 }
180 else if (wcscmp(wcsType, L"periodic") == 0)
181 {
182 iType = 3;
183 }
184 else if (wcscmp(wcsType, L"by_nan") == 0)
185 {
186 iType = 10;
187 }
188 else // undefined
189 {
190 Scierror(999, _("%s: Wrong values for input argument #%d : '%s' is an unknown '%s' type.\n"), "interp2d", 6, wcsType, "outmode");
191 return types::Function::Error;
192 }
193 }
194
195 // *** Perform operation. ***
196 pDblZp = new types::Double(pDblXp->getRows(), pDblXp->getCols());
197
198 if (_iRetCount <= 1)
199 {
200 C2F(bicubicinterp)(pDblX->get(), pDblY->get(), pDblC->get(), &sizeOfX, &sizeOfY, pDblXp->get(), pDblYp->get(), pDblZp->get(), &sizeOfXp, &iType);
201
202 }
203 else // if(_iRetCount > 2)
204 {
205 pDblDzpdx = new types::Double(pDblXp->getRows(), pDblXp->getCols());
206 pDblDzpdy = new types::Double(pDblXp->getRows(), pDblXp->getCols());
207
208 if (_iRetCount == 3)
209 {
210 C2F(bicubicinterpwithgrad)(pDblX->get(), pDblY->get(), pDblC->get(), &sizeOfX, &sizeOfY,
211 pDblXp->get(), pDblYp->get(), pDblZp->get(), pDblDzpdx->get(),
212 pDblDzpdy->get(), &sizeOfXp, &iType);
213 }
214 else // == 6
215 {
216 pDblD2zdx2p = new types::Double(pDblXp->getRows(), pDblXp->getCols());
217 pDblD2zdxyp = new types::Double(pDblXp->getRows(), pDblXp->getCols());
218 pDblD2zdy2p = new types::Double(pDblXp->getRows(), pDblXp->getCols());
219
220 C2F(bicubicinterpwithgradandhes)(pDblX->get(), pDblY->get(), pDblC->get(), &sizeOfX, &sizeOfY,
221 pDblXp->get(), pDblYp->get(), pDblZp->get(), pDblDzpdx->get(),
222 pDblDzpdy->get(), pDblD2zdx2p->get(), pDblD2zdxyp->get(),
223 pDblD2zdy2p->get(), &sizeOfXp, &iType);
224 }
225 }
226
227 // *** Return result in Scilab. ***
228 switch (_iRetCount)
229 {
230 case 6 :
231 out.insert(out.begin(), pDblD2zdy2p);
232 case 5 :
233 out.insert(out.begin(), pDblD2zdxyp);
234 case 4 :
235 out.insert(out.begin(), pDblD2zdx2p);
236 case 3 :
237 out.insert(out.begin(), pDblDzpdy);
238 case 2 :
239 out.insert(out.begin(), pDblDzpdx);
240 default :
241 break;
242 }
243
244 out.insert(out.begin(), pDblZp);
245
246 return types::Function::OK;
247 }
248
249