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