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