1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2014 - Scilab Enterprises - 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 #include "cacsd_gw.hxx"
17 #include "function.hxx"
18 #include "double.hxx"
19 #include "polynom.hxx"
20
21 extern "C"
22 {
23 #include "Scierror.h"
24 #include "localization.h"
25 #include "elem_common.h"
26
27 extern void C2F(dtild)(int*, double*, int*);
28 extern void C2F(expan)(double*, int*, double*, int*, double*, int*);
29 }
30
31 /*--------------------------------------------------------------------------*/
sci_ldiv(types::typed_list & in,int _iRetCount,types::typed_list & out)32 types::Function::ReturnValue sci_ldiv(types::typed_list &in, int _iRetCount, types::typed_list &out)
33 {
34 double** pdblCoef1 = NULL;
35 double** pdblCoef2 = NULL;
36 int* piRank1 = NULL;
37 int* piRank2 = NULL;
38 int iSize = 0;
39 int iK = 0;
40 int iRows = 0;
41 int iCols = 0;
42 int iOne = 1;
43
44 if (in.size() != 3)
45 {
46 Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), "ldiv", 3);
47 return types::Function::Error;
48 }
49
50 if (_iRetCount > 1)
51 {
52 Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "ldiv", 1);
53 return types::Function::Error;
54 }
55
56 /*** get inputs arguments ***/
57 // get first polynom
58 if (in[0]->isPoly())
59 {
60 types::Polynom* pPoly1 = in[0]->getAs<types::Polynom>();
61 if (pPoly1->isComplex())
62 {
63 Scierror(999, _("%s: Wrong type for input argument #%d: A real polynom expected.\n"), "ldiv", 1);
64 return types::Function::Error;
65 }
66
67 iSize = pPoly1->getSize();
68 iRows = pPoly1->getRows();
69 iCols = pPoly1->getCols();
70
71 piRank1 = new int[iSize];
72 pPoly1->getRank(piRank1);
73
74 pdblCoef1 = new double*[iSize];
75 for (int i = 0; i < iSize; i++)
76 {
77 pdblCoef1[i] = pPoly1->get(i)->get();
78 }
79 }
80 else if (in[0]->isDouble())
81 {
82 types::Double* pDbl1 = in[0]->getAs<types::Double>();
83 if (pDbl1->isComplex())
84 {
85 Scierror(999, _("%s: Wrong type for input argument #%d: A real matrix expected.\n"), "ldiv", 1);
86 return types::Function::Error;
87 }
88
89 iSize = pDbl1->getSize();
90 iRows = pDbl1->getRows();
91 iCols = pDbl1->getCols();
92
93 piRank1 = new int[iSize];
94 memset(piRank1, 0x00, iSize * sizeof(int));
95
96 pdblCoef1 = new double*[iSize];
97 double* pdbl = pDbl1->get();
98 for (int i = 0; i < iSize; i++)
99 {
100 pdblCoef1[i] = pdbl + i;
101 }
102 }
103 else
104 {
105 Scierror(999, _("%s: Wrong type for input argument #%d: A matrix or polynom expected.\n"), "ldiv", 1);
106 return types::Function::Error;
107 }
108
109 // get second polynom
110 if (in[1]->isPoly())
111 {
112 types::Polynom* pPoly2 = in[1]->getAs<types::Polynom>();
113 if (pPoly2->isComplex())
114 {
115 Scierror(999, _("%s: Wrong type for input argument #%d: A real polynom expected.\n"), "ldiv", 2);
116 delete[] pdblCoef1;
117 delete[] piRank1;
118 return types::Function::Error;
119 }
120
121 if (pPoly2->getRows() != iRows || pPoly2->getCols() != iCols)
122 {
123 Scierror(999, _("%s: Wrong size for input argument #%d: A same size as input argument %d expected.\n"), "ldiv", 2, 1);
124 delete[] pdblCoef1;
125 delete[] piRank1;
126 return types::Function::Error;
127 }
128
129 piRank2 = new int[iSize];
130 pPoly2->getRank(piRank2);
131
132 pdblCoef2 = new double*[iSize];
133 for (int i = 0; i < iSize; i++)
134 {
135 pdblCoef2[i] = pPoly2->get(i)->get();
136 }
137 }
138 else if (in[1]->isDouble())
139 {
140 types::Double* pDbl2 = in[1]->getAs<types::Double>();
141 if (pDbl2->isComplex())
142 {
143 Scierror(999, _("%s: Wrong type for input argument #%d: A real matrix expected.\n"), "ldiv", 2);
144 delete[] pdblCoef1;
145 delete[] piRank1;
146 return types::Function::Error;
147 }
148
149 if (pDbl2->getRows() != iRows || pDbl2->getCols() != iCols)
150 {
151 Scierror(999, _("%s: Wrong size for input argument #%d: A same size as input argument %d expected.\n"), "ldiv", 2, 1);
152 delete[] pdblCoef1;
153 delete[] piRank1;
154 return types::Function::Error;
155 }
156
157 piRank2 = new int[iSize];
158 memset(piRank2, 0x00, iSize * sizeof(int));
159
160 pdblCoef2 = new double*[iSize];
161 double* pdbl = pDbl2->get();
162 for (int i = 0; i < iSize; i++)
163 {
164 pdblCoef2[i] = pdbl + i;
165 }
166 }
167 else
168 {
169 Scierror(999, _("%s: Wrong type for input argument #%d: A matrix or polynom expected.\n"), "ldiv", 2);
170 delete[] pdblCoef1;
171 delete[] piRank1;
172 return types::Function::Error;
173 }
174
175 // get k
176 if (in[2]->isDouble() == false)
177 {
178 Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), "ldiv", 3);
179 delete[] pdblCoef1;
180 delete[] pdblCoef2;
181 delete[] piRank1;
182 delete[] piRank2;
183 return types::Function::Error;
184 }
185
186 types::Double* pDbl = in[2]->getAs<types::Double>();
187
188 if (pDbl->isComplex())
189 {
190 Scierror(999, _("%s: Wrong type for input argument #%d: A real scalar expected.\n"), "ldiv", 3);
191 delete[] pdblCoef1;
192 delete[] pdblCoef2;
193 delete[] piRank1;
194 delete[] piRank2;
195 return types::Function::Error;
196 }
197
198 if (pDbl->isScalar() == false)
199 {
200 Scierror(999, _("%s: Wrong size for input argument #%d: A real scalar expected.\n"), "ldiv", 3);
201 delete[] pdblCoef1;
202 delete[] pdblCoef2;
203 delete[] piRank1;
204 delete[] piRank2;
205 return types::Function::Error;
206 }
207
208 iK = (int)pDbl->get(0);
209
210 /*** perform operations ***/
211 types::Double* pDblOut = new types::Double(iRows * iK, iCols);
212 double* pdblout = pDblOut->get();
213
214 for (int i = 0; i < iSize; i++)
215 {
216 int iSize1 = piRank1[i] + 1;
217 int iSize2 = piRank2[i] + 1;
218 double* temp1 = new double[iSize1];
219 double* temp2 = new double[iSize2];
220 C2F(dcopy)(&iSize1, pdblCoef1[i], &iOne, temp1, &iOne);
221 C2F(dcopy)(&iSize2, pdblCoef2[i], &iOne, temp2, &iOne);
222 C2F(dtild)(&iSize1, temp1, &iOne);
223 C2F(dtild)(&iSize2, temp2, &iOne);
224 C2F(expan)(temp2, &iSize2, temp1, &iSize1, pdblout, &iK);
225 delete[] temp1;
226 delete[] temp2;
227 }
228
229 delete[] pdblCoef1;
230 delete[] pdblCoef2;
231 delete[] piRank1;
232 delete[] piRank2;
233
234 /*** retrun output arguments ***/
235 out.push_back(pDblOut);
236 return types::Function::OK;
237 }
238 /*--------------------------------------------------------------------------*/
239