Replace Min, Max and Abs by std::min, std::max and std::abs
[scilab.git] / scilab / modules / interpolation / sci_gateway / cpp / sci_interp3d.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 #include "interpolation_gw.hxx"
14 #include "function.hxx"
15 #include "double.hxx"
16 #include "string.hxx"
17 #include "tlist.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 }
26 /*--------------------------------------------------------------------------*/
27
28 types::Function::ReturnValue sci_interp3d(types::typed_list &in, int _iRetCount, types::typed_list &out)
29 {
30     // input
31     types::Double* pDblXYZ[3]       = {NULL, NULL, NULL};
32     types::TList* pTList            = NULL;
33     types::Double* pDblX            = NULL;
34     types::Double* pDblY            = NULL;
35     types::Double* pDblZ            = NULL;
36     types::Double* pDblOrder        = NULL;
37     types::Double* pDblCoef         = NULL;
38     types::Double* pDblXyzminmax    = NULL;
39
40     // output
41     types::Double* pDblFp   = NULL;
42     types::Double* pDblFpdx = NULL;
43     types::Double* pDblFpdy = NULL;
44     types::Double* pDblFpdz = NULL;
45
46     int iType = 0;
47     int order[3];
48     int sizeOfXp;
49
50     // *** check the minimal number of input args. ***
51     if ((in.size() < 4) || (5 < in.size()))
52     {
53         Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), "interp3d", 4);
54         return types::Function::Error;
55     }
56
57     // *** check number of output args according the methode. ***
58     if (_iRetCount > 4)
59     {
60         Scierror(78, _("%s: Wrong number of output argument(s): %d to %d expected.\n"), "interp3d", 1, 4);
61         return types::Function::Error;
62     }
63
64     // *** check type of input args and get it. ***
65     // xp yp zp
66     for (int i = 0; i < 3; i++)
67     {
68         if (in[i]->isDouble() == false)
69         {
70             Scierror(999, _("%s: Wrong type for input argument #%d : A matrix expected.\n"), "interp3d", i + 1);
71             return types::Function::Error;
72         }
73
74         pDblXYZ[i] = in[i]->getAs<types::Double>();
75
76         if (pDblXYZ[0]->getRows() != pDblXYZ[i]->getRows() || pDblXYZ[0]->getCols() != pDblXYZ[i]->getCols())
77         {
78             Scierror(999, _("%s: Wrong size for input argument #%d : Same size as argument %d expected.\n"), "interp3d", i + 1, 1);
79             return types::Function::Error;
80         }
81
82         if (pDblXYZ[i]->isComplex())
83         {
84             Scierror(999, _("%s: Wrong type for argument #%d: Real matrix expected.\n"), "interp3d", i + 1);
85             return types::Function::Error;
86         }
87     }
88
89     sizeOfXp = pDblXYZ[0]->getSize();
90
91     if (in[3]->isTList() == false)
92     {
93         Scierror(999, _("%s: Wrong type for input argument #%d : A tlist of type %s expected.\n"), "interp3d", 4, "tensbs3d");
94     }
95
96     pTList = in[3]->getAs<types::TList>();
97
98     if (pTList->getTypeStr() != L"tensbs3d")
99     {
100         Scierror(999, _("%s: Wrong type for input argument #%d: A %s tlist expected.\n"), "interp3d", 4, "tensbs3d");
101         return types::Function::Error;
102     }
103
104     pDblX = pTList->getField(L"tx")->getAs<types::Double>();
105     pDblY = pTList->getField(L"ty")->getAs<types::Double>();
106     pDblZ = pTList->getField(L"tz")->getAs<types::Double>();
107     pDblOrder = pTList->getField(L"order")->getAs<types::Double>();
108     pDblCoef = pTList->getField(L"bcoef")->getAs<types::Double>();
109     pDblXyzminmax = pTList->getField(L"xyzminmax")->getAs<types::Double>();
110
111     if (in.size() == 5)
112     {
113         if (in[4]->isString() == false)
114         {
115             Scierror(999, _("%s: Wrong type for input argument #%d : A string expected.\n"), "interp3d", 5);
116             return types::Function::Error;
117         }
118
119         wchar_t* wcsType = in[4]->getAs<types::String>()->get(0);
120
121         if (wcscmp(wcsType, L"C0") == 0)
122         {
123             iType = 8;
124         }
125         else if (wcscmp(wcsType, L"by_zero") == 0)
126         {
127             iType = 7;
128         }
129         else if (wcscmp(wcsType, L"periodic") == 0)
130         {
131             iType = 3;
132         }
133         else if (wcscmp(wcsType, L"by_nan") == 0)
134         {
135             iType = 10;
136         }
137         else // undefined
138         {
139             char* pstType = wide_string_to_UTF8(wcsType);
140             Scierror(999, _("%s: Wrong values for input argument #%d : '%s' is a unknow '%s' type.\n"), "interp3d", 5, pstType, "outmode");
141             FREE(pstType);
142             return types::Function::Error;
143         }
144     }
145     else
146     {
147         //"C0"
148         iType = 8;
149     }
150
151     // *** Perform operation. ***
152     pDblFp = new types::Double(pDblXYZ[0]->getRows(), pDblXYZ[0]->getCols());
153
154     order[0] = static_cast<int>(pDblOrder->get(0));
155     order[1] = static_cast<int>(pDblOrder->get(1));
156     order[2] = static_cast<int>(pDblOrder->get(2));
157
158     int sizeOfX = pDblX->getRows() - order[0];
159     int sizeOfY = pDblY->getRows() - order[1];
160     int sizeOfZ = pDblZ->getRows() - order[2];
161
162     double* minmax = pDblXyzminmax->get();
163
164     int workSize = order[1] * order[2] + 3 * std::max(order[0], std::max(order[1], order[2])) + order[2];
165     double* work = new double[workSize];
166
167     if (_iRetCount == 1)
168     {
169         C2F(driverdb3val)(pDblXYZ[0]->get(), pDblXYZ[1]->get(), pDblXYZ[2]->get(), pDblFp->get(), &sizeOfXp,
170                           pDblX->get(), pDblY->get(), pDblZ->get(), &sizeOfX, &sizeOfY, &sizeOfZ,
171                           &order[0], &order[1], &order[2], pDblCoef->get(), work,
172                           &minmax[0], &minmax[1], &minmax[2], &minmax[3], &minmax[4], &minmax[5], &iType);
173     }
174     else // _iRetCount == 4
175     {
176         pDblFpdx = new types::Double(pDblXYZ[0]->getRows(), pDblXYZ[0]->getCols());
177         pDblFpdy = new types::Double(pDblXYZ[0]->getRows(), pDblXYZ[0]->getCols());
178         pDblFpdz = new types::Double(pDblXYZ[0]->getRows(), pDblXYZ[0]->getCols());
179
180         C2F(driverdb3valwithgrad)(pDblXYZ[0]->get(), pDblXYZ[1]->get(), pDblXYZ[2]->get(),
181                                   pDblFp->get(), pDblFpdx->get(), pDblFpdy->get(), pDblFpdz->get(),
182                                   &sizeOfXp, pDblX->get(), pDblY->get(), pDblZ->get(),
183                                   &sizeOfX, &sizeOfY, &sizeOfZ, &order[0], &order[1], &order[2], pDblCoef->get(), work,
184                                   &minmax[0], &minmax[1], &minmax[2], &minmax[3], &minmax[4], &minmax[5], &iType);
185     }
186
187     delete[] work;
188
189     // *** Return result in Scilab. ***
190     switch (_iRetCount)
191     {
192         case 4 :
193             out.insert(out.begin(), pDblFpdz);
194         case 3 :
195             out.insert(out.begin(), pDblFpdy);
196         case 2 :
197             out.insert(out.begin(), pDblFpdx);
198         default :
199             break;
200     }
201
202     out.insert(out.begin(), pDblFp);
203
204     return types::Function::OK;
205 }
206