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