535ad802f030d1f0e33a42f28ed84a7a27452df3
[scilab.git] / scilab / modules / ast / src / cpp / types / polynom.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 <algorithm>
18 #include "core_math.h"
19 #include "tostring_common.hxx"
20 #include "singlepoly.hxx"
21 #include "polynom.hxx"
22 #include "configvariable.hxx"
23
24 namespace types
25 {
26 Polynom::Polynom()
27 {
28 #ifndef NDEBUG
29     Inspector::addItem(this);
30 #endif
31 }
32
33 Polynom::Polynom(const std::wstring& _szVarName, int _iRows, int _iCols)
34 {
35     int piDims[2]   = {_iRows, _iCols};
36     createPoly(_szVarName, 2, piDims, NULL);
37 }
38
39 Polynom::Polynom(const std::wstring& _szVarName, int _iRows, int _iCols, const int *_piRank)
40 {
41     int piDims[2]   = {_iRows, _iCols};
42     createPoly(_szVarName, 2, piDims, _piRank);
43 }
44
45 Polynom::Polynom(const std::wstring& _szVarName, int _iDims, const int* _piDims)
46 {
47     createPoly(_szVarName, _iDims, _piDims, NULL);
48 }
49
50 Polynom::Polynom(const std::wstring& _szVarName, int _iDims, const int* _piDims, const int *_piRank)
51 {
52     createPoly(_szVarName, _iDims, _piDims, _piRank);
53 }
54
55 Polynom::~Polynom()
56 {
57     if (isDeletable() == true)
58     {
59         deleteAll();
60     }
61 #ifndef NDEBUG
62     Inspector::removeItem(this);
63 #endif
64 }
65
66 bool Polynom::getMemory(long long* _piSize, long long* _piSizePlusType)
67 {
68     *_piSize = 0;
69     for (int i = 0; i<getSize(); i++)
70     {
71         *_piSize += (get(i)->getRank()+1)*sizeof(double);
72     }
73     
74     *_piSize = *_piSize * (isComplex() ? 2 : 1);
75     *_piSizePlusType = *_piSize + getSize()*sizeof(SinglePoly *) + sizeof(*this);
76     return true;
77 }
78
79
80 void Polynom::createPoly(const std::wstring& _szVarName, int _iDims, const int* _piDims, const int *_piRank)
81 {
82     m_szVarName = _szVarName;
83     SinglePoly** pPoly = NULL;
84     create(_piDims, _iDims, &pPoly, NULL);
85
86     if (_piRank)
87     {
88         for (int i = 0 ; i < getSize() ; i++)
89         {
90             double* pReal = NULL;
91             m_pRealData[i] = new SinglePoly(&pReal, _piRank[i]);
92         }
93     }
94 #ifndef NDEBUG
95     Inspector::addItem(this);
96 #endif
97 }
98
99 Polynom* Polynom::set(int _iPos, SinglePoly* _pS)
100 {
101     if (m_pRealData == NULL || _iPos >= m_iSize)
102     {
103         return NULL;
104     }
105
106     typedef Polynom* (Polynom::*set_t)(int, SinglePoly*);
107     Polynom* pIT = checkRef(this, (set_t)&Polynom::set, _iPos, _pS);
108     if (pIT != this)
109     {
110         return pIT;
111     }
112
113     if (m_pRealData[_iPos])
114     {
115         delete m_pRealData[_iPos];
116     }
117
118     m_pRealData[_iPos] = copyValue(_pS);
119
120     bool bComplex = isComplex();
121     if (_pS->isComplex() && bComplex == false)
122     {
123         setComplex(true);
124     }
125     else if (_pS->isComplex() == false && bComplex)
126     {
127         m_pRealData[_iPos]->setComplex(true);
128     }
129
130     return this;
131 }
132
133 Polynom* Polynom::set(int _iRows, int _iCols, SinglePoly* _pS)
134 {
135     return set(_iCols * getRows() + _iRows, _pS);
136 }
137
138 Polynom* Polynom::set(SinglePoly** _pS)
139 {
140     typedef Polynom* (Polynom::*set_t)(SinglePoly**);
141     Polynom* pIT = checkRef(this, (set_t)&Polynom::set, _pS);
142     if (pIT != this)
143     {
144         return pIT;
145     }
146
147     for (int i = 0 ; i < m_iSize ; i++)
148     {
149         set(i, _pS[i]);
150     }
151
152     return this;
153 }
154
155 Polynom* Polynom::setCoef(int _iRows, int _iCols, Double *_pdblCoef)
156 {
157     int piDims[] = {_iRows, _iCols};
158     int iPos = getIndex(piDims);
159     return setCoef(iPos, _pdblCoef);
160 }
161
162 Polynom* Polynom::setCoef(int _iIdx, Double *_pdblCoef)
163 {
164     if (_iIdx > m_iSize)
165     {
166         return NULL;
167     }
168
169     typedef Polynom* (Polynom::*setCoef_t)(int, Double*);
170     Polynom* pIT = checkRef(this, (setCoef_t)&Polynom::setCoef, _iIdx, _pdblCoef);
171     if (pIT != this)
172     {
173         return pIT;
174     }
175
176     /*Get old SinglePoly*/
177     m_pRealData[_iIdx]->setRank(_pdblCoef->getSize() - 1);
178     m_pRealData[_iIdx]->setCoef(_pdblCoef);
179
180     return this;
181 }
182
183 void Polynom::setZeros()
184 {
185     for (int i = 0; i < m_iSize; i++)
186     {
187         m_pRealData[i]->setZeros();
188     }
189 }
190
191 bool Polynom::getSizes(int *_piSizes)
192 {
193     if (_piSizes == NULL || m_pRealData == NULL)
194     {
195         return false;
196     }
197
198     for (int i = 0 ; i < getSize() ; i++)
199     {
200         _piSizes[i] = m_pRealData[i]->getSize();
201     }
202
203     return true;
204 }
205
206 bool Polynom::getRank(int *_piRank)
207 {
208     if (_piRank == NULL || m_pRealData == NULL)
209     {
210         return false;
211     }
212
213     for (int i = 0 ; i < getSize() ; i++)
214     {
215         _piRank[i] = m_pRealData[i]->getRank();
216     }
217
218     return true;
219 }
220
221 void Polynom::whoAmI(void)
222 {
223     std::cout << "types::SinglePoly";
224 }
225
226 std::wstring& Polynom::getVariableName()
227 {
228     return m_szVarName;
229 }
230
231 void Polynom::setVariableName(const std::wstring& _szVarName)
232 {
233     m_szVarName = _szVarName;
234 }
235
236 bool Polynom::isComplex()
237 {
238     if (m_iSize && m_pRealData[0])
239     {
240         return m_pRealData[0]->isComplex();
241     }
242
243     return false;
244 }
245
246 Polynom* Polynom::setComplex(bool _bComplex)
247 {
248     if (_bComplex == isComplex())
249     {
250         return this;
251     }
252
253     typedef Polynom* (Polynom::*setcplx_t)(bool);
254     Polynom* pIT = checkRef(this, (setcplx_t)&Polynom::setComplex, _bComplex);
255     if (pIT != this)
256     {
257         return pIT;
258     }
259
260     for (int i = 0 ; i < getSize() ; i++)
261     {
262         get(i)->setComplex(_bComplex);
263     }
264
265     return this;
266 }
267
268 Polynom* Polynom::clone()
269 {
270     Polynom* pMP = new Polynom(getVariableName(), getDims(), getDimsArray());
271     for (int i = 0 ; i < getSize() ; i++)
272     {
273         pMP->set(i, m_pRealData[i]);
274     }
275
276     return pMP;
277 }
278
279 bool Polynom::transpose(InternalType *& out)
280 {
281     if (isScalar())
282     {
283         out = clone();
284         return true;
285     }
286
287     if (m_iDims == 2)
288     {
289         int piNewDims[2] = {m_piDims[1], m_piDims[0]};
290         Polynom* pPoly = new Polynom(m_szVarName, m_iDims, piNewDims);
291         Transposition::transpose_clone(getRows(), getCols(), m_pRealData, pPoly->get());
292         out = pPoly;
293         return true;
294     }
295
296     return false;
297
298 }
299
300 bool Polynom::adjoint(InternalType *& out)
301 {
302     if (isComplex())
303     {
304         if (m_iDims == 2)
305         {
306             int piNewDims[2] = {m_piDims[1], m_piDims[0]};
307             Polynom* pPoly = new Polynom(m_szVarName, m_iDims, piNewDims);
308             Transposition::adjoint_clone(getRows(), getCols(), m_pRealData, pPoly->get());
309             out = pPoly;
310             return true;
311         }
312         else
313         {
314             return false;
315         }
316     }
317     else
318     {
319         return transpose(out);
320     }
321 }
322
323 Double* Polynom::evaluate(Double* _pdblValue)
324 {
325     double *pR = _pdblValue->getReal();
326     double *pI = _pdblValue->getImg();
327     int iRows  = _pdblValue->getRows();
328     int iCols  = _pdblValue->getCols();
329
330     double *pReturnR = NULL;
331     double *pReturnI = NULL;
332     Double *pReturn  = new Double(getRows() * iRows, getCols() * iCols, &pReturnR, &pReturnI);
333     pReturn->setComplex(_pdblValue->isComplex());
334
335     int i = 0;
336     //all lines of the matrix remplacement
337     for (int iCol = 0 ; iCol < iCols ; iCol++)
338     {
339         for (int iPolyCol = 0 ; iPolyCol < getCols() ; iPolyCol++)
340         {
341             for (int iRow = 0 ; iRow < iRows ; iRow++)
342             {
343                 for (int iPolyRow = 0 ; iPolyRow < getRows() ; iPolyRow++)
344                 {
345                     double OutR = 0;
346                     double OutI = 0;
347
348                     SinglePoly *pPoly = get(iPolyRow, iPolyCol);
349                     if (pReturn->isComplex())
350                     {
351                         pPoly->evaluate(pR[iCol * iRows + iRow], pI[iCol * iRows + iRow], &OutR, &OutI);
352                         pReturnR[i] = OutR;
353                         pReturnI[i] = OutI;
354                     }
355                     else
356                     {
357                         pPoly->evaluate(pR[iCol * iRows + iRow], 0, &OutR, &OutI);
358                         pReturnR[i] = OutR;
359                     }
360                     i++;
361                 }
362             }
363         }
364     }
365     return pReturn;
366 }
367
368 void Polynom::updateRank(void)
369 {
370     for (int i = 0 ; i < getSize() ; i++)
371     {
372         m_pRealData[i]->updateRank();
373     }
374 }
375
376 int Polynom::getMaxRank(void)
377 {
378     int *piRank = new int[getSize()];
379     getRank(piRank);
380     int iMaxRank = 0;
381     for (int i = 0 ; i < getSize() ; i++)
382     {
383         iMaxRank = std::max(iMaxRank, piRank[i]);
384     }
385     delete[] piRank;
386     return iMaxRank;
387 }
388
389 Double* Polynom::getCoef(void)
390 {
391     int iMaxRank = getMaxRank();
392     int iColsOut = getCols() * (iMaxRank + 1);
393
394     Double *pCoef = new Double(getRows(), iColsOut, isComplex());
395     pCoef->setZeros();
396     double *pCoefR = pCoef->getReal();
397
398     if (isComplex())
399     {
400         double *pCoefI = pCoef->getImg();
401         for (int i = 0 ; i < m_iSize ; i++)
402         {
403             SinglePoly *pPoly = m_pRealData[i];
404             int iSize = pPoly->getSize();
405             double *pR = pPoly->get();
406             double *pI = pPoly->getImg();
407
408             for (int iRank = 0 ; iRank < iSize ; iRank++)
409             {
410                 pCoefR[iRank * m_iSize + i] = pR[iRank];
411                 pCoefI[iRank * m_iSize + i] = pI[iRank];
412             }
413         }
414     }
415     else
416     {
417         for (int i = 0 ; i < m_iSize ; i++)
418         {
419             SinglePoly *pPoly = m_pRealData[i];
420             int iSize = pPoly->getSize();
421             double *pR = pPoly->get();
422             for (int iRank = 0 ; iRank < iSize ; iRank++)
423             {
424                 pCoefR[iRank * m_iSize + i] = pR[iRank];
425             }
426         }
427     }
428
429     return pCoef;
430 }
431
432 Polynom* Polynom::setCoef(Double *_pCoef)
433 {
434     typedef Polynom* (Polynom::*setCoef_t)(Double*);
435     Polynom* pIT = checkRef(this, (setCoef_t)&Polynom::setCoef, _pCoef);
436     if (pIT != this)
437     {
438         return pIT;
439     }
440
441     setComplex(_pCoef->isComplex());
442     double *pR = _pCoef->getReal();
443
444     if (isComplex())
445     {
446         double *pI = _pCoef->getImg();
447         for (int i = 0 ; i < m_iSize ; i++)
448         {
449             SinglePoly *pPoly = m_pRealData[i];
450             int iSize = pPoly->getSize();
451             double* pTempR = pPoly->get();
452             double* pTempI = pPoly->getImg();
453
454             for (int iRank = 0 ; iRank < iSize ; iRank++)
455             {
456                 pTempR[iRank] = pR[iRank * m_iSize + i];
457                 pTempI[iRank] = pI[iRank * m_iSize + i];
458             }
459         }
460     }
461     else
462     {
463         for (int i = 0 ; i < m_iSize ; i++)
464         {
465             SinglePoly *pPoly = m_pRealData[i];
466             int iSize = pPoly->getSize();
467             double* pTempR = pPoly->get();
468
469             for (int iRank = 0 ; iRank < iSize ; iRank++)
470             {
471                 pTempR[iRank] = pR[iRank * m_iSize + i];
472             }
473         }
474     }
475
476     return this;
477 }
478
479 bool Polynom::subMatrixToString(std::wostringstream& ostr, int* _piDims, int _iDims)
480 {
481     std::wostringstream osExp;
482     std::wostringstream osCoef;
483
484     std::list<std::wstring>::const_iterator it_Exp;
485     std::list<std::wstring>::const_iterator it_Coef;
486     std::list<std::wstring> listExpR, listCoefR, listExpI, listCoefI;
487
488
489     if (isScalar())
490     {
491         if (isComplex())
492         {
493             ostr << L"Real part" << std::endl << std::endl << std::endl;
494             get(0)->toStringReal(getVariableName(), &listExpR, &listCoefR);
495             for (it_Coef = listCoefR.begin(), it_Exp = listExpR.begin() ; it_Coef != listCoefR.end() ; it_Coef++, it_Exp++)
496             {
497                 ostr << *it_Exp << std::endl << *it_Coef << std::endl;
498             }
499
500             ostr << L"Imaginary part" << std::endl << std::endl << std::endl ;
501             get(0)->toStringImg(getVariableName(), &listExpI, &listCoefI);
502             for (it_Coef = listCoefI.begin(), it_Exp = listExpI.begin() ; it_Coef != listCoefI.end() ; it_Coef++, it_Exp++)
503             {
504                 ostr << *it_Exp << std::endl << *it_Coef << std::endl;
505             }
506         }
507         else
508         {
509             get(0)->toStringReal(getVariableName(), &listExpR, &listCoefR);
510
511             for (it_Coef = listCoefR.begin(), it_Exp = listExpR.begin() ; it_Coef != listCoefR.end() ; it_Coef++, it_Exp++)
512             {
513                 ostr << *it_Exp << std::endl << *it_Coef << std::endl;
514             }
515         }
516     }
517     else if (getRows() == 1)
518     {
519         if (isComplex())
520         {
521             ostr << L"Real part" << std::endl << std::endl;
522             ostr << getRowString(_piDims, _iDims, false);
523             ostr << L"Imaginary part" << std::endl << std::endl;
524             ostr << getRowString(_piDims, _iDims, true);
525         }
526         else
527         {
528             ostr << getRowString(_piDims, _iDims, false);
529         }
530     }
531     else if (getCols() == 1)
532     {
533         if (isComplex())
534         {
535             ostr << L"Real part" << std::endl << std::endl;
536             ostr << getColString(_piDims, _iDims, false);
537             ostr << L"Imaginary part" << std::endl << std::endl;
538             ostr << getColString(_piDims, _iDims, true);
539         }
540         else
541         {
542             ostr << getColString(_piDims, _iDims, false);
543         }
544     }
545     else
546     {
547         //Matrix
548         if (isComplex())
549         {
550             ostr << L"Real part" << std::endl << std::endl;
551             ostr << getMatrixString(_piDims, _iDims, false);
552             ostr << L"Imaginary part" << std::endl << std::endl;
553             ostr << getMatrixString(_piDims, _iDims, true);
554         }
555         else
556         {
557             ostr << getMatrixString(_piDims, _iDims, false);
558         }
559     }
560     return true;
561 }
562
563 std::wstring Polynom::getMatrixString(int* _piDims, int /*_iDims*/, bool _bComplex)
564 {
565     int iLineLen = ConfigVariable::getConsoleWidth();
566
567     std::wostringstream ostr;
568     std::wostringstream osExp;
569     std::wostringstream osCoef;
570
571     std::list<std::wstring>::const_iterator it_Exp;
572     std::list<std::wstring>::const_iterator it_Coef;
573     std::list<std::wstring> listExpR, listCoefR, listExpI, listCoefI;
574
575     int iLen        = 0;
576     int iLastCol    = 0;
577     bool bWordWarp  = false;
578
579     std::wstring szExp, szCoef;
580
581
582     int *piMaxLen = new int[abs(getCols())];
583     memset(piMaxLen, 0x00, sizeof(int) * abs(getCols()));
584
585     //find the largest row for each col
586     for (int iCols1 = 0 ; iCols1 < abs(getCols()) ; iCols1++)
587     {
588         for (int iRows1 = 0 ; iRows1 < abs(getRows()) ; iRows1++)
589         {
590             int iLength = 0;
591             _piDims[0] = iRows1;
592             _piDims[1] = iCols1;
593             int iPos = getIndex(_piDims);
594             if (_bComplex)
595             {
596                 get(iPos)->toStringImg(getVariableName(), &listExpR, &listCoefR);
597             }
598             else
599             {
600                 get(iPos)->toStringReal(getVariableName(), &listExpR, &listCoefR);
601             }
602
603             if (listExpR.size() > 1)
604             {
605                 for (it_Exp = listExpR.begin() ; it_Exp != listExpR.end() ; it_Exp++)
606                 {
607                     iLength += static_cast<int>((*it_Exp).size());
608                 }
609             }
610             else
611             {
612                 if (listExpR.front().size() != 0)
613                 {
614                     iLength = static_cast<int>(listExpR.front().size());
615                 }
616                 else
617                 {
618                     iLength = static_cast<int>(listCoefR.front().size());
619                 }
620             }
621             piMaxLen[iCols1] = std::min(std::max(piMaxLen[iCols1], iLength), iLineLen);
622             listExpR.clear();
623             listCoefR.clear();
624         }
625
626         //We know the length of the column
627         if (static_cast<int>(iLen + piMaxLen[iCols1]) >= iLineLen && iLen != 0)
628         {
629             //if the max length exceeded
630             std::wostringstream ostemp;
631             bWordWarp = true;
632             for (int iRows2 = 0 ; iRows2 < abs(getRows()) ; iRows2++)
633             {
634                 bool bMultiLine = false;
635                 for (int iCols2 = iLastCol ; iCols2 < iCols1; iCols2++)
636                 {
637                     _piDims[0] = iRows2;
638                     _piDims[1] = iCols2;
639
640                     int iPos = getIndex(_piDims);
641                     if (_bComplex)
642                     {
643                         get(iPos)->toStringImg(getVariableName(), &listExpR, &listCoefR);
644                     }
645                     else
646                     {
647                         get(iPos)->toStringReal(getVariableName(), &listExpR, &listCoefR);
648                     }
649
650                     if (listCoefR.size() > 1)
651                     {
652                         for (it_Coef = listCoefR.begin(), it_Exp = listExpR.begin() ; it_Coef != listCoefR.end() ; it_Coef++, it_Exp++)
653                         {
654                             osExp << *it_Exp;
655                             addSpaces(&osExp, piMaxLen[iCols2] - static_cast<int>((*it_Exp).size()));
656                             osExp << std::endl;
657                             osExp << *it_Coef;
658                             addSpaces(&osExp, piMaxLen[iCols2] - static_cast<int>((*it_Coef).size()));
659                             osExp << std::endl;
660                             bMultiLine = true;
661                         }
662                     }
663                     else
664                     {
665
666                         osExp << listExpR.front();
667                         addSpaces(&osExp, piMaxLen[iCols2] - static_cast<int>(listExpR.front().size()));
668                         osCoef << listCoefR.front();
669                         addSpaces(&osCoef, piMaxLen[iCols2] - static_cast<int>(listCoefR.front().size()));
670                         bMultiLine = false;
671                     }
672                     listExpR.clear();
673                     listCoefR.clear();
674                 }
675
676                 if (bMultiLine == false)
677                 {
678                     osExp << std::endl;
679                     osCoef << std::endl;
680                 }
681                 ostemp << osExp.str();
682                 ostemp << osCoef.str() << std::endl;
683                 osExp.str(L"");
684                 osCoef.str(L"");
685
686             }
687             iLen    = piMaxLen[iCols1];
688
689             //write "column x to y"
690             addColumnString(ostr, iLastCol + 1, iCols1);
691             ostr << ostemp.str() << std::endl;
692
693             iLastCol = iCols1;
694         }
695         else //if((int)(iLen + piMaxLen[iCols1]) <= iLineLen)
696         {
697             iLen += piMaxLen[iCols1];
698         }
699     }//for(int iCols1 = 0 ; iCols1 < getCols() ; iCols1++)
700
701     if (bWordWarp)
702     {
703         addColumnString(ostr, iLastCol + 1, getCols());
704     }
705
706     //print the end
707     for (int iRows2 = 0 ; iRows2 < abs(getRows()) ; iRows2++)
708     {
709         for (int iCols2 = iLastCol ; iCols2 < abs(getCols()) ; iCols2++)
710         {
711             _piDims[0] = iRows2;
712             _piDims[1] = iCols2;
713
714             int iPos = getIndex(_piDims);
715             if (_bComplex)
716             {
717                 get(iPos)->toStringImg( getVariableName(), &listExpR, &listCoefR);
718             }
719             else
720             {
721                 get(iPos)->toStringReal(getVariableName(), &listExpR, &listCoefR);
722             }
723
724             if (listCoefR.size() > 1)
725             {
726                 for (it_Coef = listCoefR.begin(), it_Exp = listExpR.begin() ; it_Coef != listCoefR.end() ; it_Coef++, it_Exp++)
727                 {
728                     //normally useless ...
729                     osExp << *it_Exp;
730                     addSpaces(&osExp, piMaxLen[iCols2] - static_cast<int>((*it_Exp).size()));
731                     osExp << std::endl;
732
733                     osExp << *it_Coef;
734                     addSpaces(&osExp, piMaxLen[iCols2] - static_cast<int>((*it_Coef).size()));
735                     osExp << std::endl;
736                 }
737             }
738             else
739             {
740                 if (listExpR.front().size() != 0)
741                 {
742                     osExp << listExpR.front();
743                 }
744
745                 addSpaces(&osExp, piMaxLen[iCols2] - static_cast<int>(listExpR.front().size()));
746                 osCoef << listCoefR.front();
747                 addSpaces(&osCoef, piMaxLen[iCols2] - static_cast<int>(listCoefR.front().size()));
748             }
749             listExpR.clear();
750             listCoefR.clear();
751         }
752
753         if (osExp.str().size() != 0)
754         {
755             osExp << std::endl;
756         }
757         osCoef << std::endl;
758         if (isIdentity())
759         {
760             ostr << L"eye *" << std::endl << std::endl;
761         }
762         ostr << osExp.str();
763         ostr << osCoef.str() << std::endl;
764         osExp.str(L"");
765         osCoef.str(L"");
766     }
767
768     delete[] piMaxLen;
769     return ostr.str();
770 }
771
772 std::wstring Polynom::getRowString(int* _piDims, int /*_iDims*/, bool _bComplex)
773 {
774     int iLineLen = ConfigVariable::getConsoleWidth();
775
776     int iLen        = 0;
777     int iLastFlush  = 0;
778
779     std::wostringstream ostr;
780     std::wostringstream osExp;
781     std::wostringstream osCoef;
782
783     std::list<std::wstring>::const_iterator it_Exp;
784     std::list<std::wstring>::const_iterator it_Coef;
785     std::list<std::wstring> listExpR, listCoefR, listExpI, listCoefI;
786
787     for (int i = 0 ; i < getCols() ; i++)
788     {
789         std::wstring szExp, szCoef;
790
791         _piDims[1] = 0;
792         _piDims[0] = i;
793         int iPos = getIndex(_piDims);
794         if (_bComplex)
795         {
796             get(iPos)->toStringImg(getVariableName(), &listExpR, &listCoefR);
797         }
798         else
799         {
800             get(iPos)->toStringReal(getVariableName(), &listExpR, &listCoefR);
801         }
802
803         if (iLen != 0 && static_cast<int>(listExpR.front().size()) + iLen >= iLineLen - 1)
804         {
805             //flush strean
806             addColumnString(ostr, iLastFlush + 1, i);
807             iLastFlush = i;
808             iLen = 0;
809             ostr << osExp.str() << std::endl;
810             ostr << osCoef.str() << std::endl;
811             osExp.str(L" ");
812             osCoef.str(L" ");
813         }
814
815         if (listCoefR.size() > 1)
816         {
817             for (it_Coef = listCoefR.begin(), it_Exp = listExpR.begin() ; it_Coef != listCoefR.end() ; it_Coef++, it_Exp++)
818             {
819                 osExp << *it_Exp << std::endl << *it_Coef << std::endl;
820             }
821         }
822         else
823         {
824             osExp << listExpR.front();
825             osCoef << listCoefR.front();
826         }
827
828         if (osExp.str().size() != 0)
829         {
830             iLen = static_cast<int>(osExp.str().size());
831         }
832         else
833         {
834             iLen = static_cast<int>(osCoef.str().size());
835         }
836
837         listCoefR.clear();
838         listExpR.clear();
839     }
840
841     if (iLastFlush != 0)
842     {
843         //last line of a multiline output
844         addColumnString(ostr, iLastFlush + 1, getSize());
845     }
846     ostr << osExp.str() << std::endl;
847     ostr << osCoef.str() << std::endl;
848     return ostr.str();
849 }
850
851 std::wstring Polynom::getColString(int* _piDims, int /*_iDims*/, bool _bComplex)
852 {
853     std::wostringstream ostr;
854     std::wostringstream osExp;
855     std::wostringstream osCoef;
856
857     std::list<std::wstring>::const_iterator it_Exp;
858     std::list<std::wstring>::const_iterator it_Coef;
859     std::list<std::wstring> listExpR, listCoefR, listExpI, listCoefI;
860
861     for (int i = 0 ; i < getRows() ; i++)
862     {
863         std::wstring szExp, szCoef;
864
865         _piDims[0] = i;
866         _piDims[1] = 0;
867         int iPos = getIndex(_piDims);
868         if (_bComplex)
869         {
870             get(iPos)->toStringImg(getVariableName(), &listExpR, &listCoefR);
871         }
872         else
873         {
874             get(iPos)->toStringReal(getVariableName(), &listExpR, &listCoefR);
875         }
876
877         for (it_Coef = listCoefR.begin(), it_Exp = listExpR.begin() ; it_Coef != listCoefR.end() ; it_Coef++, it_Exp++)
878         {
879             ostr << *it_Exp << std::endl << *it_Coef << std::endl;
880         }
881         ostr << std::endl;
882         listCoefR.clear();
883         listExpR.clear();
884     }
885     return ostr.str();
886 }
887
888 Double* Polynom::extractCoef(int _iRank)
889 {
890     Double *pdbl = new Double(getRows(), getCols(), isComplex());
891     pdbl->setZeros();
892     double *pReal = pdbl->getReal();
893
894     if (isComplex())
895     {
896         double *pImg = pdbl->getImg();
897         for (int i = 0 ; i < getSize() ; i++)
898         {
899             SinglePoly *pPoly = m_pRealData[i];
900             if (pPoly->getRank() >= _iRank)
901             {
902                 pReal[i] = pPoly->get()[_iRank];
903                 pImg[i]  = pPoly->getImg()[_iRank];
904             }
905         }
906     }
907     else
908     {
909         for (int i = 0 ; i < getSize() ; i++)
910         {
911             SinglePoly *pPoly = m_pRealData[i];
912             if (pPoly->getRank() >= _iRank)
913             {
914                 pReal[i] = pPoly->get()[_iRank];
915             }
916         }
917     }
918
919     return pdbl;
920 }
921
922 bool Polynom::insertCoef(int _iRank, Double* _pCoef)
923 {
924     double *pReal = _pCoef->getReal();
925     if (isComplex())
926     {
927         double *pImg  = _pCoef->getImg();
928         for (int i = 0 ; i < getSize() ; i++)
929         {
930             SinglePoly *pPoly = m_pRealData[i];
931             if (pPoly->getRank() <= _iRank)
932             {
933                 return false;
934             }
935
936             pPoly->get()[_iRank] = pReal[i];
937             pPoly->getImg()[_iRank] = pImg[i];
938         }
939     }
940     else
941     {
942         for (int i = 0 ; i < getSize() ; i++)
943         {
944             SinglePoly *pPoly = m_pRealData[i];
945             if (pPoly->getRank() <= _iRank)
946             {
947                 return false;
948             }
949
950             pPoly->get()[_iRank] = pReal[i];
951         }
952     }
953
954     return true;
955 }
956
957 bool Polynom::operator==(const InternalType& it)
958 {
959     if (const_cast<InternalType &>(it).isPoly() == false)
960     {
961         return false;
962     }
963
964     Polynom* pM = const_cast<InternalType &>(it).getAs<types::Polynom>();
965
966     if (pM->getRows() != getRows() || pM->getCols() != getCols())
967     {
968         return false;
969     }
970
971     for (int i = 0 ; i < getSize() ; i++)
972     {
973         SinglePoly* p1 = get(i);
974         SinglePoly* p2 = pM->get(i);
975
976         if (*p1 != *p2)
977         {
978             return false;
979         }
980     }
981     return true;
982 }
983
984 bool Polynom::operator!=(const InternalType& it)
985 {
986     return !(*this == it);
987 }
988
989 SinglePoly* Polynom::getNullValue()
990 {
991     return new SinglePoly();
992 }
993
994 Polynom* Polynom::createEmpty(int _iDims, int* _piDims, bool /*_bComplex*/)
995 {
996     return new Polynom(getVariableName(), _iDims, _piDims, NULL);
997 }
998
999 SinglePoly* Polynom::copyValue(SinglePoly* _pData)
1000 {
1001     if (_pData == NULL)
1002     {
1003         return NULL;
1004     }
1005     return _pData->clone();
1006 }
1007
1008 void Polynom::deleteAll()
1009 {
1010     for (int i = 0 ; i < m_iSizeMax ; i++)
1011     {
1012         m_pRealData[i]->killMe();
1013     }
1014     delete[] m_pRealData;
1015     m_pRealData = NULL;
1016     deleteImg();
1017 }
1018
1019 void Polynom::deleteImg()
1020 {
1021
1022 }
1023
1024 SinglePoly** Polynom::allocData(int _iSize)
1025 {
1026     SinglePoly** pData = new SinglePoly*[_iSize];
1027     memset(pData, 0x00, _iSize * sizeof(SinglePoly*));
1028     return pData;
1029 }
1030
1031 void Polynom::deleteData(SinglePoly* data)
1032 {
1033     if (data)
1034     {
1035         data->killMe();
1036     }
1037 }
1038
1039 //overload to check variable name and call arrayof<>::insert after
1040 Polynom* Polynom::insert(typed_list* _pArgs, InternalType* _pSource)
1041 {
1042     Polynom* p = _pSource->getAs<Polynom>();
1043     if (p->getVariableName() != getVariableName())
1044     {
1045         char szError[512];
1046         os_sprintf(szError, _("Input arguments should have the same formal variable name.\n"));
1047         wchar_t* pwstError = to_wide_string(szError);
1048         std::wstring wstError(pwstError);
1049         FREE(pwstError);
1050         throw ast::InternalError(wstError);
1051     }
1052
1053     return ArrayOf<SinglePoly*>::insert(_pArgs, _pSource)->getAs<Polynom>();
1054 }
1055
1056 Polynom* Polynom::Dollar()
1057 {
1058     int iRank = 1;
1059     Polynom* pDollar = new Polynom(L"$", 1, 1, &iRank);
1060     double* pdblCoef = pDollar->get(0)->get();
1061     pdblCoef[0] = 0;
1062     pdblCoef[1] = 1;
1063
1064     return pDollar;
1065 }
1066
1067 bool Polynom::isDollar()
1068 {
1069     if (m_szVarName != L"$" || getSize() != 1)
1070     {
1071         return false;
1072     }
1073
1074     double* pCoef = get(0)->get();
1075
1076     if (pCoef[0] != 0 && pCoef[1] != 1)
1077     {
1078         return false;
1079     }
1080
1081     return true;
1082 }
1083
1084 }
1085