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