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