0e8ce21acf909c5343aa84a413d90f1bb92b909c
[scilab.git] / scilab / modules / ast / src / cpp / types / double.cpp
1 /*
2 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *  Copyright (C) 2008-2008 - DIGITEO - Antoine ELIAS
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 <sstream>
14 #include <math.h>
15 #include "double.hxx"
16 #include "doubleexp.hxx"
17 #include "tostring_common.hxx"
18 #include "scilabexception.hxx"
19 #include "configvariable.hxx"
20
21 extern "C"
22 {
23 #include <stdio.h>
24 #include "elem_common.h"
25 #include "localization.h"
26 #include "charEncoding.h"
27 #include "os_string.h"
28 }
29
30 using namespace std;
31
32 namespace types
33 {
34 Double* Double::Empty()
35 {
36     return new Double(0, 0);
37 }
38
39 Double* Double::Identity(int _iRows, int _iCols)
40 {
41     double* pdbl = NULL;
42     Double* pI = new Double(_iRows, _iCols, &pdbl);
43     pI->setZeros();
44     for (int i = 0 ; i < std::min(_iRows, _iCols) ; i++)
45     {
46         pI->set(i, i, 1);
47     }
48
49     if (_iRows == -1 && _iCols == -1)
50     {
51         pdbl[0] = 1;
52     }
53     return pI;
54 }
55
56 Double* Double::Identity(int _iDims, int* _piDims)
57 {
58     Double* pI = new Double(_iDims, _piDims);
59     pI->setZeros();
60     int iMinDim = _piDims[0];
61     for (int i = 1 ; i < _iDims ; i++)
62     {
63         if (_piDims[i] < iMinDim)
64         {
65             iMinDim = _piDims[i];
66         }
67     }
68
69     for (int i = 0 ; i < iMinDim ; i++)
70     {
71         int* piIndex = new int[_iDims];
72         for (int j = 0 ; j < _iDims ; j++)
73         {
74             piIndex[j] = i;
75         }
76
77         int index = getIndexWithDims(piIndex, _piDims, _iDims);
78         pI->set(index, 1);
79     }
80     return pI;
81 }
82
83 bool Double::isEmpty()
84 {
85     if (getDims() == 2 && getRows() == 0 && getCols() == 0)
86     {
87         return true;
88     }
89     return false;
90 }
91
92 Double::~Double()
93 {
94     if (isDeletable() == true)
95     {
96         deleteAll();
97     }
98 #ifndef NDEBUG
99     Inspector::removeItem(this);
100 #endif
101 }
102
103 Double::Double(int _iRows, int _iCols, bool _bComplex, bool _bZComplex)
104 {
105     int piDims[2]   = {_iRows, _iCols};
106     double *pReal   = NULL;
107     double *pImg    = NULL;
108     setViewAsZComplex(_bZComplex);
109     if (_bComplex == false || _bZComplex)
110     {
111         create(piDims, 2, &pReal, NULL);
112     }
113     else
114     {
115         create(piDims, 2, &pReal, &pImg);
116     }
117
118     setViewAsInteger(false);
119 #ifndef NDEBUG
120     Inspector::addItem(this);
121 #endif
122 }
123
124 Double::Double(double _dblReal)
125 {
126     m_piDims[0] = 1;
127     m_piDims[1] = 1;
128     m_iDims = 2;
129     m_iRows = 1;
130     m_iCols = 1;
131     m_iSize = 1;
132     m_iSizeMax = m_iSize;
133     m_pRealData = new double[1];
134     setViewAsInteger(false);
135     setViewAsZComplex(false);
136     m_pRealData[0] = _dblReal;
137
138     //      int piDims[2] = {1, 1};
139     //double *pdblVal;
140     //create(piDims, 2, &pdblVal, NULL);
141     //pdblVal[0] = _dblReal;
142 #ifndef NDEBUG
143     Inspector::addItem(this);
144 #endif
145 }
146
147 Double::Double(double _dblReal, double _dblImg)
148 {
149     int piDims[2] = {1, 1};
150     double *pdblR;
151     double *pdblI;
152     setViewAsInteger(false);
153     setViewAsZComplex(false);
154     create(piDims, 2, &pdblR, &pdblI);
155
156     pdblR[0] = _dblReal;
157     pdblI[0] = _dblImg;
158 #ifndef NDEBUG
159     Inspector::addItem(this);
160 #endif
161 }
162
163 Double::Double(int _iRows, int _iCols, double **_pdblReal)
164 {
165     int piDims[2] = {_iRows, _iCols};
166     setViewAsInteger(false);
167     setViewAsZComplex(false);
168     create(piDims, 2, _pdblReal, NULL);
169
170 #ifndef NDEBUG
171     Inspector::addItem(this);
172 #endif
173 }
174
175 Double::Double(int _iRows, int _iCols, double **_pdblReal, double **_pdblImg)
176 {
177     int piDims[2] = {_iRows, _iCols};
178     setViewAsInteger(false);
179     setViewAsZComplex(false);
180     create(piDims, 2, _pdblReal, _pdblImg);
181
182 #ifndef NDEBUG
183     Inspector::addItem(this);
184 #endif
185 }
186
187 Double::Double(int _iDims, int* _piDims, bool _bComplex, bool _bZComplex)
188 {
189     double *pReal   = NULL;
190     double *pImg    = NULL;
191     setViewAsZComplex(_bZComplex);
192     setViewAsInteger(false);
193
194     if (_bComplex == false || _bZComplex)
195     {
196         create(_piDims, _iDims, &pReal, NULL);
197     }
198     else
199     {
200         create(_piDims, _iDims, &pReal, &pImg);
201     }
202
203 #ifndef NDEBUG
204     Inspector::addItem(this);
205 #endif
206 }
207
208 double*    Double::getReal() const
209 {
210     return get();
211 }
212
213 double Double::getReal(int _iRows, int _iCols)
214 {
215     return get(_iRows, _iCols);
216 }
217
218 bool Double::setInt(int* _piReal)
219 {
220     bool ret = true;
221     for (int i = 0 ; i < m_iSize ; i++)
222     {
223         ret = set(i, static_cast<double>(_piReal[i]));
224         if (ret == false)
225         {
226             return false;
227         }
228     }
229     return true;
230 }
231
232 void Double::whoAmI()
233 {
234     std::cout << "types::Double";
235 }
236
237 bool Double::setZeros()
238 {
239     if (m_pRealData != NULL)
240     {
241         memset(m_pRealData, 0x00, m_iSize * sizeof(double));
242     }
243     else
244     {
245         return false;
246     }
247
248     if (isComplex() == true)
249     {
250         if (m_pImgData != NULL)
251         {
252             memset(m_pImgData, 0x00, m_iSize * sizeof(double));
253         }
254         else
255         {
256             return false;
257         }
258     }
259     return true;
260 }
261
262 bool Double::setOnes()
263 {
264     if (m_pRealData != NULL)
265     {
266         std::fill(m_pRealData, m_pRealData + m_iSize, 1);
267     }
268     else
269     {
270         return false;
271     }
272
273     if (isComplex() == true)
274     {
275         if (m_pImgData != NULL)
276         {
277             std::fill(m_pImgData, m_pImgData + m_iSize, 1);
278         }
279         else
280         {
281             return false;
282         }
283     }
284     return true;
285 }
286
287 bool Double::subMatrixToString(wostringstream& ostr, int* _piDims, int /*_iDims*/)
288 {
289     int iCurrentLine = 0;
290     int iLineLen = ConfigVariable::getConsoleWidth();
291     int iMaxLines = ConfigVariable::getConsoleLines();
292
293     if (isIdentity())
294     {
295         ostr << L"eye *" << endl << endl;
296         if (isComplex() == false)
297         {
298             DoubleFormat df;
299             getDoubleFormat((m_pRealData[0]), &df);
300             addDoubleValue(&ostr, (m_pRealData[0]), &df);
301             ostr << endl;
302         }
303         else
304         {
305             //complex value
306             DoubleFormat dfR, dfI;
307             getDoubleFormat(ZeroIsZero(m_pRealData[0]), &dfR);
308             getDoubleFormat(ZeroIsZero(m_pImgData[0]), &dfI);
309             addDoubleComplexValue(&ostr, ZeroIsZero(m_pRealData[0]), ZeroIsZero(m_pImgData[0]), dfR.iWidth + dfI.iWidth, &dfR, &dfI);
310             ostr << endl;
311         }
312         ostr << endl;
313     }
314     else if (isEmpty())
315     {
316         ostr << L"    []";
317         ostr << endl;
318     }
319     else if (isScalar())
320     {
321         //scalar
322         _piDims[0] = 0;
323         _piDims[1] = 0;
324         int iPos = getIndex(_piDims);
325
326         if (isComplex() == false)
327         {
328             DoubleFormat df;
329             getDoubleFormat((m_pRealData[iPos]), &df);
330             ostr << SPACE_BETWEEN_TWO_VALUES;
331             addDoubleValue(&ostr, (m_pRealData[iPos]), &df);
332             ostr << endl;
333         }
334         else
335         {
336             //complex value
337             DoubleFormat dfR, dfI;
338             getDoubleFormat(ZeroIsZero(m_pRealData[iPos]), &dfR);
339             getDoubleFormat(ZeroIsZero(m_pImgData[iPos]), &dfI);
340             ostr << SPACE_BETWEEN_TWO_VALUES;
341             addDoubleComplexValue(&ostr, ZeroIsZero(m_pRealData[iPos]), ZeroIsZero(m_pImgData[iPos]), dfR.iWidth + dfI.iWidth, &dfR, &dfI);
342             ostr << endl;
343         }
344     }
345     else if (getCols() == 1)
346     {
347         //column vector
348
349         if (isComplex() == false)
350         {
351             for (int i = m_iRows1PrintState ; i < getRows() ; i++)
352             {
353                 iCurrentLine++;
354                 if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) || (iMaxLines != 0 && iCurrentLine >= iMaxLines))
355                 {
356                     m_iRows1PrintState = i;
357                     return false;
358                 }
359
360                 _piDims[1] = 0;
361                 _piDims[0] = i;
362                 int iPos = getIndex(_piDims);
363
364                 DoubleFormat df;
365                 getDoubleFormat(ZeroIsZero(m_pRealData[iPos]), &df);
366                 ostr << SPACE_BETWEEN_TWO_VALUES;
367                 addDoubleValue(&ostr, ZeroIsZero(m_pRealData[iPos]), &df);
368                 ostr << endl;
369             }
370         }
371         else
372         {
373             for (int i = m_iRows1PrintState ; i < getRows() ; i++)
374             {
375                 //complex value
376                 iCurrentLine++;
377                 if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) || (iMaxLines != 0 && iCurrentLine >= iMaxLines))
378                 {
379                     m_iRows1PrintState = i;
380                     return false;
381                 }
382
383                 _piDims[1] = 0;
384                 _piDims[0] = i;
385                 int iPos = getIndex(_piDims);
386
387                 DoubleFormat dfR, dfI;
388                 getDoubleFormat(ZeroIsZero(m_pRealData[iPos]), &dfR);
389                 getDoubleFormat(ZeroIsZero(m_pImgData[iPos]), &dfI);
390
391                 ostr << SPACE_BETWEEN_TWO_VALUES;
392                 addDoubleComplexValue(&ostr, ZeroIsZero(m_pRealData[iPos]), ZeroIsZero(m_pImgData[iPos]), dfR.iWidth + dfI.iWidth, &dfR, &dfI);
393                 ostr << endl;
394             }
395         }
396     }
397     else if (getRows() == 1)
398     {
399         //row vector
400         wostringstream ostemp;
401         int iLastVal = m_iCols1PrintState;
402
403         if (isComplex() == false)
404         {
405             int iLen = 0;
406             for (int i = m_iCols1PrintState ; i < getCols() ; i++)
407             {
408                 _piDims[0] = 0;
409                 _piDims[1] = i;
410                 int iPos = getIndex(_piDims);
411
412                 DoubleFormat df;
413                 getDoubleFormat(ZeroIsZero(m_pRealData[iPos]), &df);
414                 iLen = static_cast<int>(ostemp.str().size()) + SIZE_BETWEEN_TWO_VALUES + df.iSignLen + df.iWidth;
415                 if (iLen >= iLineLen - 1 && iLastVal != i)
416                 {
417                     //Max length, new line
418                     iCurrentLine += 4; //"column x to Y" + empty line + value + empty line
419                     if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) || (iMaxLines != 0 && iCurrentLine >= iMaxLines))
420                     {
421                         m_iCols1PrintState = iLastVal;
422                         ostr << endl << endl;
423                         return false;
424                     }
425
426                     addColumnString(ostr, iLastVal + 1, i);
427                     ostr << ostemp.str() << endl;
428                     ostemp.str(L"");
429                     iLastVal = i;
430                 }
431
432                 ostemp << SPACE_BETWEEN_TWO_VALUES;
433                 addDoubleValue(&ostemp, ZeroIsZero(m_pRealData[iPos]), &df);
434             }
435
436             if (iLastVal != 0)
437             {
438                 addColumnString(ostr, iLastVal + 1, getCols());
439             }
440             ostemp << endl;
441             ostr << ostemp.str();
442         }
443         else //complex case
444         {
445             int iTotalLen = 0;
446             int iLen = 0;
447
448             for (int i = m_iCols1PrintState ; i < getCols() ; i++)
449             {
450                 _piDims[0] = 0;
451                 _piDims[1] = i;
452                 int iPos = getIndex(_piDims);
453
454                 DoubleFormat dfR, dfI;
455                 getComplexFormat(ZeroIsZero(m_pRealData[iPos]), ZeroIsZero(m_pImgData[iPos]), &iTotalLen, &dfR, &dfI);
456                 iLen = static_cast<int>(ostemp.str().size()) + SIZE_BETWEEN_TWO_VALUES + iTotalLen;
457                 if (iLen >= iLineLen - 1 && iLastVal != i)
458                 {
459                     //Max length, new line
460                     iCurrentLine += 4; //"column x to Y" + empty line + value + empty line
461                     if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) || (iMaxLines != 0 && iCurrentLine >= iMaxLines))
462                     {
463                         m_iCols1PrintState = iLastVal;
464                         return false;
465                     }
466
467                     addColumnString(ostr, iLastVal + 1, i);
468                     ostr << ostemp.str() << endl;
469                     ostemp.str(L"");
470                     iLastVal = i;
471                 }
472
473                 ostemp << SPACE_BETWEEN_TWO_VALUES;
474                 addDoubleComplexValue(&ostemp, ZeroIsZero(m_pRealData[iPos]), ZeroIsZero(m_pImgData[iPos]), iTotalLen, &dfR, &dfI);
475             }
476
477             if (iLastVal != 0)
478             {
479                 addColumnString(ostr, iLastVal + 1, getCols());
480             }
481             ostemp << endl;
482             ostr << ostemp.str();
483         }
484     }
485     else // matrix
486     {
487         wostringstream ostemp;
488         int iLen = 0;
489         int iLastCol = m_iCols1PrintState;
490
491         //Array with the max printed size of each col
492         int *piSize = new int[getCols()];
493         memset(piSize, 0x00, getCols() * sizeof(int));
494
495         //Array with the max precision of each col (use to padd right with 0 3.6000)
496         int *piMaxPrec = new int[getCols()];
497         memset(piMaxPrec, 0x00, getCols() * sizeof(int));
498
499         if (isComplex() == false)
500         {
501             //compute the row size for padding for each printed bloc.
502             for (int iCols1 = m_iCols1PrintState ; iCols1 < getCols() ; iCols1++)
503             {
504                 for (int iRows1 = 0 ; iRows1 < getRows() ; iRows1++)
505                 {
506                     _piDims[0] = iRows1;
507                     _piDims[1] = iCols1;
508                     int iPos = getIndex(_piDims);
509
510                     DoubleFormat df;
511                     getDoubleFormat(ZeroIsZero(m_pRealData[iPos]), &df);
512                     piSize[iCols1] = std::max(piSize[iCols1], df.iWidth);
513                     piMaxPrec[iCols1] = std::max(piMaxPrec[iCols1], df.iPrec);
514                 }
515
516                 if (iLen + piSize[iCols1] > iLineLen && iCols1 != iLastCol)
517                 {
518                     //find the limit, print this part
519                     for (int iRows2 = m_iRows2PrintState ; iRows2 < getRows() ; iRows2++)
520                     {
521                         iCurrentLine++;
522                         if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) ||
523                                 ( (iMaxLines != 0 && iCurrentLine + 3 >= iMaxLines && iRows2 == m_iRows2PrintState) ||
524                                   (iMaxLines != 0 && iCurrentLine + 1 >= iMaxLines && iRows2 != m_iRows2PrintState)))
525                         {
526                             if (m_iRows2PrintState == 0 && iRows2 != 0)
527                             {
528                                 //add header
529                                 addColumnString(ostr, iLastCol + 1, iCols1);
530                             }
531                             ostr << ostemp.str();
532                             m_iRows2PrintState = iRows2;
533                             m_iCols1PrintState = iLastCol;
534                             delete[] piSize;
535                             delete[] piMaxPrec;
536                             return false;
537                         }
538
539                         for (int iCols2 = iLastCol ; iCols2 < iCols1 ; iCols2++)
540                         {
541                             _piDims[0] = iRows2;
542                             _piDims[1] = iCols2;
543                             int iPos = getIndex(_piDims);
544
545                             DoubleFormat df;
546                             getDoubleFormat(ZeroIsZero(m_pRealData[iPos]), &df);
547
548                             ostemp << SPACE_BETWEEN_TWO_VALUES;
549
550                             df.iPrec = piMaxPrec[iCols2];
551                             df.iWidth = piSize[iCols2];
552                             addDoubleValue(&ostemp, ZeroIsZero(m_pRealData[iPos]), &df);
553                         }
554                         ostemp << endl;
555                     }
556
557                     iLen = 0;
558
559                     iCurrentLine++;
560                     if (m_iRows2PrintState == 0)
561                     {
562                         iCurrentLine += 3;
563                         addColumnString(ostr, iLastCol + 1, iCols1);
564                     }
565                     ostr << ostemp.str();
566                     ostemp.str(L"");
567                     iLastCol = iCols1;
568                     m_iRows2PrintState = 0;
569                     m_iCols1PrintState = 0;
570                 }
571
572                 iLen += piSize[iCols1] + SIGN_LENGTH + SIZE_BETWEEN_TWO_VALUES;
573             }
574
575             for (int iRows2 = m_iRows2PrintState ; iRows2 < getRows() ; iRows2++)
576             {
577                 iCurrentLine++;
578                 if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) || (iMaxLines != 0 && iCurrentLine >= iMaxLines))
579                 {
580                     if (m_iRows2PrintState == 0 && iLastCol != 0)
581                     {
582                         //add header
583                         addColumnString(ostr, iLastCol + 1, getCols());
584                     }
585
586                     ostr << ostemp.str();
587                     m_iRows2PrintState = iRows2;
588                     m_iCols1PrintState = iLastCol;
589                     delete[] piSize;
590                     delete[] piMaxPrec;
591                     return false;
592                 }
593
594                 for (int iCols2 = iLastCol ; iCols2 < getCols() ; iCols2++)
595                 {
596                     _piDims[0] = iRows2;
597                     _piDims[1] = iCols2;
598                     int iPos = getIndex(_piDims);
599
600                     DoubleFormat df;
601                     getDoubleFormat(ZeroIsZero(m_pRealData[iPos]), &df);
602
603                     ostemp << SPACE_BETWEEN_TWO_VALUES;
604                     df.iPrec = piMaxPrec[iCols2];
605                     df.iWidth = piSize[iCols2];
606                     addDoubleValue(&ostemp, ZeroIsZero(m_pRealData[iPos]), &df);
607                 }
608                 ostemp << endl;
609             }
610
611             if (m_iRows2PrintState == 0 && iLastCol != 0)
612             {
613                 addColumnString(ostr, iLastCol + 1, getCols());
614             }
615             ostr << ostemp.str();
616         }
617         else //Complex case
618         {
619             //compute the row size for padding for each printed bloc.
620             for (int iCols1 = m_iCols1PrintState ; iCols1 < getCols() ; iCols1++)
621             {
622                 for (int iRows1 = 0 ; iRows1 < getRows() ; iRows1++)
623                 {
624                     int iTotalWidth = 0;
625                     _piDims[0] = iRows1;
626                     _piDims[1] = iCols1;
627                     int iPos = getIndex(_piDims);
628
629                     DoubleFormat dfR, dfI;
630                     getComplexFormat(ZeroIsZero(m_pRealData[iPos]), ZeroIsZero(m_pImgData[iPos]), &iTotalWidth, &dfR, &dfI);
631
632                     iTotalWidth += (dfR.iWidth == 0 ? 0 : SIGN_LENGTH) + (dfI.iWidth == 0 ? 0 : SIGN_LENGTH + 1);
633                     if (iTotalWidth > piSize[iCols1])
634                     {
635                         piSize[iCols1] = iTotalWidth;
636                     }
637
638                     piMaxPrec[iCols1] = std::max(piMaxPrec[iCols1], dfR.iPrec);
639                 }
640
641                 if (iLen + piSize[iCols1] > iLineLen && iCols1 != iLastCol)
642                 {
643                     //find the limit, print this part
644                     for (int iRows2 = m_iRows2PrintState ; iRows2 < getRows() ; iRows2++)
645                     {
646                         iCurrentLine++;
647                         if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) ||
648                                 ( (iMaxLines != 0 && iCurrentLine + 3 >= iMaxLines && iRows2 == m_iRows2PrintState) ||
649                                   (iMaxLines != 0 && iCurrentLine + 1 >= iMaxLines && iRows2 != m_iRows2PrintState)))
650                         {
651                             if (m_iRows2PrintState == 0 && iRows2 != 0)
652                             {
653                                 //add header
654                                 addColumnString(ostr, iLastCol + 1, iCols1);
655                             }
656                             ostr << ostemp.str();
657                             m_iRows2PrintState = iRows2;
658                             m_iCols1PrintState = iLastCol;
659                             delete[] piSize;
660                             delete[] piMaxPrec;
661                             return false;
662                         }
663
664                         for (int iCols2 = iLastCol ; iCols2 < iCols1 ; iCols2++)
665                         {
666                             int iTotalWidth = 0;
667                             _piDims[0] = iRows2;
668                             _piDims[1] = iCols2;
669                             int iPos = getIndex(_piDims);
670
671                             DoubleFormat dfR, dfI;
672                             getComplexFormat(ZeroIsZero(m_pRealData[iPos]), ZeroIsZero(m_pImgData[iPos]), &iTotalWidth, &dfR, &dfI);
673
674                             ostemp << SPACE_BETWEEN_TWO_VALUES;
675                             dfR.iPrec = piMaxPrec[iCols2];
676                             dfI.iPrec = piMaxPrec[iCols2];
677                             addDoubleComplexValue(&ostemp, ZeroIsZero(m_pRealData[iPos]), ZeroIsZero(m_pImgData[iPos]), piSize[iCols2], &dfR, &dfI);
678                         }
679                         ostemp << endl;
680                     }
681
682                     iLen = 0;
683
684                     iCurrentLine++;
685                     if (m_iRows2PrintState == 0)
686                     {
687                         iCurrentLine += 3;
688                         addColumnString(ostr, iLastCol + 1, iCols1);
689                     }
690                     ostr << ostemp.str();
691                     ostemp.str(L"");
692                     iLastCol = iCols1;
693                     m_iRows2PrintState = 0;
694                     m_iCols1PrintState = 0;
695                 }
696
697                 iLen += piSize[iCols1] + SIZE_BETWEEN_TWO_VALUES;
698             }
699
700             for (int iRows2 = m_iRows2PrintState ; iRows2 < getRows() ; iRows2++)
701             {
702                 iCurrentLine++;
703                 if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) || (iMaxLines != 0 && iCurrentLine >= iMaxLines))
704                 {
705                     if (m_iRows2PrintState == 0 && iLastCol != 0)
706                     {
707                         //add header
708                         addColumnString(ostr, iLastCol + 1, getCols());
709                     }
710
711                     ostr << ostemp.str();
712                     m_iRows2PrintState = iRows2;
713                     m_iCols1PrintState = iLastCol;
714                     delete[] piSize;
715                     delete[] piMaxPrec;
716                     return false;
717                 }
718
719                 for (int iCols2 = iLastCol ; iCols2 < getCols() ; iCols2++)
720                 {
721                     int iTotalWidth = 0;
722                     _piDims[0] = iRows2;
723                     _piDims[1] = iCols2;
724                     int iPos = getIndex(_piDims);
725
726                     DoubleFormat dfR, dfI;
727                     getComplexFormat(ZeroIsZero(m_pRealData[iPos]), ZeroIsZero(m_pImgData[iPos]), &iTotalWidth, &dfR, &dfI);
728
729                     ostemp << SPACE_BETWEEN_TWO_VALUES;
730                     dfR.iPrec = piMaxPrec[iCols2];
731                     dfI.iPrec = piMaxPrec[iCols2];
732                     addDoubleComplexValue(&ostemp, ZeroIsZero(m_pRealData[iPos]), ZeroIsZero(m_pImgData[iPos]), piSize[iCols2], &dfR, &dfI);
733                 }
734                 ostemp << endl;
735             }
736
737             if (m_iRows2PrintState == 0 && iLastCol != 0)
738             {
739                 addColumnString(ostr, iLastCol + 1, getCols());
740             }
741             ostr << ostemp.str();
742         }
743
744         delete[] piSize;
745         delete[] piMaxPrec;
746     }
747
748     return true;
749 }
750
751 InternalType* Double::clone()
752 {
753     int iOne = 1;
754     Double *pReturn = new Double(m_iDims, m_piDims, isComplex());
755     //memcpy(pReturn->getReal(), m_pRealData, m_iSize * sizeof(double));
756     dcopy_(&m_iSize, m_pRealData, &iOne, pReturn->getReal(), &iOne);
757
758     if (isComplex())
759     {
760         pReturn->setComplex(true);
761         //memcpy(pReturn->getImg(), m_pImgData, m_iSize * sizeof(double));
762         dcopy_(&m_iSize, m_pImgData, &iOne, pReturn->getImg(), &iOne);
763     }
764     return pReturn;
765 }
766
767 bool Double::fillFromCol(int _iCols, Double *_poSource)
768 {
769     //blas
770     int iDestOffset     = _iCols * m_iRows;
771     int iSize           = _poSource->getSize();
772     double* pdblDest    = m_pRealData + iDestOffset;
773     int iOne            = 1;
774     dcopy_(&iSize, _poSource->getReal(), &iOne, pdblDest, &iOne);
775
776     if (isComplex())
777     {
778         pdblDest    = m_pImgData + iDestOffset;
779         dcopy_(&iSize, _poSource->getImg(), &iOne, pdblDest, &iOne);
780     }
781     return true;
782 }
783
784 bool Double::fillFromRow(int _iRows, Double *_poSource)
785 {
786     int iCols = _poSource->getCols();
787
788     if (isComplex())
789     {
790     }
791     else
792     {
793         for (int i = 0 ; i < iCols ; i++)
794         {
795             int iDestOffset     = i * m_iRows + _iRows;
796             int iOrigOffset     = i * _poSource->getRows();
797             int iSize           = _poSource->getRows();
798             double* pdblDest    = m_pRealData + iDestOffset;
799             double* pdblSource  = _poSource->getReal() + iOrigOffset;
800             int iOne            = 1;
801
802             dcopy_(&iSize, pdblSource, &iOne, pdblDest, &iOne);
803         }
804     }
805     return true;
806 }
807
808 bool Double::operator==(const InternalType& it)
809 {
810     if (const_cast<InternalType &>(it).isDouble() == false)
811     {
812         return false;
813     }
814
815     Double* pdbl = const_cast<InternalType &>(it).getAs<Double>();
816
817     if (pdbl->getDims() != getDims())
818     {
819         return false;
820     }
821
822     for (int i = 0 ; i < getDims() ; i++)
823     {
824         if (pdbl->getDimsArray()[i] != getDimsArray()[i])
825         {
826             return false;
827         }
828     }
829
830     double *pdblReal = pdbl->getReal();
831     for (int i = 0 ; i < getSize() ; i++)
832     {
833         if (m_pRealData[i] != pdblReal[i])
834         {
835             return false;
836         }
837     }
838
839     //both complex
840     if (isComplex() && pdbl->isComplex())
841     {
842         double *pdblImg = pdbl->getImg();
843         for (int i = 0 ; i < m_iSize ; i++)
844         {
845             if (m_pImgData[i] != pdblImg[i])
846             {
847                 return false;
848             }
849         }
850     }
851     //pdbl complex check all img values == 0
852     else if (pdbl->isComplex())
853     {
854         double *pdblImg = pdbl->getImg();
855         for (int i = 0 ; i < m_iSize ; i++)
856         {
857             if (pdblImg[i])
858             {
859                 return false;
860             }
861         }
862     }
863     //complex check all img values == 0
864     else if (isComplex())
865     {
866         for (int i = 0 ; i < m_iSize ; i++)
867         {
868             if (m_pImgData[i])
869             {
870                 return false;
871             }
872         }
873     }
874
875     return true;
876 }
877
878 bool Double::operator!=(const InternalType& it)
879 {
880     return !(*this == it);
881 }
882
883 double Double::getNullValue()
884 {
885     return 0;
886 }
887
888 Double* Double::createEmpty(int _iDims, int* _piDims, bool _bComplex)
889 {
890     return new Double(_iDims, _piDims, _bComplex);
891 }
892
893 double Double::copyValue(double _dblData)
894 {
895     return _dblData;
896 }
897
898 void Double::deleteAll()
899 {
900     delete[] m_pRealData;
901     m_pRealData = NULL;
902     deleteImg();
903 }
904
905 void Double::deleteImg()
906 {
907     if (isComplex() && m_pImgData)
908     {
909         delete[] m_pImgData;
910         m_pImgData = NULL;
911     }
912 }
913
914 double* Double::allocData(int _iSize)
915 {
916     double* pDbl = NULL;
917     try
918     {
919         if (_iSize < 0)
920         {
921             m_pRealData = NULL;
922             m_pImgData = NULL;
923             char message[bsiz];
924             os_sprintf(message, _("Can not allocate negative size (%d).\n"), _iSize);
925             ast::ScilabError se(message);
926             se.SetErrorNumber(999);
927             throw (se);
928         }
929         else
930         {
931             if (isViewAsZComplex())
932             {
933                 pDbl = (double*)new doublecomplex[_iSize];
934             }
935             else
936             {
937                 pDbl = new double[_iSize];
938             }
939         }
940     }
941     catch (std::bad_alloc & /*e*/)
942     {
943         char message[bsiz];
944         os_sprintf(message, _("Can not allocate %.2f MB memory.\n"), (double)(_iSize * sizeof(double)) / 1.e6);
945         ast::ScilabError se(message);
946         se.SetErrorNumber(999);
947         throw (se);
948     }
949     return pDbl;
950 }
951
952 bool Double::append(int _iRows, int _iCols, InternalType* _poSource)
953 {
954     Double* pD = _poSource->getAs<Double>();
955     int iRows = pD->getRows();
956     int iCols = pD->getCols();
957     int iSize = iRows * iCols;
958
959     //insert without resize
960     if (iRows + _iRows > m_iRows || iCols + _iCols > m_iCols)
961     {
962         return false;
963     }
964
965     //Update complexity if necessary
966     setComplex(isComplex() || pD->isComplex());
967
968     int iInc = 1;
969     int iOne = 1;
970
971     //two cases :
972     //  - append to 0,0
973     //  - real append in x,y
974
975     if (_iRows == 0 && _iCols == 0)
976     {
977         //append to 0,0
978         //std::cout << "append 0,0" << std::endl;
979         if (iRows == 1 || iRows == getRows())
980         {
981             //std::cout << "full Rows or one row" << std::endl;
982             if (iRows == 1)
983             {
984                 iInc = getRows();
985                 //std::cout << "iInc : " << iInc << std::endl;
986             }
987
988             if (isComplex())
989             {
990                 C2F(dcopy)(&iSize, pD->get(), &iOne, get(), &iInc);
991                 if (pD->isComplex())
992                 {
993                     C2F(dcopy)(&iSize, pD->getImg(), &iOne, getImg(), &iInc);
994                 }
995                 else
996                 {
997                     memset(getImg(), 0x00, iSize * sizeof(double));
998                 }
999             }
1000             else
1001             {
1002                 C2F(dcopy)(&iSize, pD->get(), &iOne, get(), &iInc);
1003             }
1004         }
1005         else
1006         {
1007             //std::cout << "part of row" << std::endl;
1008             if (isComplex())
1009             {
1010                 for (int i = 0 ; i < iCols ; i++)
1011                 {
1012                     int iOffset = i * getRows();
1013                     C2F(dcopy)(&iRows, pD->get() + i * iRows, &iOne, get() + iOffset, &iOne);
1014                     if (pD->isComplex())
1015                     {
1016                         C2F(dcopy)(&iRows, pD->getImg() + i * iRows, &iOne, getImg() + iOffset, &iOne);
1017                     }
1018                     else
1019                     {
1020                         memset(getImg() + iOffset, 0x00, iRows * sizeof(double));
1021                     }
1022                 }
1023             }
1024             else
1025             {
1026                 for (int i = 0 ; i < iCols ; i++)
1027                 {
1028                     C2F(dcopy)(&iRows, pD->get() + i * iRows, &iOne, get() + i * getRows(), &iOne);
1029                 }
1030             }
1031         }
1032     }
1033     else if (_iRows == 0 || (_iCols == 0 && (iCols == 1 || iRows == 1)))
1034     {
1035         //real append in x,y
1036         //std::cout << "real append in x,y" << std::endl;
1037         if (iRows == 1)
1038         {
1039             iInc = getRows();
1040             //std::cout << "iInc : " << iInc << std::endl;
1041         }
1042
1043         int iOffset =  _iCols * getRows() + _iRows;
1044         C2F(dcopy)(&iSize, pD->get(), &iOne, get() + iOffset, &iInc);
1045
1046         if (isComplex())
1047         {
1048             int iOffset =  _iCols * getRows() + _iRows;
1049             C2F(dcopy)(&iSize, pD->get(), &iOne, get() + iOffset, &iInc);
1050             if (pD->isComplex())
1051             {
1052                 C2F(dcopy)(&iSize, pD->getImg(), &iOne, getImg() + iOffset, &iInc);
1053             }
1054             else
1055             {
1056                 int iZero = 0;
1057                 double dblZero = 0;
1058                 C2F(dcopy)(&iSize, &dblZero, &iZero, getImg() + iOffset, &iInc);
1059             }
1060         }
1061     }
1062     else
1063     {
1064         //std::cout << "no optimisation" << std::endl;
1065         if (isComplex())
1066         {
1067             for (int i = 0 ; i < iCols ; i++)
1068             {
1069                 int iOffset = (_iCols + i) * getRows() + _iRows;
1070                 C2F(dcopy)(&iRows, pD->get() + i * iRows, &iOne, get() + iOffset, &iOne);
1071                 if (pD->isComplex())
1072                 {
1073                     C2F(dcopy)(&iRows, pD->getImg() + i * iRows, &iOne, getImg() + iOffset, &iOne);
1074                 }
1075                 else
1076                 {
1077                     memset(getImg() + iOffset, 0x00, iRows * sizeof(double));
1078                 }
1079             }
1080         }
1081         else
1082         {
1083             for (int i = 0 ; i < iCols ; i++)
1084             {
1085                 C2F(dcopy)(&iRows, pD->get() + i * iRows, &iOne, get() + (_iCols + i) * getRows() + _iRows, &iOne);
1086             }
1087         }
1088     }
1089     return true;
1090 }
1091
1092 void Double::convertToInteger()
1093 {
1094     if (isViewAsInteger())
1095     {
1096         //already done
1097         return;
1098     }
1099     //convert in place double to integer
1100     int* piR = (int*)get();
1101     double *pdblR = get();
1102
1103     if (isComplex())
1104     {
1105         int* piI = (int*)getImg();
1106         double *pdblI = getImg();
1107
1108         //normal way to prevent overlap
1109         for (int i = 0 ; i < getSize() ; i++)
1110         {
1111             piR[i] = (int)pdblR[i];
1112             piI[i] = (int)pdblI[i];
1113         }
1114     }
1115     else
1116     {
1117         //normal way to prevent overlap
1118         for (int i = 0 ; i < getSize() ; i++)
1119         {
1120             piR[i] = (int)pdblR[i];
1121         }
1122     }
1123
1124     setViewAsInteger(true);
1125 }
1126
1127 void Double::convertFromInteger()
1128 {
1129     if (isViewAsInteger() == false)
1130     {
1131         //no need change
1132         return;
1133     }
1134
1135     int* piR = (int*)get();
1136     double *pdblR = get();
1137     //convert in place integer to double
1138
1139     if (isComplex())
1140     {
1141         int* piI = (int*)getImg();
1142         double *pdblI = getImg();
1143
1144         //reverse way to prevent overlap
1145         for (int i = getSize() - 1 ; i >= 0 ; i--)
1146         {
1147             pdblR[i] = (double)piR[i];
1148             pdblI[i] = (double)piI[i];
1149         }
1150     }
1151     else
1152     {
1153         //reverse way to prevent overlap
1154         for (int i = getSize() - 1 ; i >= 0 ; i--)
1155         {
1156             pdblR[i] = (double)piR[i];
1157         }
1158     }
1159
1160     setViewAsInteger(false);
1161 }
1162
1163 void Double::convertFromZComplex()
1164 {
1165     if (isViewAsZComplex() == false)
1166     {
1167         //no need change
1168         return;
1169     }
1170
1171     doublecomplex* pdblZ = (doublecomplex*)get();
1172     m_pRealData = new double[getSize()];
1173
1174     if (m_pImgData)
1175     {
1176         delete[] m_pImgData;
1177     }
1178
1179     m_pImgData = new double[getSize()];
1180
1181     vGetPointerFromDoubleComplex(pdblZ, getSize(), m_pRealData, m_pImgData);
1182     vFreeDoubleComplexFromPointer(pdblZ);
1183     setViewAsZComplex(false);
1184 }
1185
1186 void Double::convertToZComplex()
1187 {
1188     if (isViewAsZComplex())
1189     {
1190         //already done
1191         return;
1192     }
1193
1194     doublecomplex* pdblZ = NULL;
1195
1196     if (isComplex())
1197     {
1198         pdblZ = oGetDoubleComplexFromPointer(getReal(), getImg() , getSize());
1199         delete[] m_pImgData;
1200         m_pImgData = NULL;
1201     }
1202     else
1203     {
1204         pdblZ = oGetDoubleComplexFromPointer(getReal(), NULL, getSize());
1205     }
1206
1207     delete[] m_pRealData;
1208     m_pRealData = (double*)pdblZ;
1209     setViewAsZComplex(true);
1210 }
1211
1212 ast::Exp* Double::getExp(const Location& loc)
1213 {
1214     return new ast::DoubleExp(loc, this);
1215 }
1216
1217 }