* Bug #14303 fixed - matrix display for large number was not correctly aligned
[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         if (isComplex() == false)
558         {
559             //compute the row size for padding for each printed bloc.
560             for (int iCols1 = m_iCols1PrintState ; iCols1 < getCols() ; iCols1++)
561             {
562                 for (int iRows1 = 0 ; iRows1 < getRows() ; iRows1++)
563                 {
564                     _piDims[0] = iRows1;
565                     _piDims[1] = iCols1;
566                     int iPos = getIndex(_piDims);
567
568                     DoubleFormat df;
569                     getDoubleFormat(ZeroIsZero(m_pRealData[iPos]), &df);
570                     piSize[iCols1] = std::max(piSize[iCols1], df.iWidth);
571                 }
572
573                 if (iLen + piSize[iCols1] > iLineLen && iCols1 != iLastCol)
574                 {
575                     //find the limit, print this part
576                     for (int iRows2 = m_iRows2PrintState ; iRows2 < getRows() ; iRows2++)
577                     {
578                         iCurrentLine++;
579                         if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) ||
580                                 ( (iMaxLines != 0 && iCurrentLine + 3 >= iMaxLines && iRows2 == m_iRows2PrintState) ||
581                                   (iMaxLines != 0 && iCurrentLine + 1 >= iMaxLines && iRows2 != m_iRows2PrintState)))
582                         {
583                             if (m_iRows2PrintState == 0 && iRows2 != 0)
584                             {
585                                 //add header
586                                 addColumnString(ostr, iLastCol + 1, iCols1);
587                             }
588                             ostr << ostemp.str();
589                             m_iRows2PrintState = iRows2;
590                             m_iCols1PrintState = iLastCol;
591                             delete[] piSize;
592                             return false;
593                         }
594
595                         for (int iCols2 = iLastCol ; iCols2 < iCols1 ; iCols2++)
596                         {
597                             _piDims[0] = iRows2;
598                             _piDims[1] = iCols2;
599                             int iPos = getIndex(_piDims);
600
601                             DoubleFormat df;
602                             getDoubleFormat(ZeroIsZero(m_pRealData[iPos]), &df);
603
604                             ostemp << SPACE_BETWEEN_TWO_VALUES;
605
606                             df.iWidth = piSize[iCols2];
607                             addDoubleValue(&ostemp, ZeroIsZero(m_pRealData[iPos]), &df);
608                         }
609                         ostemp << std::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                     return false;
646                 }
647
648                 for (int iCols2 = iLastCol ; iCols2 < getCols() ; iCols2++)
649                 {
650                     _piDims[0] = iRows2;
651                     _piDims[1] = iCols2;
652                     int iPos = getIndex(_piDims);
653
654                     DoubleFormat df;
655                     getDoubleFormat(ZeroIsZero(m_pRealData[iPos]), &df);
656
657                     ostemp << SPACE_BETWEEN_TWO_VALUES;
658                     df.iWidth = piSize[iCols2];
659                     addDoubleValue(&ostemp, ZeroIsZero(m_pRealData[iPos]), &df);
660                 }
661                 ostemp << std::endl;
662             }
663
664             if (m_iRows2PrintState == 0 && iLastCol != 0)
665             {
666                 addColumnString(ostr, iLastCol + 1, getCols());
667             }
668             ostr << ostemp.str();
669         }
670         else //Complex case
671         {
672             //compute the row size for padding for each printed bloc.
673             for (int iCols1 = m_iCols1PrintState ; iCols1 < getCols() ; iCols1++)
674             {
675                 for (int iRows1 = 0 ; iRows1 < getRows() ; iRows1++)
676                 {
677                     int iTotalWidth = 0;
678                     _piDims[0] = iRows1;
679                     _piDims[1] = iCols1;
680                     int iPos = getIndex(_piDims);
681
682                     DoubleFormat dfR, dfI;
683                     getComplexFormat(ZeroIsZero(m_pRealData[iPos]), ZeroIsZero(m_pImgData[iPos]), &iTotalWidth, &dfR, &dfI);
684
685                     iTotalWidth += (dfR.iWidth == 0 ? 0 : SIGN_LENGTH) + (dfI.iWidth == 0 ? 0 : SIGN_LENGTH + 1);
686                     if (iTotalWidth > piSize[iCols1])
687                     {
688                         piSize[iCols1] = iTotalWidth;
689                     }
690
691                 }
692
693                 if (iLen + piSize[iCols1] > iLineLen && iCols1 != iLastCol)
694                 {
695                     //find the limit, print this part
696                     for (int iRows2 = m_iRows2PrintState ; iRows2 < getRows() ; iRows2++)
697                     {
698                         iCurrentLine++;
699                         if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) ||
700                                 ( (iMaxLines != 0 && iCurrentLine + 3 >= iMaxLines && iRows2 == m_iRows2PrintState) ||
701                                   (iMaxLines != 0 && iCurrentLine + 1 >= iMaxLines && iRows2 != m_iRows2PrintState)))
702                         {
703                             if (m_iRows2PrintState == 0 && iRows2 != 0)
704                             {
705                                 //add header
706                                 addColumnString(ostr, iLastCol + 1, iCols1);
707                             }
708                             ostr << ostemp.str();
709                             m_iRows2PrintState = iRows2;
710                             m_iCols1PrintState = iLastCol;
711                             delete[] piSize;
712                             return false;
713                         }
714
715                         for (int iCols2 = iLastCol ; iCols2 < iCols1 ; iCols2++)
716                         {
717                             int iTotalWidth = 0;
718                             _piDims[0] = iRows2;
719                             _piDims[1] = iCols2;
720                             int iPos = getIndex(_piDims);
721
722                             DoubleFormat dfR, dfI;
723                             getComplexFormat(ZeroIsZero(m_pRealData[iPos]), ZeroIsZero(m_pImgData[iPos]), &iTotalWidth, &dfR, &dfI);
724
725                             ostemp << SPACE_BETWEEN_TWO_VALUES;
726                             addDoubleComplexValue(&ostemp, ZeroIsZero(m_pRealData[iPos]), ZeroIsZero(m_pImgData[iPos]), piSize[iCols2], &dfR, &dfI);
727                         }
728                         ostemp << std::endl;
729                     }
730
731                     iLen = 0;
732
733                     iCurrentLine++;
734                     if (m_iRows2PrintState == 0)
735                     {
736                         iCurrentLine += 3;
737                         addColumnString(ostr, iLastCol + 1, iCols1);
738                     }
739                     ostr << ostemp.str();
740                     ostemp.str(L"");
741                     iLastCol = iCols1;
742                     m_iRows2PrintState = 0;
743                     m_iCols1PrintState = 0;
744                 }
745
746                 iLen += piSize[iCols1] + SIZE_BETWEEN_TWO_VALUES;
747             }
748
749             for (int iRows2 = m_iRows2PrintState ; iRows2 < getRows() ; iRows2++)
750             {
751                 iCurrentLine++;
752                 if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) || (iMaxLines != 0 && iCurrentLine >= iMaxLines))
753                 {
754                     if (m_iRows2PrintState == 0 && iLastCol != 0)
755                     {
756                         //add header
757                         addColumnString(ostr, iLastCol + 1, getCols());
758                     }
759
760                     ostr << ostemp.str();
761                     m_iRows2PrintState = iRows2;
762                     m_iCols1PrintState = iLastCol;
763                     delete[] piSize;
764                     return false;
765                 }
766
767                 for (int iCols2 = iLastCol ; iCols2 < getCols() ; iCols2++)
768                 {
769                     int iTotalWidth = 0;
770                     _piDims[0] = iRows2;
771                     _piDims[1] = iCols2;
772                     int iPos = getIndex(_piDims);
773
774                     DoubleFormat dfR, dfI;
775                     getComplexFormat(ZeroIsZero(m_pRealData[iPos]), ZeroIsZero(m_pImgData[iPos]), &iTotalWidth, &dfR, &dfI);
776
777                     ostemp << SPACE_BETWEEN_TWO_VALUES;
778                     addDoubleComplexValue(&ostemp, ZeroIsZero(m_pRealData[iPos]), ZeroIsZero(m_pImgData[iPos]), piSize[iCols2], &dfR, &dfI);
779                 }
780                 ostemp << std::endl;
781             }
782
783             if (m_iRows2PrintState == 0 && iLastCol != 0)
784             {
785                 addColumnString(ostr, iLastCol + 1, getCols());
786             }
787             ostr << ostemp.str();
788         }
789
790         delete[] piSize;
791     }
792
793     return true;
794 }
795
796 Double* Double::clone()
797 {
798     int iOne = 1;
799     Double *pReturn = new Double(m_iDims, m_piDims, isComplex());
800     //memcpy(pReturn->getReal(), m_pRealData, m_iSize * sizeof(double));
801     dcopy_(&m_iSize, m_pRealData, &iOne, pReturn->getReal(), &iOne);
802
803     if (isComplex())
804     {
805         pReturn->setComplex(true);
806         //memcpy(pReturn->getImg(), m_pImgData, m_iSize * sizeof(double));
807         dcopy_(&m_iSize, m_pImgData, &iOne, pReturn->getImg(), &iOne);
808     }
809     return pReturn;
810 }
811
812 bool Double::fillFromCol(int _iCols, Double *_poSource)
813 {
814     //blas
815     int iDestOffset     = _iCols * m_iRows;
816     int iSize           = _poSource->getSize();
817     double* pdblDest    = m_pRealData + iDestOffset;
818     int iOne            = 1;
819     dcopy_(&iSize, _poSource->getReal(), &iOne, pdblDest, &iOne);
820
821     if (isComplex())
822     {
823         pdblDest    = m_pImgData + iDestOffset;
824         dcopy_(&iSize, _poSource->getImg(), &iOne, pdblDest, &iOne);
825     }
826     return true;
827 }
828
829 bool Double::fillFromRow(int _iRows, Double *_poSource)
830 {
831     int iCols = _poSource->getCols();
832
833     if (isComplex())
834     {
835     }
836     else
837     {
838         for (int i = 0 ; i < iCols ; i++)
839         {
840             int iDestOffset     = i * m_iRows + _iRows;
841             int iOrigOffset     = i * _poSource->getRows();
842             int iSize           = _poSource->getRows();
843             double* pdblDest    = m_pRealData + iDestOffset;
844             double* pdblSource  = _poSource->getReal() + iOrigOffset;
845             int iOne            = 1;
846
847             dcopy_(&iSize, pdblSource, &iOne, pdblDest, &iOne);
848         }
849     }
850     return true;
851 }
852
853 bool Double::operator==(const InternalType& it)
854 {
855     if (const_cast<InternalType &>(it).isDouble() == false)
856     {
857         return false;
858     }
859
860     Double* pdbl = const_cast<InternalType &>(it).getAs<Double>();
861
862     if (pdbl->getDims() != getDims())
863     {
864         return false;
865     }
866
867     for (int i = 0 ; i < getDims() ; i++)
868     {
869         if (pdbl->getDimsArray()[i] != getDimsArray()[i])
870         {
871             return false;
872         }
873     }
874
875     double *pdblReal = pdbl->getReal();
876     for (int i = 0 ; i < getSize() ; i++)
877     {
878         if (m_pRealData[i] != pdblReal[i])
879         {
880             return false;
881         }
882     }
883
884     //both complex
885     if (isComplex() && pdbl->isComplex())
886     {
887         double *pdblImg = pdbl->getImg();
888         for (int i = 0 ; i < m_iSize ; i++)
889         {
890             if (m_pImgData[i] != pdblImg[i])
891             {
892                 return false;
893             }
894         }
895     }
896     //pdbl complex check all img values == 0
897     else if (pdbl->isComplex())
898     {
899         double *pdblImg = pdbl->getImg();
900         for (int i = 0 ; i < m_iSize ; i++)
901         {
902             if (pdblImg[i])
903             {
904                 return false;
905             }
906         }
907     }
908     //complex check all img values == 0
909     else if (isComplex())
910     {
911         for (int i = 0 ; i < m_iSize ; i++)
912         {
913             if (m_pImgData[i])
914             {
915                 return false;
916             }
917         }
918     }
919
920     return true;
921 }
922
923 bool Double::operator!=(const InternalType& it)
924 {
925     return !(*this == it);
926 }
927
928 double Double::getNullValue()
929 {
930     return 0;
931 }
932
933 Double* Double::createEmpty(int _iDims, int* _piDims, bool _bComplex)
934 {
935     return new Double(_iDims, _piDims, _bComplex);
936 }
937
938 double Double::copyValue(double _dblData)
939 {
940     return _dblData;
941 }
942
943 void Double::deleteAll()
944 {
945     delete[] m_pRealData;
946     m_pRealData = NULL;
947     deleteImg();
948 }
949
950 void Double::deleteImg()
951 {
952     if (isComplex() && m_pImgData)
953     {
954         delete[] m_pImgData;
955         m_pImgData = NULL;
956     }
957 }
958
959 double* Double::allocData(int _iSize)
960 {
961     if (isViewAsZComplex())
962     {
963         return (double*)new doublecomplex[_iSize];
964     }
965     else
966     {
967         return new double[_iSize];
968     }
969 }
970
971 Double* Double::append(int _iRows, int _iCols, InternalType* _poSource)
972 {
973     Double* pIT = checkRef(this, &Double::append, _iRows, _iCols, _poSource);
974     if (pIT != this)
975     {
976         return pIT;
977     }
978
979     Double* pD = _poSource->getAs<Double>();
980     int iRows = pD->getRows();
981     int iCols = pD->getCols();
982     int iSize = iRows * iCols;
983
984     //insert without resize
985     if (iRows + _iRows > m_iRows || iCols + _iCols > m_iCols)
986     {
987         return NULL;
988     }
989
990     //Update complexity if necessary
991     setComplex(isComplex() || pD->isComplex());
992
993     int iInc = 1;
994     int iOne = 1;
995
996     //two cases :
997     //  - append to 0,0
998     //  - real append in x,y
999
1000     if (_iRows == 0 && _iCols == 0)
1001     {
1002         //append to 0,0
1003         //std::cout << "append 0,0" << std::endl;
1004         if (iRows == 1 || iRows == getRows())
1005         {
1006             //std::cout << "full Rows or one row" << std::endl;
1007             if (iRows == 1)
1008             {
1009                 iInc = getRows();
1010                 //std::cout << "iInc : " << iInc << std::endl;
1011             }
1012
1013             if (isComplex())
1014             {
1015                 C2F(dcopy)(&iSize, pD->get(), &iOne, get(), &iInc);
1016                 if (pD->isComplex())
1017                 {
1018                     C2F(dcopy)(&iSize, pD->getImg(), &iOne, getImg(), &iInc);
1019                 }
1020                 else
1021                 {
1022                     memset(getImg(), 0x00, iSize * sizeof(double));
1023                 }
1024             }
1025             else
1026             {
1027                 C2F(dcopy)(&iSize, pD->get(), &iOne, get(), &iInc);
1028             }
1029         }
1030         else
1031         {
1032             //std::cout << "part of row" << std::endl;
1033             if (isComplex())
1034             {
1035                 for (int i = 0 ; i < iCols ; i++)
1036                 {
1037                     int iOffset = i * getRows();
1038                     C2F(dcopy)(&iRows, pD->get() + i * iRows, &iOne, get() + iOffset, &iOne);
1039                     if (pD->isComplex())
1040                     {
1041                         C2F(dcopy)(&iRows, pD->getImg() + i * iRows, &iOne, getImg() + iOffset, &iOne);
1042                     }
1043                     else
1044                     {
1045                         memset(getImg() + iOffset, 0x00, iRows * sizeof(double));
1046                     }
1047                 }
1048             }
1049             else
1050             {
1051                 for (int i = 0 ; i < iCols ; i++)
1052                 {
1053                     C2F(dcopy)(&iRows, pD->get() + i * iRows, &iOne, get() + i * getRows(), &iOne);
1054                 }
1055             }
1056         }
1057     }
1058     else if (_iRows == 0 || (_iCols == 0 && (iCols == 1 || iRows == 1)))
1059     {
1060         //real append in x,y
1061         //std::cout << "real append in x,y" << std::endl;
1062         if (iRows == 1)
1063         {
1064             iInc = getRows();
1065             //std::cout << "iInc : " << iInc << std::endl;
1066         }
1067
1068         int iOffset =  _iCols * getRows() + _iRows;
1069         C2F(dcopy)(&iSize, pD->get(), &iOne, get() + iOffset, &iInc);
1070
1071         if (isComplex())
1072         {
1073             int iOffset =  _iCols * getRows() + _iRows;
1074             C2F(dcopy)(&iSize, pD->get(), &iOne, get() + iOffset, &iInc);
1075             if (pD->isComplex())
1076             {
1077                 C2F(dcopy)(&iSize, pD->getImg(), &iOne, getImg() + iOffset, &iInc);
1078             }
1079             else
1080             {
1081                 int iZero = 0;
1082                 double dblZero = 0;
1083                 C2F(dcopy)(&iSize, &dblZero, &iZero, getImg() + iOffset, &iInc);
1084             }
1085         }
1086     }
1087     else
1088     {
1089         //std::cout << "no optimisation" << std::endl;
1090         if (isComplex())
1091         {
1092             for (int i = 0 ; i < iCols ; i++)
1093             {
1094                 int iOffset = (_iCols + i) * getRows() + _iRows;
1095                 C2F(dcopy)(&iRows, pD->get() + i * iRows, &iOne, get() + iOffset, &iOne);
1096                 if (pD->isComplex())
1097                 {
1098                     C2F(dcopy)(&iRows, pD->getImg() + i * iRows, &iOne, getImg() + iOffset, &iOne);
1099                 }
1100                 else
1101                 {
1102                     memset(getImg() + iOffset, 0x00, iRows * sizeof(double));
1103                 }
1104             }
1105         }
1106         else
1107         {
1108             for (int i = 0 ; i < iCols ; i++)
1109             {
1110                 C2F(dcopy)(&iRows, pD->get() + i * iRows, &iOne, get() + (_iCols + i) * getRows() + _iRows, &iOne);
1111             }
1112         }
1113     }
1114     return this;
1115 }
1116
1117 void Double::convertToInteger()
1118 {
1119     if (isViewAsInteger())
1120     {
1121         //already done
1122         return;
1123     }
1124     //convert in place double to integer
1125     int* piR = (int*)get();
1126     double *pdblR = get();
1127
1128     if (isComplex())
1129     {
1130         int* piI = (int*)getImg();
1131         double *pdblI = getImg();
1132
1133         //normal way to prevent overlap
1134         for (int i = 0 ; i < getSize() ; i++)
1135         {
1136             piR[i] = (int)pdblR[i];
1137             piI[i] = (int)pdblI[i];
1138         }
1139     }
1140     else
1141     {
1142         //normal way to prevent overlap
1143         for (int i = 0 ; i < getSize() ; i++)
1144         {
1145             piR[i] = (int)pdblR[i];
1146         }
1147     }
1148
1149     setViewAsInteger(true);
1150 }
1151
1152 void Double::convertFromInteger()
1153 {
1154     if (isViewAsInteger() == false)
1155     {
1156         //no need change
1157         return;
1158     }
1159
1160     int* piR = (int*)get();
1161     double *pdblR = get();
1162     //convert in place integer to double
1163
1164     if (isComplex())
1165     {
1166         int* piI = (int*)getImg();
1167         double *pdblI = getImg();
1168
1169         //reverse way to prevent overlap
1170         for (int i = getSize() - 1 ; i >= 0 ; i--)
1171         {
1172             pdblR[i] = (double)piR[i];
1173             pdblI[i] = (double)piI[i];
1174         }
1175     }
1176     else
1177     {
1178         //reverse way to prevent overlap
1179         for (int i = getSize() - 1 ; i >= 0 ; i--)
1180         {
1181             pdblR[i] = (double)piR[i];
1182         }
1183     }
1184
1185     setViewAsInteger(false);
1186 }
1187
1188 void Double::convertFromZComplex()
1189 {
1190     if (isViewAsZComplex() == false)
1191     {
1192         //no need change
1193         return;
1194     }
1195
1196     doublecomplex* pdblZ = (doublecomplex*)get();
1197     m_pRealData = new double[getSize()];
1198
1199     if (m_pImgData)
1200     {
1201         delete[] m_pImgData;
1202     }
1203
1204     m_pImgData = new double[getSize()];
1205
1206     vGetPointerFromDoubleComplex(pdblZ, getSize(), m_pRealData, m_pImgData);
1207     vFreeDoubleComplexFromPointer(pdblZ);
1208     setViewAsZComplex(false);
1209 }
1210
1211 void Double::convertToZComplex()
1212 {
1213     if (isViewAsZComplex())
1214     {
1215         //already done
1216         return;
1217     }
1218
1219     doublecomplex* pdblZ = NULL;
1220
1221     if (isComplex())
1222     {
1223         pdblZ = oGetDoubleComplexFromPointer(getReal(), getImg() , getSize());
1224         delete[] m_pImgData;
1225         m_pImgData = NULL;
1226     }
1227     else
1228     {
1229         pdblZ = oGetDoubleComplexFromPointer(getReal(), NULL, getSize());
1230     }
1231
1232     delete[] m_pRealData;
1233     m_pRealData = (double*)pdblZ;
1234     setViewAsZComplex(true);
1235 }
1236
1237 ast::Exp* Double::getExp(const Location& loc)
1238 {
1239     return new ast::DoubleExp(loc, this);
1240 }
1241
1242 bool Double::isTrue()
1243 {
1244     if (isEmpty() || isComplex())
1245     {
1246         return false;
1247     }
1248
1249     return type_traits::isTrue<double>(m_iSize, m_pRealData);
1250 }
1251 }