2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2014 - Scilab Enterprises - Cedric DELAMARRE
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
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.
15 /*--------------------------------------------------------------------------*/
16 #include "cacsd_gw.hxx"
17 #include "function.hxx"
19 #include "polynom.hxx"
24 #include "localization.h"
25 #include "elem_common.h"
27 extern void C2F(residu)(double*, int*, double*, int*, double*, int*, double*, double*, int*);
28 extern void C2F(wesidu)(double*, double*, int*, double*, double*, int*,
29 double*, double*, int*, double*, double*, double*, int*);
32 /*--------------------------------------------------------------------------*/
33 types::Function::ReturnValue sci_residu(types::typed_list &in, int _iRetCount, types::typed_list &out)
35 int iRows[3] = {0, 0, 0};
36 int iCols[3] = {0, 0, 0};
37 int iComplex[3] = {0, 0, 0};
38 int* piRank[3] = {NULL, NULL, NULL};
39 double** pdblInR[3] = {NULL, NULL, NULL};
40 double** pdblInI[3] = {NULL, NULL, NULL};
41 bool isDeletable[3] = {false, false, false};
42 types::Double* pDblIn[3] = {NULL, NULL, NULL};
43 types::Polynom* pPoly[3] = {NULL, NULL, NULL};
44 types::Double* pDblOut = NULL;
46 double dblEps = nc_eps_machine();
54 Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), "residu", 3);
55 return types::Function::Error;
60 Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "residu", 1);
61 return types::Function::Error;
66 /*** get inputs arguments ***/
67 for (int i = 0; i < 3; i++)
69 if (in[i]->isDouble())
71 pDblIn[i] = in[i]->clone()->getAs<types::Double>();
72 iRows[i] = pDblIn[i]->getRows();
73 iCols[i] = pDblIn[i]->getCols();
75 iSize = pDblIn[i]->getSize();
76 piRank[i] = new int[iSize];
77 memset(piRank[i], 0x00, iSize * sizeof(int));
79 pdblInR[i] = new double*[iSize];
80 double* pdbl = pDblIn[i]->get();
81 for (int j = 0; j < iSize; j++)
83 pdblInR[i][j] = pdbl + j;
86 if (pDblIn[i]->isComplex())
88 pdblInI[i] = new double*[iSize];
89 double* pdbl = pDblIn[i]->get();
90 for (int j = 0; j < iSize; j++)
92 pdblInI[i][j] = pdbl + j;
96 else if (in[i]->isPoly())
98 pPoly[i] = in[i]->clone()->getAs<types::Polynom>();
99 iRows[i] = pPoly[i]->getRows();
100 iCols[i] = pPoly[i]->getCols();
102 iSize = pPoly[i]->getSize();
103 piRank[i] = new int[iSize];
104 pPoly[i]->getRank(piRank[i]);
106 pdblInR[i] = new double*[iSize];
107 if (pPoly[i]->isComplex())
109 pdblInI[i] = new double*[iSize];
110 for (int j = 0; j < iSize; j++)
112 pdblInR[i][j] = pPoly[i]->get(j)->get();
113 pdblInI[i][j] = pPoly[i]->get(j)->getImg();
118 for (int j = 0; j < iSize; j++)
120 pdblInR[i][j] = pPoly[i]->get(j)->get();
126 Scierror(999, _("%s: Wrong type for input argument #%d: A Matrix or polynom expected.\n"), "residu", i + 1);
131 if (iRows[0] != iRows[1] || iCols[0] != iCols[1] || iRows[0] != iRows[2] || iCols[0] != iCols[2])
133 Scierror(999, _("%s: Wrong size for argument: Incompatible dimensions.\n"), "residu");
137 /*** perform operations ***/
138 if (pdblInI[0] == NULL && pdblInI[1] == NULL && pdblInI[2] == NULL)
141 pDblOut = new types::Double(iRows[0], iCols[0]);
142 double* pdblOut = pDblOut->get();
143 for (int i = 0; i < iRows[0] * iCols[0]; i++)
148 int iSize1 = piRank[0][i] + 1;
149 int iSize2 = piRank[1][i] + 1;
150 int iSize3 = piRank[2][i] + 1;
151 C2F(residu)(pdblInR[0][i], &iSize1, pdblInR[1][i], &iSize2,
152 pdblInR[2][i], &iSize3, &v, &dblEps, &iErr);
155 Scierror(78, _("%s: An error occured in '%s'.\n"), "residu", "residu");
165 pDblOut = new types::Double(iRows[0], iCols[0], true);
166 double* pdblOutR = pDblOut->get();
167 double* pdblOutI = pDblOut->getImg();
169 for (int i = 0; i < 3; i++)
171 if (pdblInI[i] == NULL)
173 pdblInI[i] = new double*[iSize];
174 for (int j = 0; j < iSize; j++)
176 int iLen = piRank[i][j] + 1;
177 pdblInI[i][j] = new double[iLen];
178 memset(pdblInI[i][j], 0x00, iLen * sizeof(double));
181 isDeletable[i] = true;
185 for (int i = 0; i < iRows[0] * iCols[0]; i++)
191 C2F(wesidu)(pdblInR[0][i], pdblInI[0][i], (piRank[0]) + i,
192 pdblInR[1][i], pdblInI[1][i], (piRank[1]) + i,
193 pdblInR[2][i], pdblInI[2][i], (piRank[2]) + i,
194 &real, &imag, &dblEps, &iErr);
198 Scierror(78, _("%s: An error occured in '%s'.\n"), "residu", "wesidu");
213 for (int i = 0; i < 3; i++)
237 for (int j = 0; j < iSize; j++)
239 delete[] pdblInI[i][j];
249 /*** retrun output arguments ***/
252 return types::Function::Error;
255 out.push_back(pDblOut);
256 return types::Function::OK;
258 /*--------------------------------------------------------------------------*/