elementary_functions module.
[scilab.git] / scilab / modules / elementary_functions / src / cpp / diag.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - 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
14 #include "diag.hxx"
15
16 types::Double* diag(types::Double* pIn,  int iStartPos)
17 {
18     types::Double* pDblOut = NULL;
19
20     int iRows = pIn->getRows();
21     int iCols = pIn->getCols();
22
23     int iSize       = 0;
24     int iStartRow   = 0;
25     int iStartCol   = 0;
26     int iPos        = 0;
27
28     if (iRows != 1 && iCols != 1) // pIn is a matrix
29     {
30         if (iStartPos < 0)
31         {
32             iSize = Max(0, Min(iRows + iStartPos, iCols));
33             iStartRow = -iStartPos;
34         }
35         else
36         {
37             iSize = Max(0, Min(iRows, iCols - iStartPos));
38             iStartCol = iStartPos;
39         }
40
41         if (iSize)
42         {
43             pDblOut = new types::Double(iSize, 1, pIn->isComplex());
44         }
45         else
46         {
47             return types::Double::Empty();
48         }
49
50         for (int i = 0; i < iSize; i++)
51         {
52             iPos = (i + iStartCol) * iRows + (i + iStartRow);
53             pDblOut->set(i, pIn->get(iPos));
54
55             if (pIn->isComplex())
56             {
57                 pDblOut->setImg(i, pIn->getImg(iPos));
58             }
59         }
60     }
61     else // pIn is a vector
62     {
63         int iSizeOfVector = Max(iRows, iCols);
64         if (iStartPos < 0)
65         {
66             iSize = iSizeOfVector - iStartPos;
67             iStartRow = -iStartPos;
68         }
69         else
70         {
71             iSize = iSizeOfVector + iStartPos;
72             iStartCol = iStartPos;
73         }
74
75         pDblOut = new types::Double(iSize, iSize, pIn->isComplex());
76         memset(pDblOut->get(), 0x00, iSize * iSize * sizeof(double));
77
78         if (pIn->isComplex())
79         {
80             memset(pDblOut->getImg(), 0x00, iSize * iSize * sizeof(double));
81         }
82
83         for (int i = 0; i < iSizeOfVector; i++)
84         {
85             iPos = (i + iStartCol) * iSize + (i + iStartRow);
86             pDblOut->set(iPos, pIn->get(i));
87
88             if (pIn->isComplex())
89             {
90                 pDblOut->setImg(iPos, pIn->getImg(i));
91             }
92         }
93     }
94
95     return pDblOut;
96 }
97
98 types::Polynom* diag(types::Polynom* pIn,  int iStartPos)
99 {
100     types::Polynom* pPolyOut    = NULL;
101     types::SinglePoly* pSP      = NULL;
102
103     int iRows = pIn->getRows();
104     int iCols = pIn->getCols();
105
106     int iSize       = 0;
107     int iStartRow   = 0;
108     int iStartCol   = 0;
109     int iPos        = 0;
110     int iRank       = 0;
111
112     double* pdRData = 0;
113     double* pdIData = 0;
114
115     if (iRows != 1 && iCols != 1) // pIn is a matrix
116     {
117         if (iStartPos < 0)
118         {
119             iSize = Max(0, Min(iRows + iStartPos, iCols));
120             iStartRow = -iStartPos;
121         }
122         else
123         {
124             iSize = Max(0, Min(iRows, iCols - iStartPos));
125             iStartCol = iStartPos;
126         }
127
128         if (iSize)
129         {
130             pPolyOut = new types::Polynom(pIn->getVariableName(), iSize, 1);
131             pPolyOut->setComplex(pIn->isComplex());
132         }
133         else
134         {
135             return NULL;
136         }
137
138         for (int i = 0; i < iSize; i++)
139         {
140             iRank = pIn->get(i)->getRank();
141
142             if (pIn->isComplex())
143             {
144                 pSP = new types::SinglePoly(&pdRData, &pdIData, iRank);
145             }
146             else
147             {
148                 pSP = new types::SinglePoly(&pdRData, iRank);
149             }
150
151             iPos = (i + iStartCol) * iRows + (i + iStartRow);
152
153             for (int j = 0; j < iRank; j++)
154             {
155                 pdRData[j] = pIn->get(iPos)->getCoefReal()[j];
156                 if (pIn->isComplex())
157                 {
158                     pdIData[j] = pIn->get(iPos)->getCoefImg()[j];
159                 }
160             }
161
162             pPolyOut->set(i, pSP);
163             delete pSP;
164             pSP = NULL;
165         }
166     }
167     else // pIn is a vector
168     {
169         int iSizeOfVector = Max(iRows, iCols);
170         if (iStartPos < 0)
171         {
172             iSize = iSizeOfVector - iStartPos;
173             iStartRow = -iStartPos;
174         }
175         else
176         {
177             iSize = iSizeOfVector + iStartPos;
178             iStartCol = iStartPos;
179         }
180
181         pPolyOut = new types::Polynom(pIn->getVariableName(), iSize, iSize);
182         pPolyOut->setComplex(pIn->isComplex());
183
184         for (int i = 0; i < iSizeOfVector; i++)
185         {
186             iRank = pIn->get(i)->getRank();
187
188             if (pIn->isComplex())
189             {
190                 pSP = new types::SinglePoly(&pdRData, &pdIData, iRank);
191             }
192             else
193             {
194                 pSP = new types::SinglePoly(&pdRData, iRank);
195             }
196
197             iPos = (i + iStartCol) * iSize + (i + iStartRow);
198
199             for (int j = 0; j < iRank; j++)
200             {
201                 pdRData[j] = pIn->get(i)->getCoefReal()[j];
202                 if (pIn->isComplex())
203                 {
204                     pdIData[j] = pIn->get(i)->getCoefImg()[j];
205                 }
206             }
207
208             pPolyOut->set(iPos, pSP);
209             delete pSP;
210             pSP = NULL;
211         }
212     }
213
214     return pPolyOut;
215 }
216
217
218 types::String* diag(types::String* pIn,  int iStartPos)
219 {
220     types::String* pStrOut = NULL;
221
222     int iRows = pIn->getRows();
223     int iCols = pIn->getCols();
224
225     int iSize       = 0;
226     int iStartRow   = 0;
227     int iStartCol   = 0;
228     int iPos        = 0;
229
230     if (iRows != 1 && iCols != 1) // pIn is a matrix
231     {
232         if (iStartPos < 0)
233         {
234             iSize = Max(0, Min(iRows + iStartPos, iCols));
235             iStartRow = -iStartPos;
236         }
237         else
238         {
239             iSize = Max(0, Min(iRows, iCols - iStartPos));
240             iStartCol = iStartPos;
241         }
242
243         if (iSize)
244         {
245             pStrOut = new types::String(iSize, 1);
246         }
247         else
248         {
249             return NULL;
250         }
251
252         for (int i = 0; i < iSize; i++)
253         {
254             iPos = (i + iStartCol) * iRows + (i + iStartRow);
255             pStrOut->set(i, pIn->get(iPos));
256         }
257     }
258     else // pIn is a vector
259     {
260         int iSizeOfVector = Max(iRows, iCols);
261         if (iStartPos < 0)
262         {
263             iSize = iSizeOfVector - iStartPos;
264             iStartRow = -iStartPos;
265         }
266         else
267         {
268             iSize = iSizeOfVector + iStartPos;
269             iStartCol = iStartPos;
270         }
271
272         pStrOut = new types::String(iSize, iSize);
273
274         for (int i = 0; i < iSize * iSize; i++)
275         {
276             pStrOut->set(i, L"");
277         }
278
279         for (int i = 0; i < iSizeOfVector; i++)
280         {
281             iPos = (i + iStartCol) * iSize + (i + iStartRow);
282             pStrOut->set(iPos, pIn->get(i));
283         }
284     }
285
286     return pStrOut;
287 }
288