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