for no display the zeros in a polynom
[scilab.git] / scilab / modules / ast / src / cpp / types / singlepoly.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 #include <sstream>
13 #include <math.h>
14 #include "singlepoly.hxx"
15 #include "double.hxx"
16 #include "tostring_common.hxx"
17 #include "configvariable.hxx"
18 #include "scilabWrite.hxx"
19
20 extern "C"
21 {
22 #include "log.h"
23 #include "exp.h"
24 #include "elem_common.h"
25 }
26
27 using namespace std;
28
29 namespace types
30 {
31 SinglePoly::SinglePoly()
32 {
33     double* pdblCoefR = NULL;
34     int piDims[2] = {1, 1};
35     create(piDims, 2, &pdblCoefR, NULL);
36     pdblCoefR[0] = 0;
37 #ifndef NDEBUG
38     Inspector::addItem(this);
39 #endif
40 }
41
42 SinglePoly::SinglePoly(double** _pdblCoefR, int _iRank)
43 {
44     int piDims[2] = {_iRank + 1, 1};
45     create(piDims, 2, _pdblCoefR, NULL);
46 #ifndef NDEBUG
47     Inspector::addItem(this);
48 #endif
49 }
50
51 SinglePoly::SinglePoly(double** _pdblCoefR, double** _pdblCoefI, int _iRank)
52 {
53     int piDims[2] = {_iRank + 1, 1};
54     create(piDims, 2, _pdblCoefR, _pdblCoefI);
55 #ifndef NDEBUG
56     Inspector::addItem(this);
57 #endif
58 }
59
60 SinglePoly::~SinglePoly()
61 {
62     deleteAll();
63 #ifndef NDEBUG
64     Inspector::removeItem(this);
65 #endif
66 }
67
68 void SinglePoly::deleteAll()
69 {
70     delete[] m_pRealData;
71     m_pRealData = NULL;
72     deleteImg();
73 }
74
75 void SinglePoly::deleteImg()
76 {
77     if (m_pImgData != NULL)
78     {
79         delete[] m_pImgData;
80         m_pImgData = NULL;
81     }
82 }
83
84 double SinglePoly::getNullValue()
85 {
86     return 0;
87 }
88
89 SinglePoly* SinglePoly::createEmpty(int /*_iDims*/, int* _piDims, bool _bComplex)
90 {
91     double* pdblData = NULL;
92     SinglePoly* pSP = new SinglePoly(&pdblData, _piDims[0] - 1);
93     pSP->setComplex(_bComplex);
94
95     return pSP;
96 }
97
98 double* SinglePoly::allocData(int _iSize)
99 {
100     double* pDbl = NULL;
101     try
102     {
103         if (_iSize < 0)
104         {
105             m_pRealData = NULL;
106             m_pImgData = NULL;
107             char message[bsiz];
108             os_sprintf(message, _("Can not allocate negative size (%d).\n"),  _iSize);
109             ast::ScilabError se(message);
110             se.SetErrorNumber(999);
111             throw (se);
112         }
113         else
114         {
115             pDbl = new double[_iSize];
116         }
117     }
118     catch (std::bad_alloc &/*e*/)
119     {
120         char message[bsiz];
121         os_sprintf(message, _("Can not allocate %.2f MB memory.\n"),  (double) (_iSize * sizeof(double)) / 1.e6);
122         ast::ScilabError se(message);
123         se.SetErrorNumber(999);
124         throw (se);
125     }
126
127     return pDbl;
128 }
129
130 double SinglePoly::copyValue(double _dblData)
131 {
132     return _dblData;
133 }
134
135 int SinglePoly::getRank()
136 {
137     return m_iSize - 1;
138 }
139
140 bool SinglePoly::setRank(int _iRank, bool bSave)
141 {
142     double *pR = NULL;
143     double *pI = NULL;
144     if (bSave == false)
145     {
146         if (getRank() != _iRank)
147         {
148             int piDims[2] = {_iRank + 1, 1};
149             if (m_pImgData == NULL)
150             {
151                 deleteAll();
152                 create(piDims, 2, &pR, NULL);
153             }
154             else
155             {
156                 deleteAll();
157                 create(piDims, 2, &pR, &pI);
158             }
159
160             return true;
161         }
162
163         return true;
164     }
165     else
166     {
167         double* pdblOldReal = m_pRealData;
168         double* pdblOldImg  = m_pImgData;
169         int iMinSize = Min(m_iSize, _iRank + 1);
170         int piDims[2] = {_iRank + 1, 1};
171
172         if (m_pImgData == NULL)
173         {
174             create(piDims, 2, &pR, NULL);
175         }
176         else
177         {
178             create(piDims, 2, &pR, &pI);
179             memcpy(m_pImgData, pdblOldImg, iMinSize * sizeof(double));
180         }
181
182         memcpy(m_pRealData, pdblOldReal, iMinSize * sizeof(double));
183
184         if (pdblOldImg)
185         {
186             delete[] pdblOldImg;
187             pdblOldImg = NULL;
188         }
189
190         delete[] pdblOldReal;
191         pdblOldReal = NULL;
192
193         return true;
194     }
195
196     return false;
197 }
198
199 bool SinglePoly::setZeros()
200 {
201     if (m_pRealData != NULL)
202     {
203         memset(m_pRealData, 0x00, m_iSize * sizeof(double));
204     }
205     else
206     {
207         return false;
208     }
209
210     if (isComplex() == true)
211     {
212         if (m_pImgData != NULL)
213         {
214             memset(m_pImgData, 0x00, m_iSize * sizeof(double));
215         }
216         else
217         {
218             return false;
219         }
220     }
221
222     return true;
223 }
224
225 bool SinglePoly::setCoef(Double* _pdblCoefR)
226 {
227     if (m_pRealData == NULL || _pdblCoefR == NULL)
228     {
229         return false;
230     }
231
232     double *pInR    = _pdblCoefR->getReal();
233     double *pInI    = _pdblCoefR->getImg();
234
235     return setCoef(pInR, pInI);
236 }
237
238 bool SinglePoly::setCoef(double* _pdblCoefR, double* _pdblCoefI)
239 {
240     if (_pdblCoefI != NULL && isComplex() == false)
241     {
242         setComplex(true);
243     }
244
245     if (_pdblCoefR != NULL)
246     {
247         memcpy(m_pRealData, _pdblCoefR, m_iSize * sizeof(double));
248     }
249
250     if (_pdblCoefI != NULL)
251     {
252         memcpy(m_pImgData, _pdblCoefI, m_iSize * sizeof(double));
253     }
254
255     return true;
256 }
257
258 void SinglePoly::whoAmI()
259 {
260     std::cout << "types::SinglePoly";
261 }
262
263 bool SinglePoly::evaluate(double _dblInR, double _dblInI, double *_pdblOutR, double *_pdblOutI)
264 {
265     *_pdblOutR = 0;
266     *_pdblOutI = 0;
267     if (m_iSize == 0)
268     {
269         return true;
270     }
271
272     for (int i = 0 ; i < m_iSize ; i++)
273     {
274         //real part
275         *_pdblOutR += m_pRealData[i] * pow(_dblInR, i);
276         //only if variable is complex
277         if (isComplex())
278         {
279             *_pdblOutR -= m_pImgData[i] * pow(_dblInI, i);
280             //img part
281             *_pdblOutI += m_pRealData[i] * pow(_dblInR, i);
282         }
283         *_pdblOutI += m_pRealData[i] * pow(_dblInI, i);
284     }
285
286     return true;
287 }
288
289 void SinglePoly::updateRank(void)
290 {
291     int iNewRank = getRank();
292     if (m_pImgData)
293     {
294         for (int i = getRank(); i > 0 ; i--)
295         {
296             if (fabs(m_pRealData[i]) == 0.0 && abs(m_pImgData[i]) == 0.0)
297             {
298                 iNewRank--;
299             }
300             else
301             {
302                 break;
303             }
304         }
305     }
306     else
307     {
308         for (int i = getRank(); i > 0 ; i--)
309         {
310             if (fabs(m_pRealData[i]) == 0.0)
311             {
312                 iNewRank--;
313             }
314             else
315             {
316                 break;
317             }
318         }
319     }
320
321     if (iNewRank < getRank())
322     {
323         setRank(iNewRank, true);
324     }
325 }
326
327 bool SinglePoly::toString(std::wostringstream& ostr)
328 {
329     ostr << L"FIXME : implement SinglePoly::toString" << std::endl;
330     return true;
331 }
332
333 void SinglePoly::toStringReal(wstring _szVar, list<wstring>* _pListExp , list<wstring>* _pListCoef)
334 {
335     toStringInternal(m_pRealData, _szVar, _pListExp, _pListCoef);
336 }
337
338 void SinglePoly::toStringImg(wstring _szVar, list<wstring>* _pListExp , list<wstring>* _pListCoef)
339 {
340     if (isComplex() == false)
341     {
342         _pListExp->clear();
343         _pListCoef->clear();
344         return;
345     }
346
347     toStringInternal(m_pImgData, _szVar, _pListExp, _pListCoef);
348 }
349
350 bool SinglePoly::subMatrixToString(wostringstream& /*ostr*/, int* /*_piDims*/, int /*_iDims*/)
351 {
352     return false;
353 }
354
355 void SinglePoly::toStringInternal(double *_pdblVal, wstring _szVar, list<wstring>* _pListExp , list<wstring>* _pListCoef)
356 {
357     int iLineLen = ConfigVariable::getConsoleWidth();
358
359     wostringstream ostemp;
360     wostringstream ostemp2;
361
362     ostemp << L" ";
363     ostemp2 << L" ";
364
365     int iLen = 0;
366     int iLastFlush = 2;
367     for (int i = 0 ; i < m_iSize ; i++)
368     {
369         if (_pdblVal[i] != 0)
370         {
371             DoubleFormat df;
372             getDoubleFormat(_pdblVal[i], &df);
373
374             if (iLen + df.iWidth + df.iSignLen >= iLineLen - 1)
375             {
376                 iLastFlush = i;
377                 _pListExp->push_back(ostemp2.str());
378                 ostemp2.str(L""); //reset stream
379                 addSpaces(&ostemp2, 11); //take from scilab ... why not ...
380
381                 _pListCoef->push_back(ostemp.str());
382                 ostemp.str(L""); //reset stream
383                 addSpaces(&ostemp, 11); //take from scilab ... why not ...
384             }
385
386             bool bFirst = ostemp.str().size() == 1;
387
388             // In scientific notation case bExp == true, so we have to print point (2.000D+10s)
389             // In other case don't print point (2s)
390             df.bPrintPoint = df.bExp;
391             df.bPrintPlusSign = bFirst == false;
392             df.bPrintOne = i == 0;
393             addDoubleValue(&ostemp, _pdblVal[i], &df);
394
395             if (i == 0)
396             {
397                 iLen = static_cast<int>(ostemp.str().size());
398             }
399             else if (i == 1)
400             {
401                 // add polynom name
402                 ostemp << _szVar;
403                 iLen = static_cast<int>(ostemp.str().size());
404             }
405             else
406             {
407                 // add polynom name and exponent
408                 ostemp << _szVar;
409                 iLen = static_cast<int>(ostemp.str().size());
410                 addSpaces(&ostemp2, iLen - static_cast<int>(ostemp2.str().size()));
411                 ostemp2 << i;
412                 int iSize = static_cast<int>(ostemp2.str().size()) - iLen;
413                 addSpaces(&ostemp, iSize);
414             }
415         }
416     }
417
418     if (iLastFlush != 0)
419     {
420         if (ostemp.str() == L" ")
421         {
422             ostemp << L"  0";
423             addSpaces(&ostemp2, static_cast<int>(ostemp.str().size()));
424         }
425
426         if (ostemp2.str() == L" ")
427         {
428             // -1 because ostemp2 have already a space
429             addSpaces(&ostemp2, static_cast<int>(ostemp.str().size()) - 1);
430         }
431
432         _pListExp->push_back(ostemp2.str());
433         _pListCoef->push_back(ostemp.str());
434     }
435
436     return;
437 }
438
439 bool SinglePoly::operator==(const InternalType& it)
440 {
441     if (const_cast<InternalType &>(it).isSinglePoly() == false)
442     {
443         return false;
444     }
445
446     SinglePoly* pP = const_cast<InternalType &>(it).getAs<SinglePoly>();
447
448     if (getRank() != pP->getRank())
449     {
450         return false;
451     }
452
453     double *pdblReal = pP->get();
454     for (int i = 0 ; i < getSize() ; i++)
455     {
456         if (m_pRealData[i] != pdblReal[i])
457         {
458             return false;
459         }
460     }
461
462     //both complex
463     if (isComplex() && pP->isComplex())
464     {
465         double *pdblImg = pP->getImg();
466         for (int i = 0 ; i < m_iSize ; i++)
467         {
468             if (m_pImgData[i] != pdblImg[i])
469             {
470                 return false;
471             }
472         }
473     }
474     //pdbl complex check all img values == 0
475     else if (pP->isComplex())
476     {
477         double *pdblImg = pP->getImg();
478         for (int i = 0 ; i < m_iSize ; i++)
479         {
480             if (pdblImg[i])
481             {
482                 return false;
483             }
484         }
485     }
486     //complex check all img values == 0
487     else if (isComplex())
488     {
489         for (int i = 0 ; i < m_iSize ; i++)
490         {
491             if (m_pImgData[i])
492             {
493                 return false;
494             }
495         }
496     }
497
498     return true;
499 }
500
501 bool SinglePoly::operator!=(const InternalType& it)
502 {
503     return !(*this == it);
504 }
505
506 SinglePoly* SinglePoly::clone()
507 {
508     SinglePoly* pPoly = NULL;
509     double *pR = NULL;
510     if (isComplex())
511     {
512         double *pI = NULL;
513         pPoly = new SinglePoly(&pR, &pI, getRank());
514         pPoly->setCoef(m_pRealData, m_pImgData);
515     }
516     else
517     {
518         pPoly = new SinglePoly(&pR, getRank());
519         pPoly->setCoef(m_pRealData, NULL);
520     }
521     return pPoly;
522 }
523
524 SinglePoly* SinglePoly::conjugate()
525 {
526     if (isComplex())
527     {
528         double *pR = NULL;
529         double *pI = NULL;
530         SinglePoly * pPoly = new SinglePoly(&pR, &pI, getRank());
531
532         Transposition::conjugate(m_iSize, m_pRealData, pR, m_pImgData, pI);
533
534         return pPoly;
535     }
536     else
537     {
538         return clone();
539     }
540 }
541
542 SinglePoly* operator*(const SinglePoly& _lhs, const SinglePoly& _rhs)
543 {
544     SinglePoly& lhs = const_cast<SinglePoly &>(_lhs);
545     SinglePoly& rhs = const_cast<SinglePoly &>(_rhs);
546     SinglePoly* pOut = NULL;
547
548     bool isComplexL = lhs.isComplex();
549     bool isComplexR = rhs.isComplex();
550     bool isComplexOut = isComplexL || isComplexR;
551
552     int iRankL = lhs.getRank();
553     int iRankR = rhs.getRank();
554     int iRankOut = lhs.getRank() + rhs.getRank();
555
556     double* pdblOutR = NULL;
557     double* pdblOutI = NULL;
558     double* pdblLR = lhs.get();
559     double* pdblLI = lhs.getImg();
560     double* pdblRR = rhs.get();
561     double* pdblRI = rhs.getImg();
562
563     if (isComplexOut)
564     {
565         pOut = new SinglePoly(&pdblOutR, &pdblOutI, iRankOut);
566         memset(pdblOutR, 0x00, sizeof(double) * (iRankOut + 1));
567         memset(pdblOutI, 0x00, sizeof(double) * (iRankOut + 1));
568     }
569     else
570     {
571         pOut = new SinglePoly(&pdblOutR, iRankOut);
572         memset(pdblOutR, 0x00, sizeof(double) * (iRankOut + 1));
573     }
574
575     if (isComplexL)
576     {
577         if (isComplexR)
578         {
579             for (int i = 0 ; i < iRankL + 1; ++i)
580             {
581                 for (int j = 0 ; j < iRankR + 1; ++j)
582                 {
583                     pdblOutR[i + j]  += pdblLR[i] * pdblRR[j] - pdblLI[i] * pdblRI[j];
584                     pdblOutI[i + j]  += pdblLI[i] * pdblRR[j] + pdblLR[i] * pdblRI[j];
585                 }
586             }
587         }
588         else
589         {
590             for (int i = 0 ; i < iRankL + 1 ; ++i)
591             {
592                 for (int j = 0 ; j < iRankR + 1 ; ++j)
593                 {
594                     pdblOutR[i + j]  += pdblLR[i] * pdblRR[j];
595                     pdblOutI[i + j]  += pdblLI[i] * pdblRR[j];
596                 }
597             }
598         }
599     }
600     else
601     {
602         if (isComplexR)
603         {
604             for (int i = 0 ; i < iRankL + 1 ; ++i)
605             {
606                 for (int j = 0 ; j < iRankR + 1 ; ++j)
607                 {
608                     pdblOutR[i + j]  += pdblLR[i] * pdblRR[j];
609                     pdblOutI[i + j]  += pdblLR[i] * pdblRI[j];
610                 }
611             }
612         }
613         else
614         {
615             for (int i = 0 ; i < iRankL + 1 ; ++i)
616             {
617                 for (int j = 0 ; j < iRankR + 1 ; ++j)
618                 {
619                     pdblOutR[i + j]  += pdblLR[i] * pdblRR[j];
620                 }
621             }
622         }
623     }
624
625     return pOut;
626 }
627 }
628
629
630