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