c6f31f220745e21f6e54acc380484c795dab5a80
[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 // matrix
396     {
397         std::wostringstream ostemp;
398         int iLen = SIZE_BETWEEN_TWO_VALUES;
399         int iLastCol = m_iCols1PrintState;
400         // some unchanging field is to be retrieved for later used
401         DoubleFormat df;
402         int iBlankSize = df.bPrintBlank ? BLANK_SIZE : 0;
403
404         //Array with the max printed size of each col
405         int *piSize = new int[getCols()];
406         int *piRSize = new int[getCols()];
407         int *piISize = new int[getCols()];
408         memset(piSize, 0x00, getCols() * sizeof(int));
409         memset(piRSize, 0x00, getCols() * sizeof(int));
410         memset(piISize, 0x00, getCols() * sizeof(int));
411
412         if (isComplex() == false)
413         {
414             //compute the row size for padding for the full matrix
415             for (int iCols1 = 0 ; iCols1 < getCols() ; iCols1++)
416             {
417                 for (int iRows1 = 0 ; iRows1 < getRows() ; iRows1++)
418                 {
419                     _piDims[0] = iRows1;
420                     _piDims[1] = iCols1;
421                     int iPos = getIndex(_piDims);
422
423                     DoubleFormat df;
424                     getDoubleFormat(ZeroIsZero(m_pRealData[iPos]), &df);
425                     piSize[iCols1] = std::max(piSize[iCols1], df.iWidth);
426                 }
427             }
428
429             for (int iCols1 = m_iCols1PrintState ; iCols1 < getCols() ; iCols1++)
430             {
431                 if (iLen + piSize[iCols1] > iLineLen && iCols1 != iLastCol)
432                 {
433                     //find the limit, print this part
434                     for (int iRows2 = m_iRows2PrintState ; iRows2 < getRows() ; iRows2++)
435                     {
436                         iCurrentLine++;
437                         if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) ||
438                                 ( (iMaxLines != 0 && iCurrentLine + 3 >= iMaxLines && iRows2 == m_iRows2PrintState) ||
439                                   (iMaxLines != 0 && iCurrentLine + 1 >= iMaxLines && iRows2 != m_iRows2PrintState)))
440                         {
441                             if (m_iRows2PrintState == 0 && iRows2 != 0)
442                             {
443                                 //add header
444                                 addColumnString(ostr, iLastCol + 1, iCols1);
445                             }
446                             ostr << ostemp.str();
447                             m_iRows2PrintState = iRows2;
448                             m_iCols1PrintState = iLastCol;
449                             delete[] piSize;
450                             return false;
451                         }
452
453                         for (int iCols2 = iLastCol ; iCols2 < iCols1 ; iCols2++)
454                         {
455                             _piDims[0] = iRows2;
456                             _piDims[1] = iCols2;
457                             int iPos = getIndex(_piDims);
458
459                             DoubleFormat df;
460                             getDoubleFormat(ZeroIsZero(m_pRealData[iPos]), &df);
461
462                             ostemp << SPACE_BETWEEN_TWO_VALUES;
463
464                             df.iWidth = piSize[iCols2];
465                             addDoubleValue(&ostemp, ZeroIsZero(m_pRealData[iPos]), &df);
466                         }
467                         ostemp << std::endl;
468                     }
469
470                     iLen = SIZE_BETWEEN_TWO_VALUES;
471
472                     iCurrentLine++;
473                     if (m_iRows2PrintState == 0)
474                     {
475                         iCurrentLine += 3;
476                         addColumnString(ostr, iLastCol + 1, iCols1);
477                     }
478                     ostr << ostemp.str();
479                     ostemp.str(L"");
480                     iLastCol = iCols1;
481                     m_iRows2PrintState = 0;
482                     m_iCols1PrintState = 0;
483                 }
484
485                 iLen += piSize[iCols1] + SIZE_BETWEEN_TWO_VALUES + iBlankSize;
486             }
487
488             for (int iRows2 = m_iRows2PrintState ; iRows2 < getRows() ; iRows2++)
489             {
490                 iCurrentLine++;
491                 if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) || (iMaxLines != 0 && iCurrentLine >= iMaxLines))
492                 {
493                     if (m_iRows2PrintState == 0 && iLastCol != 0)
494                     {
495                         //add header
496                         addColumnString(ostr, iLastCol + 1, getCols());
497                     }
498
499                     ostr << ostemp.str();
500                     m_iRows2PrintState = iRows2;
501                     m_iCols1PrintState = iLastCol;
502                     delete[] piSize;
503                     return false;
504                 }
505
506                 for (int iCols2 = iLastCol ; iCols2 < getCols() ; iCols2++)
507                 {
508                     _piDims[0] = iRows2;
509                     _piDims[1] = iCols2;
510                     int iPos = getIndex(_piDims);
511
512                     DoubleFormat df;
513                     getDoubleFormat(ZeroIsZero(m_pRealData[iPos]), &df);
514
515                     ostemp << SPACE_BETWEEN_TWO_VALUES;
516                     df.iWidth = piSize[iCols2];
517                     addDoubleValue(&ostemp, ZeroIsZero(m_pRealData[iPos]), &df);
518                 }
519                 ostemp << std::endl;
520             }
521
522             if (m_iRows2PrintState == 0 && iLastCol != 0)
523             {
524                 addColumnString(ostr, iLastCol + 1, getCols());
525             }
526             ostr << ostemp.str();
527         }
528         else //Complex case
529         {
530             //compute the row size for padding for the full matrix.
531             for (int iCols1 = 0; iCols1 < getCols() ; iCols1++)
532             {
533                 for (int iRows1 = 0 ; iRows1 < getRows() ; iRows1++)
534                 {
535                     int iTotalWidth = 0;
536                     _piDims[0] = iRows1;
537                     _piDims[1] = iCols1;
538                     int iPos = getIndex(_piDims);
539
540                     DoubleFormat dfR, dfI;
541                     getComplexFormat(ZeroIsZero(m_pRealData[iPos]), ZeroIsZero(m_pImgData[iPos]), &iTotalWidth, &dfR, &dfI);
542                     // keep track of real and imaginary part width for further alignment
543                     piISize[iCols1] = std::max(piISize[iCols1], dfI.iWidth);
544                     piRSize[iCols1] = std::max(piRSize[iCols1], dfR.iWidth);
545                     piSize[iCols1]  = std::max(piSize[iCols1], iTotalWidth);
546                 }
547             }
548
549             for (int iCols1 = m_iCols1PrintState ; iCols1 < getCols() ; iCols1++)
550             {
551                 if (iLen + piSize[iCols1] > iLineLen && iCols1 != iLastCol)
552                 {
553                     //find the limit, print this part
554                     for (int iRows2 = m_iRows2PrintState ; iRows2 < getRows() ; iRows2++)
555                     {
556                         iCurrentLine++;
557                         if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) ||
558                                 ( (iMaxLines != 0 && iCurrentLine + 3 >= iMaxLines && iRows2 == m_iRows2PrintState) ||
559                                   (iMaxLines != 0 && iCurrentLine + 1 >= iMaxLines && iRows2 != m_iRows2PrintState)))
560                         {
561                             if (m_iRows2PrintState == 0 && iRows2 != 0)
562                             {
563                                 //add header
564                                 addColumnString(ostr, iLastCol + 1, iCols1);
565                             }
566                             ostr << ostemp.str();
567                             m_iRows2PrintState = iRows2;
568                             m_iCols1PrintState = iLastCol;
569                             delete[] piSize;
570                             delete[] piRSize;
571                             delete[] piISize;
572                             return false;
573                         }
574
575                         for (int iCols2 = iLastCol ; iCols2 < iCols1 ; iCols2++)
576                         {
577                             int iTotalWidth = 0;
578                             _piDims[0] = iRows2;
579                             _piDims[1] = iCols2;
580                             int iPos = getIndex(_piDims);
581
582                             DoubleFormat dfR, dfI;
583                             getComplexFormat(ZeroIsZero(m_pRealData[iPos]), ZeroIsZero(m_pImgData[iPos]), &iTotalWidth, &dfR, &dfI);
584
585                             // override with precomputed real part width for alignment of imaginary part sign
586                             dfR.iWidth = piRSize[iCols2];
587                             dfI.iWidth = piISize[iCols2];
588                             ostemp << SPACE_BETWEEN_TWO_VALUES;
589                             addDoubleComplexValue(&ostemp, ZeroIsZero(m_pRealData[iPos]), ZeroIsZero(m_pImgData[iPos]),  piSize[iCols2], &dfR, &dfI);
590                         }
591                         ostemp << std::endl;
592                     }
593
594                     iLen = SIZE_BETWEEN_TWO_VALUES;
595
596                     iCurrentLine++;
597                     if (m_iRows2PrintState == 0)
598                     {
599                         iCurrentLine += 3;
600                         addColumnString(ostr, iLastCol + 1, iCols1);
601                     }
602                     ostr << ostemp.str();
603                     ostemp.str(L"");
604                     iLastCol = iCols1;
605                     m_iRows2PrintState = 0;
606                     m_iCols1PrintState = 0;
607                 }
608
609                 iLen += piSize[iCols1] + SIZE_BETWEEN_TWO_VALUES;
610             }
611
612             for (int iRows2 = m_iRows2PrintState ; iRows2 < getRows() ; iRows2++)
613             {
614                 iCurrentLine++;
615                 if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) || (iMaxLines != 0 && iCurrentLine >= iMaxLines))
616                 {
617                     if (m_iRows2PrintState == 0 && iLastCol != 0)
618                     {
619                         //add header
620                         addColumnString(ostr, iLastCol + 1, getCols());
621                     }
622
623                     ostr << ostemp.str();
624                     m_iRows2PrintState = iRows2;
625                     m_iCols1PrintState = iLastCol;
626                     delete[] piSize;
627                     delete[] piRSize;
628                     return false;
629                 }
630
631                 for (int iCols2 = iLastCol ; iCols2 < getCols() ; iCols2++)
632                 {
633                     int iTotalWidth = 0;
634                     _piDims[0] = iRows2;
635                     _piDims[1] = iCols2;
636                     int iPos = getIndex(_piDims);
637
638                     DoubleFormat dfR, dfI;
639                     getComplexFormat(ZeroIsZero(m_pRealData[iPos]), ZeroIsZero(m_pImgData[iPos]), &iTotalWidth, &dfR, &dfI);
640
641                     // override with precomputed real part width for aligment of imaginary part sign
642                     dfR.iWidth = piRSize[iCols2];
643                     dfI.iWidth = piISize[iCols2];
644                     ostemp << SPACE_BETWEEN_TWO_VALUES;
645                     addDoubleComplexValue(&ostemp, ZeroIsZero(m_pRealData[iPos]), ZeroIsZero(m_pImgData[iPos]),  piSize[iCols2], &dfR, &dfI);
646                 }
647                 ostemp << std::endl;
648             }
649
650             if (m_iRows2PrintState == 0 && iLastCol != 0)
651             {
652                 addColumnString(ostr, iLastCol + 1, getCols());
653             }
654             ostr << ostemp.str();
655         }
656
657         delete[] piSize;
658         delete[] piRSize;
659         delete[] piISize;
660     }
661
662     return true;
663 }
664
665 Double* Double::clone()
666 {
667     int iOne = 1;
668     Double *pReturn = new Double(m_iDims, m_piDims, isComplex());
669     //memcpy(pReturn->getReal(), m_pRealData, m_iSize * sizeof(double));
670     dcopy_(&m_iSize, m_pRealData, &iOne, pReturn->getReal(), &iOne);
671
672     if (isComplex())
673     {
674         pReturn->setComplex(true);
675         //memcpy(pReturn->getImg(), m_pImgData, m_iSize * sizeof(double));
676         dcopy_(&m_iSize, m_pImgData, &iOne, pReturn->getImg(), &iOne);
677     }
678     return pReturn;
679 }
680
681 bool Double::fillFromCol(int _iCols, Double *_poSource)
682 {
683     //blas
684     int iDestOffset     = _iCols * m_iRows;
685     int iSize           = _poSource->getSize();
686     double* pdblDest    = m_pRealData + iDestOffset;
687     int iOne            = 1;
688     dcopy_(&iSize, _poSource->getReal(), &iOne, pdblDest, &iOne);
689
690     if (isComplex())
691     {
692         pdblDest    = m_pImgData + iDestOffset;
693         dcopy_(&iSize, _poSource->getImg(), &iOne, pdblDest, &iOne);
694     }
695     return true;
696 }
697
698 bool Double::fillFromRow(int _iRows, Double *_poSource)
699 {
700     int iCols = _poSource->getCols();
701
702     if (isComplex())
703     {
704     }
705     else
706     {
707         for (int i = 0 ; i < iCols ; i++)
708         {
709             int iDestOffset     = i * m_iRows + _iRows;
710             int iOrigOffset     = i * _poSource->getRows();
711             int iSize           = _poSource->getRows();
712             double* pdblDest    = m_pRealData + iDestOffset;
713             double* pdblSource  = _poSource->getReal() + iOrigOffset;
714             int iOne            = 1;
715
716             dcopy_(&iSize, pdblSource, &iOne, pdblDest, &iOne);
717         }
718     }
719     return true;
720 }
721
722 bool Double::operator==(const InternalType& it)
723 {
724     if (const_cast<InternalType &>(it).isDouble() == false)
725     {
726         return false;
727     }
728
729     Double* pdbl = const_cast<InternalType &>(it).getAs<Double>();
730
731     if (pdbl->getDims() != getDims())
732     {
733         return false;
734     }
735
736     for (int i = 0 ; i < getDims() ; i++)
737     {
738         if (pdbl->getDimsArray()[i] != getDimsArray()[i])
739         {
740             return false;
741         }
742     }
743
744     double *pdblReal = pdbl->getReal();
745     for (int i = 0 ; i < getSize() ; i++)
746     {
747         if (m_pRealData[i] != pdblReal[i])
748         {
749             return false;
750         }
751     }
752
753     //both complex
754     if (isComplex() && pdbl->isComplex())
755     {
756         double *pdblImg = pdbl->getImg();
757         for (int i = 0 ; i < m_iSize ; i++)
758         {
759             if (m_pImgData[i] != pdblImg[i])
760             {
761                 return false;
762             }
763         }
764     }
765     //pdbl complex check all img values == 0
766     else if (pdbl->isComplex())
767     {
768         double *pdblImg = pdbl->getImg();
769         for (int i = 0 ; i < m_iSize ; i++)
770         {
771             if (pdblImg[i])
772             {
773                 return false;
774             }
775         }
776     }
777     //complex check all img values == 0
778     else if (isComplex())
779     {
780         for (int i = 0 ; i < m_iSize ; i++)
781         {
782             if (m_pImgData[i])
783             {
784                 return false;
785             }
786         }
787     }
788
789     return true;
790 }
791
792 bool Double::operator!=(const InternalType& it)
793 {
794     return !(*this == it);
795 }
796
797 double Double::getNullValue()
798 {
799     return 0;
800 }
801
802 Double* Double::createEmpty(int _iDims, int* _piDims, bool _bComplex)
803 {
804     return new Double(_iDims, _piDims, _bComplex);
805 }
806
807 double Double::copyValue(double _dblData)
808 {
809     return _dblData;
810 }
811
812 void Double::deleteAll()
813 {
814     if (isViewAsZComplex())
815     {
816         vFreeDoubleComplexFromPointer((doublecomplex*)m_pRealData);
817     }
818     else
819     {
820         delete[] m_pRealData;
821     }
822
823     m_pRealData = NULL;
824     deleteImg();
825 }
826
827 void Double::deleteImg()
828 {
829     if (isComplex() && m_pImgData)
830     {
831         delete[] m_pImgData;
832         m_pImgData = NULL;
833     }
834 }
835
836 double* Double::allocData(int _iSize)
837 {
838     if (isViewAsZComplex())
839     {
840         return (double*)new doublecomplex[_iSize];
841     }
842     else
843     {
844         return new double[_iSize];
845     }
846 }
847
848 Double* Double::append(int _iRows, int _iCols, InternalType* _poSource)
849 {
850     Double* pIT = checkRef(this, &Double::append, _iRows, _iCols, _poSource);
851     if (pIT != this)
852     {
853         return pIT;
854     }
855
856     Double* pD = _poSource->getAs<Double>();
857     int iRows = pD->getRows();
858     int iCols = pD->getCols();
859     int iSize = iRows * iCols;
860
861     //insert without resize
862     if (iRows + _iRows > m_iRows || iCols + _iCols > m_iCols)
863     {
864         return NULL;
865     }
866
867     //Update complexity if necessary
868     setComplex(isComplex() || pD->isComplex());
869
870     int iInc = 1;
871     int iOne = 1;
872
873     //two cases :
874     //  - append to 0,0
875     //  - real append in x,y
876
877     if (_iRows == 0 && _iCols == 0)
878     {
879         //append to 0,0
880         //std::cout << "append 0,0" << std::endl;
881         if (iRows == 1 || iRows == getRows())
882         {
883             //std::cout << "full Rows or one row" << std::endl;
884             if (iRows == 1)
885             {
886                 iInc = getRows();
887                 //std::cout << "iInc : " << iInc << std::endl;
888             }
889
890             if (isComplex())
891             {
892                 C2F(dcopy)(&iSize, pD->get(), &iOne, get(), &iInc);
893                 if (pD->isComplex())
894                 {
895                     C2F(dcopy)(&iSize, pD->getImg(), &iOne, getImg(), &iInc);
896                 }
897                 else
898                 {
899                     memset(getImg(), 0x00, iSize * sizeof(double));
900                 }
901             }
902             else
903             {
904                 C2F(dcopy)(&iSize, pD->get(), &iOne, get(), &iInc);
905             }
906         }
907         else
908         {
909             //std::cout << "part of row" << std::endl;
910             if (isComplex())
911             {
912                 for (int i = 0 ; i < iCols ; i++)
913                 {
914                     int iOffset = i * getRows();
915                     C2F(dcopy)(&iRows, pD->get() + i * iRows, &iOne, get() + iOffset, &iOne);
916                     if (pD->isComplex())
917                     {
918                         C2F(dcopy)(&iRows, pD->getImg() + i * iRows, &iOne, getImg() + iOffset, &iOne);
919                     }
920                     else
921                     {
922                         memset(getImg() + iOffset, 0x00, iRows * sizeof(double));
923                     }
924                 }
925             }
926             else
927             {
928                 for (int i = 0 ; i < iCols ; i++)
929                 {
930                     C2F(dcopy)(&iRows, pD->get() + i * iRows, &iOne, get() + i * getRows(), &iOne);
931                 }
932             }
933         }
934     }
935     else if (_iRows == 0 || (_iCols == 0 && (iCols == 1 || iRows == 1)))
936     {
937         //real append in x,y
938         //std::cout << "real append in x,y" << std::endl;
939         if (iRows == 1)
940         {
941             iInc = getRows();
942             //std::cout << "iInc : " << iInc << std::endl;
943         }
944
945         int iOffset =  _iCols * getRows() + _iRows;
946         C2F(dcopy)(&iSize, pD->get(), &iOne, get() + iOffset, &iInc);
947
948         if (isComplex())
949         {
950             int iOffset =  _iCols * getRows() + _iRows;
951             C2F(dcopy)(&iSize, pD->get(), &iOne, get() + iOffset, &iInc);
952             if (pD->isComplex())
953             {
954                 C2F(dcopy)(&iSize, pD->getImg(), &iOne, getImg() + iOffset, &iInc);
955             }
956             else
957             {
958                 int iZero = 0;
959                 double dblZero = 0;
960                 C2F(dcopy)(&iSize, &dblZero, &iZero, getImg() + iOffset, &iInc);
961             }
962         }
963     }
964     else
965     {
966         //std::cout << "no optimisation" << std::endl;
967         if (isComplex())
968         {
969             for (int i = 0 ; i < iCols ; i++)
970             {
971                 int iOffset = (_iCols + i) * getRows() + _iRows;
972                 C2F(dcopy)(&iRows, pD->get() + i * iRows, &iOne, get() + iOffset, &iOne);
973                 if (pD->isComplex())
974                 {
975                     C2F(dcopy)(&iRows, pD->getImg() + i * iRows, &iOne, getImg() + iOffset, &iOne);
976                 }
977                 else
978                 {
979                     memset(getImg() + iOffset, 0x00, iRows * sizeof(double));
980                 }
981             }
982         }
983         else
984         {
985             for (int i = 0 ; i < iCols ; i++)
986             {
987                 C2F(dcopy)(&iRows, pD->get() + i * iRows, &iOne, get() + (_iCols + i) * getRows() + _iRows, &iOne);
988             }
989         }
990     }
991     return this;
992 }
993
994 void Double::convertToInteger()
995 {
996     if (isViewAsInteger())
997     {
998         //already done
999         return;
1000     }
1001     //convert in place double to integer
1002     int* piR = (int*)get();
1003     double *pdblR = get();
1004
1005     if (isComplex())
1006     {
1007         int* piI = (int*)getImg();
1008         double *pdblI = getImg();
1009
1010         //normal way to prevent overlap
1011         for (int i = 0 ; i < getSize() ; i++)
1012         {
1013             piR[i] = (int)pdblR[i];
1014             piI[i] = (int)pdblI[i];
1015         }
1016     }
1017     else
1018     {
1019         //normal way to prevent overlap
1020         for (int i = 0 ; i < getSize() ; i++)
1021         {
1022             piR[i] = (int)pdblR[i];
1023         }
1024     }
1025
1026     setViewAsInteger(true);
1027 }
1028
1029 void Double::convertFromInteger()
1030 {
1031     if (isViewAsInteger() == false)
1032     {
1033         //no need change
1034         return;
1035     }
1036
1037     int* piR = (int*)get();
1038     double *pdblR = get();
1039     //convert in place integer to double
1040
1041     if (isComplex())
1042     {
1043         int* piI = (int*)getImg();
1044         double *pdblI = getImg();
1045
1046         //reverse way to prevent overlap
1047         for (int i = getSize() - 1 ; i >= 0 ; i--)
1048         {
1049             pdblR[i] = (double)piR[i];
1050             pdblI[i] = (double)piI[i];
1051         }
1052     }
1053     else
1054     {
1055         //reverse way to prevent overlap
1056         for (int i = getSize() - 1 ; i >= 0 ; i--)
1057         {
1058             pdblR[i] = (double)piR[i];
1059         }
1060     }
1061
1062     setViewAsInteger(false);
1063 }
1064
1065 void Double::convertFromZComplex()
1066 {
1067     if (isViewAsZComplex() == false)
1068     {
1069         //no need change
1070         return;
1071     }
1072
1073     doublecomplex* pdblZ = (doublecomplex*)get();
1074     m_pRealData = new double[getSize()];
1075
1076     if (m_pImgData)
1077     {
1078         delete[] m_pImgData;
1079     }
1080
1081     m_pImgData = new double[getSize()];
1082
1083     vGetPointerFromDoubleComplex(pdblZ, getSize(), m_pRealData, m_pImgData);
1084     vFreeDoubleComplexFromPointer(pdblZ);
1085     setViewAsZComplex(false);
1086 }
1087
1088 void Double::convertToZComplex()
1089 {
1090     if (isViewAsZComplex())
1091     {
1092         //already done
1093         return;
1094     }
1095
1096     doublecomplex* pdblZ = NULL;
1097
1098     if (isComplex())
1099     {
1100         pdblZ = oGetDoubleComplexFromPointer(getReal(), getImg() , getSize());
1101         delete[] m_pImgData;
1102         m_pImgData = NULL;
1103     }
1104     else
1105     {
1106         pdblZ = oGetDoubleComplexFromPointer(getReal(), NULL, getSize());
1107     }
1108
1109     delete[] m_pRealData;
1110     m_pRealData = (double*)pdblZ;
1111     setViewAsZComplex(true);
1112 }
1113
1114 ast::Exp* Double::getExp(const Location& loc)
1115 {
1116     return new ast::DoubleExp(loc, this);
1117 }
1118
1119 bool Double::isTrue()
1120 {
1121     if (isEmpty() || isComplex())
1122     {
1123         return false;
1124     }
1125
1126     return type_traits::isTrue<double>(m_iSize, m_pRealData);
1127 }
1128 }