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