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