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