* Bug 16263 fixed: insertion in complex polynomial is repaired
[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         for (int i = 0 ; i < getSize() ; i++)
239         {
240             if  (m_pRealData[i] && m_pRealData[i]->isComplex())
241             {
242                 return true;
243             }
244         }
245         return false;
246 }
247
248 Polynom* Polynom::setComplex(bool _bComplex)
249 {
250     if (_bComplex == isComplex())
251     {
252         return this;
253     }
254
255     typedef Polynom* (Polynom::*setcplx_t)(bool);
256     Polynom* pIT = checkRef(this, (setcplx_t)&Polynom::setComplex, _bComplex);
257     if (pIT != this)
258     {
259         return pIT;
260     }
261
262     for (int i = 0 ; i < getSize() ; i++)
263     {
264         get(i)->setComplex(_bComplex);
265     }
266
267     return this;
268 }
269
270 Polynom* Polynom::clone()
271 {
272     Polynom* pMP = new Polynom(getVariableName(), getDims(), getDimsArray());
273     for (int i = 0 ; i < getSize() ; i++)
274     {
275         pMP->set(i, m_pRealData[i]);
276     }
277
278     return pMP;
279 }
280
281 bool Polynom::transpose(InternalType *& out)
282 {
283     if (isScalar())
284     {
285         out = clone();
286         return true;
287     }
288
289     if (m_iDims == 2)
290     {
291         int piNewDims[2] = {m_piDims[1], m_piDims[0]};
292         Polynom* pPoly = new Polynom(m_szVarName, m_iDims, piNewDims);
293         Transposition::transpose_clone(getRows(), getCols(), m_pRealData, pPoly->get());
294         out = pPoly;
295         return true;
296     }
297
298     return false;
299
300 }
301
302 bool Polynom::adjoint(InternalType *& out)
303 {
304     if (isComplex())
305     {
306         if (m_iDims == 2)
307         {
308             int piNewDims[2] = {m_piDims[1], m_piDims[0]};
309             Polynom* pPoly = new Polynom(m_szVarName, m_iDims, piNewDims);
310             Transposition::adjoint_clone(getRows(), getCols(), m_pRealData, pPoly->get());
311             out = pPoly;
312             return true;
313         }
314         else
315         {
316             return false;
317         }
318     }
319     else
320     {
321         return transpose(out);
322     }
323 }
324
325 Double* Polynom::evaluate(Double* _pdblValue)
326 {
327     double *pR = _pdblValue->getReal();
328     double *pI = _pdblValue->getImg();
329     int iRows  = _pdblValue->getRows();
330     int iCols  = _pdblValue->getCols();
331
332     double *pReturnR = NULL;
333     double *pReturnI = NULL;
334     Double *pReturn  = new Double(getRows() * iRows, getCols() * iCols, &pReturnR, &pReturnI);
335     pReturn->setComplex(_pdblValue->isComplex());
336
337     int i = 0;
338     //all lines of the matrix remplacement
339     for (int iCol = 0 ; iCol < iCols ; iCol++)
340     {
341         for (int iPolyCol = 0 ; iPolyCol < getCols() ; iPolyCol++)
342         {
343             for (int iRow = 0 ; iRow < iRows ; iRow++)
344             {
345                 for (int iPolyRow = 0 ; iPolyRow < getRows() ; iPolyRow++)
346                 {
347                     double OutR = 0;
348                     double OutI = 0;
349
350                     SinglePoly *pPoly = get(iPolyRow, iPolyCol);
351                     if (pReturn->isComplex())
352                     {
353                         pPoly->evaluate(pR[iCol * iRows + iRow], pI[iCol * iRows + iRow], &OutR, &OutI);
354                         pReturnR[i] = OutR;
355                         pReturnI[i] = OutI;
356                     }
357                     else
358                     {
359                         pPoly->evaluate(pR[iCol * iRows + iRow], 0, &OutR, &OutI);
360                         pReturnR[i] = OutR;
361                     }
362                     i++;
363                 }
364             }
365         }
366     }
367     return pReturn;
368 }
369
370 void Polynom::updateRank(void)
371 {
372     for (int i = 0 ; i < getSize() ; i++)
373     {
374         m_pRealData[i]->updateRank();
375     }
376 }
377
378 int Polynom::getMaxRank(void)
379 {
380     int *piRank = new int[getSize()];
381     getRank(piRank);
382     int iMaxRank = 0;
383     for (int i = 0 ; i < getSize() ; i++)
384     {
385         iMaxRank = std::max(iMaxRank, piRank[i]);
386     }
387     delete[] piRank;
388     return iMaxRank;
389 }
390
391 Double* Polynom::getCoef(void)
392 {
393     int iMaxRank = getMaxRank();
394     int iColsOut = getCols() * (iMaxRank + 1);
395
396     Double *pCoef = new Double(getRows(), iColsOut, isComplex());
397     pCoef->setZeros();
398     double *pCoefR = pCoef->getReal();
399
400     if (isComplex())
401     {
402         double *pCoefI = pCoef->getImg();
403         for (int i = 0 ; i < m_iSize ; i++)
404         {
405             SinglePoly *pPoly = m_pRealData[i];
406             int iSize = pPoly->getSize();
407             double *pR = pPoly->get();
408             double *pI = pPoly->getImg();
409
410             for (int iRank = 0 ; iRank < iSize ; iRank++)
411             {
412                 pCoefR[iRank * m_iSize + i] = pR[iRank];
413                 pCoefI[iRank * m_iSize + i] = pI[iRank];
414             }
415         }
416     }
417     else
418     {
419         for (int i = 0 ; i < m_iSize ; i++)
420         {
421             SinglePoly *pPoly = m_pRealData[i];
422             int iSize = pPoly->getSize();
423             double *pR = pPoly->get();
424             for (int iRank = 0 ; iRank < iSize ; iRank++)
425             {
426                 pCoefR[iRank * m_iSize + i] = pR[iRank];
427             }
428         }
429     }
430
431     return pCoef;
432 }
433
434 Polynom* Polynom::setCoef(Double *_pCoef)
435 {
436     typedef Polynom* (Polynom::*setCoef_t)(Double*);
437     Polynom* pIT = checkRef(this, (setCoef_t)&Polynom::setCoef, _pCoef);
438     if (pIT != this)
439     {
440         return pIT;
441     }
442
443     setComplex(_pCoef->isComplex());
444     double *pR = _pCoef->getReal();
445
446     if (isComplex())
447     {
448         double *pI = _pCoef->getImg();
449         for (int i = 0 ; i < m_iSize ; i++)
450         {
451             SinglePoly *pPoly = m_pRealData[i];
452             int iSize = pPoly->getSize();
453             double* pTempR = pPoly->get();
454             double* pTempI = pPoly->getImg();
455
456             for (int iRank = 0 ; iRank < iSize ; iRank++)
457             {
458                 pTempR[iRank] = pR[iRank * m_iSize + i];
459                 pTempI[iRank] = pI[iRank * m_iSize + i];
460             }
461         }
462     }
463     else
464     {
465         for (int i = 0 ; i < m_iSize ; i++)
466         {
467             SinglePoly *pPoly = m_pRealData[i];
468             int iSize = pPoly->getSize();
469             double* pTempR = pPoly->get();
470
471             for (int iRank = 0 ; iRank < iSize ; iRank++)
472             {
473                 pTempR[iRank] = pR[iRank * m_iSize + i];
474             }
475         }
476     }
477
478     return this;
479 }
480
481 bool Polynom::subMatrixToString(std::wostringstream& ostr, int* _piDims, int _iDims)
482 {
483     std::wostringstream osExp;
484     std::wostringstream osPoly;
485
486     std::list<std::wstring>::const_iterator it_Exp;
487     std::list<std::wstring>::const_iterator it_Coef;
488     std::list<std::wstring> listExpR, listWstPoly, listExpI, listCoefI;
489
490     //Matrix
491     if (isComplex())
492     {
493         ostr << L"Real part" << std::endl << std::endl;
494         ostr << getMatrixString(_piDims, _iDims, false);
495         ostr << L"Imaginary part" << std::endl << std::endl;
496         ostr << getMatrixString(_piDims, _iDims, true);
497     }
498     else
499     {
500         ostr << getMatrixString(_piDims, _iDims, false);
501     }
502     return true;
503 }
504
505 std::wstring Polynom::getMatrixString(int* _piDims, int /*_iDims*/, bool _bComplex)
506 {
507     int iLineLen = ConfigVariable::getConsoleWidth();
508
509     std::wostringstream ostr;
510     std::wostringstream osPoly;
511
512     std::list<std::wstring>::const_iterator it_Coef;
513     std::list<std::wstring> listWstPoly;
514
515     int iLen        = 0;
516     int iLastCol    = 0;
517     bool bWordWarp  = false;
518
519     int *piMaxLen = new int[abs(getCols())];
520     memset(piMaxLen, 0x00, sizeof(int) * abs(getCols()));
521
522     //find the largest row for each col
523     for (int iCols1 = 0 ; iCols1 < abs(getCols()) ; iCols1++)
524     {
525         for (int iRows1 = 0 ; iRows1 < abs(getRows()) ; iRows1++)
526         {
527             int iLength = 0;
528             _piDims[0] = iRows1;
529             _piDims[1] = iCols1;
530             int iPos = getIndex(_piDims);
531             if (_bComplex)
532             {
533                 get(iPos)->toStringImg(getVariableName(), &listWstPoly);
534             }
535             else
536             {
537                 get(iPos)->toStringReal(getVariableName(), &listWstPoly);
538             }
539
540             for (auto it : listWstPoly)
541             {
542                 iLength += static_cast<int>(it.size());
543             }
544             piMaxLen[iCols1] = std::min(std::max(piMaxLen[iCols1], iLength), iLineLen);
545             listWstPoly.clear();
546         }
547
548         //We know the length of the column
549         if (static_cast<int>(iLen + piMaxLen[iCols1]) >= iLineLen && iLen != 0)
550         {
551             //if the max length exceeded
552             std::wostringstream ostemp;
553             bWordWarp = true;
554             for (int iRows2 = 0 ; iRows2 < abs(getRows()) ; iRows2++)
555             {
556                 bool bMultiLine = false;
557                 for (int iCols2 = iLastCol ; iCols2 < iCols1; iCols2++)
558                 {
559                     _piDims[0] = iRows2;
560                     _piDims[1] = iCols2;
561
562                     int iPos = getIndex(_piDims);
563                     if (_bComplex)
564                     {
565                         get(iPos)->toStringImg(getVariableName(),  &listWstPoly);
566                     }
567                     else
568                     {
569                         get(iPos)->toStringReal(getVariableName(),  &listWstPoly);
570                     }
571
572                     if (listWstPoly.size() > 1)
573                     {
574                         for (auto it : listWstPoly)
575                         {
576                             osPoly << it << std::endl;
577                             bMultiLine = true;
578                         }
579                     }
580                     else
581                     {
582                         osPoly << listWstPoly.front();
583                         addSpaces(&osPoly, piMaxLen[iCols2] - static_cast<int>(listWstPoly.front().size()));
584                         bMultiLine = false;
585                     }
586                     listWstPoly.clear();
587                 }
588
589                 if (bMultiLine == false)
590                 {
591                     osPoly << std::endl;
592                 }
593                 ostemp << osPoly.str() << std::endl;
594                 osPoly.str(L"");
595
596             }
597             iLen = piMaxLen[iCols1];
598
599             //write "column x to y"
600             addColumnString(ostr, iLastCol + 1, iCols1);
601             ostr << ostemp.str() << std::endl;
602
603             iLastCol = iCols1;
604         }
605         else //if((int)(iLen + piMaxLen[iCols1]) <= iLineLen)
606         {
607             iLen += piMaxLen[iCols1];
608         }
609     }//for(int iCols1 = 0 ; iCols1 < getCols() ; iCols1++)
610
611     if (bWordWarp)
612     {
613         addColumnString(ostr, iLastCol + 1, getCols());
614     }
615
616     //print the end
617     for (int iRows2 = 0 ; iRows2 < abs(getRows()) ; iRows2++)
618     {
619         for (int iCols2 = iLastCol ; iCols2 < abs(getCols()) ; iCols2++)
620         {
621             _piDims[0] = iRows2;
622             _piDims[1] = iCols2;
623
624             int iPos = getIndex(_piDims);
625             if (_bComplex)
626             {
627                 get(iPos)->toStringImg(getVariableName(), &listWstPoly);
628             }
629             else
630             {
631                 get(iPos)->toStringReal(getVariableName(), &listWstPoly);
632             }
633
634             if (listWstPoly.size() > 1)
635             {
636                 for (auto it : listWstPoly)
637                 {
638                     osPoly << it << std::endl;
639                 }
640             }
641             else
642             {
643                 osPoly << listWstPoly.front();
644                 addSpaces(&osPoly, piMaxLen[iCols2] - static_cast<int>(listWstPoly.front().size()));
645             }
646             listWstPoly.clear();
647         }
648
649         osPoly << std::endl;
650         if (isIdentity())
651         {
652             ostr << L"eye *" << std::endl << std::endl;
653         }
654         ostr << osPoly.str() << std::endl;
655         osPoly.str(L"");
656     }
657
658     delete[] piMaxLen;
659     return ostr.str();
660 }
661
662
663 Double* Polynom::extractCoef(int _iRank)
664 {
665     Double *pdbl = new Double(getRows(), getCols(), isComplex());
666     pdbl->setZeros();
667     double *pReal = pdbl->getReal();
668
669     if (isComplex())
670     {
671         double *pImg = pdbl->getImg();
672         for (int i = 0 ; i < getSize() ; i++)
673         {
674             SinglePoly *pPoly = m_pRealData[i];
675             if (pPoly->getRank() >= _iRank)
676             {
677                 pReal[i] = pPoly->get()[_iRank];
678                 pImg[i]  = pPoly->getImg()[_iRank];
679             }
680         }
681     }
682     else
683     {
684         for (int i = 0 ; i < getSize() ; i++)
685         {
686             SinglePoly *pPoly = m_pRealData[i];
687             if (pPoly->getRank() >= _iRank)
688             {
689                 pReal[i] = pPoly->get()[_iRank];
690             }
691         }
692     }
693
694     return pdbl;
695 }
696
697 bool Polynom::insertCoef(int _iRank, Double* _pCoef)
698 {
699     double *pReal = _pCoef->getReal();
700     if (isComplex())
701     {
702         double *pImg  = _pCoef->getImg();
703         for (int i = 0 ; i < getSize() ; i++)
704         {
705             SinglePoly *pPoly = m_pRealData[i];
706             if (pPoly->getRank() <= _iRank)
707             {
708                 return false;
709             }
710
711             pPoly->get()[_iRank] = pReal[i];
712             pPoly->getImg()[_iRank] = pImg[i];
713         }
714     }
715     else
716     {
717         for (int i = 0 ; i < getSize() ; i++)
718         {
719             SinglePoly *pPoly = m_pRealData[i];
720             if (pPoly->getRank() <= _iRank)
721             {
722                 return false;
723             }
724
725             pPoly->get()[_iRank] = pReal[i];
726         }
727     }
728
729     return true;
730 }
731
732 bool Polynom::operator==(const InternalType& it)
733 {
734     if (const_cast<InternalType &>(it).isPoly() == false)
735     {
736         return false;
737     }
738
739     Polynom* pM = const_cast<InternalType &>(it).getAs<types::Polynom>();
740
741     if (pM->getRows() != getRows() || pM->getCols() != getCols())
742     {
743         return false;
744     }
745
746     for (int i = 0 ; i < getSize() ; i++)
747     {
748         SinglePoly* p1 = get(i);
749         SinglePoly* p2 = pM->get(i);
750
751         if (*p1 != *p2)
752         {
753             return false;
754         }
755     }
756     return true;
757 }
758
759 bool Polynom::operator!=(const InternalType& it)
760 {
761     return !(*this == it);
762 }
763
764 SinglePoly* Polynom::getNullValue()
765 {
766     return new SinglePoly();
767 }
768
769 Polynom* Polynom::createEmpty(int _iDims, int* _piDims, bool /*_bComplex*/)
770 {
771     return new Polynom(getVariableName(), _iDims, _piDims, NULL);
772 }
773
774 SinglePoly* Polynom::copyValue(SinglePoly* _pData)
775 {
776     if (_pData == NULL)
777     {
778         return NULL;
779     }
780     return _pData->clone();
781 }
782
783 void Polynom::deleteAll()
784 {
785     for (int i = 0 ; i < m_iSizeMax ; i++)
786     {
787         m_pRealData[i]->killMe();
788     }
789     delete[] m_pRealData;
790     m_pRealData = NULL;
791     deleteImg();
792 }
793
794 void Polynom::deleteImg()
795 {
796
797 }
798
799 SinglePoly** Polynom::allocData(int _iSize)
800 {
801     SinglePoly** pData = new SinglePoly*[_iSize];
802     memset(pData, 0x00, _iSize * sizeof(SinglePoly*));
803     return pData;
804 }
805
806 void Polynom::deleteData(SinglePoly* data)
807 {
808     if (data)
809     {
810         data->killMe();
811     }
812 }
813
814 //overload to check variable name and call arrayof<>::insert after
815 Polynom* Polynom::insert(typed_list* _pArgs, InternalType* _pSource)
816 {
817     Polynom* p = _pSource->getAs<Polynom>();
818     if (p->getVariableName() != getVariableName())
819     {
820         char szError[512];
821         os_sprintf(szError, _("Input arguments should have the same formal variable name.\n"));
822         wchar_t* pwstError = to_wide_string(szError);
823         std::wstring wstError(pwstError);
824         FREE(pwstError);
825         throw ast::InternalError(wstError);
826     }
827
828     return ArrayOf<SinglePoly*>::insert(_pArgs, _pSource)->getAs<Polynom>();
829 }
830
831 Polynom* Polynom::Dollar()
832 {
833     int iRank = 1;
834     Polynom* pDollar = new Polynom(L"$", 1, 1, &iRank);
835     double* pdblCoef = pDollar->get(0)->get();
836     pdblCoef[0] = 0;
837     pdblCoef[1] = 1;
838
839     return pDollar;
840 }
841
842 bool Polynom::isDollar()
843 {
844     if (m_szVarName != L"$" || getSize() != 1)
845     {
846         return false;
847     }
848
849     double* pCoef = get(0)->get();
850
851     if (pCoef[0] != 0 && pCoef[1] != 1)
852     {
853         return false;
854     }
855
856     return true;
857 }
858
859 }
860