2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2008-2008 - DIGITEO - Antoine ELIAS
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
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.
18 #include "core_math.h"
19 #include "tostring_common.hxx"
20 #include "singlepoly.hxx"
21 #include "polynom.hxx"
22 #include "configvariable.hxx"
29 Inspector::addItem(this);
33 Polynom::Polynom(const std::wstring& _szVarName, int _iRows, int _iCols)
35 int piDims[2] = {_iRows, _iCols};
36 createPoly(_szVarName, 2, piDims, NULL);
39 Polynom::Polynom(const std::wstring& _szVarName, int _iRows, int _iCols, const int *_piRank)
41 int piDims[2] = {_iRows, _iCols};
42 createPoly(_szVarName, 2, piDims, _piRank);
45 Polynom::Polynom(const std::wstring& _szVarName, int _iDims, const int* _piDims)
47 createPoly(_szVarName, _iDims, _piDims, NULL);
50 Polynom::Polynom(const std::wstring& _szVarName, int _iDims, const int* _piDims, const int *_piRank)
52 createPoly(_szVarName, _iDims, _piDims, _piRank);
57 if (isDeletable() == true)
62 Inspector::removeItem(this);
66 bool Polynom::getMemory(long long* _piSize, long long* _piSizePlusType)
69 for (int i = 0; i<getSize(); i++)
71 *_piSize += (get(i)->getRank()+1)*sizeof(double);
74 *_piSize = *_piSize * (isComplex() ? 2 : 1);
75 *_piSizePlusType = *_piSize + getSize()*sizeof(SinglePoly *) + sizeof(*this);
80 void Polynom::createPoly(const std::wstring& _szVarName, int _iDims, const int* _piDims, const int *_piRank)
82 m_szVarName = _szVarName;
83 SinglePoly** pPoly = NULL;
84 create(_piDims, _iDims, &pPoly, NULL);
88 for (int i = 0 ; i < getSize() ; i++)
91 m_pRealData[i] = new SinglePoly(&pReal, _piRank[i]);
95 Inspector::addItem(this);
99 Polynom* Polynom::set(int _iPos, SinglePoly* _pS)
101 if (m_pRealData == NULL || _iPos >= m_iSize)
106 typedef Polynom* (Polynom::*set_t)(int, SinglePoly*);
107 Polynom* pIT = checkRef(this, (set_t)&Polynom::set, _iPos, _pS);
113 if (m_pRealData[_iPos])
115 delete m_pRealData[_iPos];
118 m_pRealData[_iPos] = copyValue(_pS);
120 bool bComplex = isComplex();
121 if (_pS->isComplex() && bComplex == false)
125 else if (_pS->isComplex() == false && bComplex)
127 m_pRealData[_iPos]->setComplex(true);
133 Polynom* Polynom::set(int _iRows, int _iCols, SinglePoly* _pS)
135 return set(_iCols * getRows() + _iRows, _pS);
138 Polynom* Polynom::set(SinglePoly** _pS)
140 typedef Polynom* (Polynom::*set_t)(SinglePoly**);
141 Polynom* pIT = checkRef(this, (set_t)&Polynom::set, _pS);
147 for (int i = 0 ; i < m_iSize ; i++)
155 Polynom* Polynom::setCoef(int _iRows, int _iCols, Double *_pdblCoef)
157 int piDims[] = {_iRows, _iCols};
158 int iPos = getIndex(piDims);
159 return setCoef(iPos, _pdblCoef);
162 Polynom* Polynom::setCoef(int _iIdx, Double *_pdblCoef)
169 typedef Polynom* (Polynom::*setCoef_t)(int, Double*);
170 Polynom* pIT = checkRef(this, (setCoef_t)&Polynom::setCoef, _iIdx, _pdblCoef);
176 /*Get old SinglePoly*/
177 m_pRealData[_iIdx]->setRank(_pdblCoef->getSize() - 1);
178 m_pRealData[_iIdx]->setCoef(_pdblCoef);
183 void Polynom::setZeros()
185 for (int i = 0; i < m_iSize; i++)
187 m_pRealData[i]->setZeros();
191 bool Polynom::getSizes(int *_piSizes)
193 if (_piSizes == NULL || m_pRealData == NULL)
198 for (int i = 0 ; i < getSize() ; i++)
200 _piSizes[i] = m_pRealData[i]->getSize();
206 bool Polynom::getRank(int *_piRank)
208 if (_piRank == NULL || m_pRealData == NULL)
213 for (int i = 0 ; i < getSize() ; i++)
215 _piRank[i] = m_pRealData[i]->getRank();
221 void Polynom::whoAmI(void)
223 std::cout << "types::SinglePoly";
226 std::wstring& Polynom::getVariableName()
231 void Polynom::setVariableName(const std::wstring& _szVarName)
233 m_szVarName = _szVarName;
236 bool Polynom::isComplex()
238 for (int i = 0 ; i < getSize() ; i++)
240 if (m_pRealData[i] && m_pRealData[i]->isComplex())
248 Polynom* Polynom::setComplex(bool _bComplex)
250 if (_bComplex == isComplex())
255 typedef Polynom* (Polynom::*setcplx_t)(bool);
256 Polynom* pIT = checkRef(this, (setcplx_t)&Polynom::setComplex, _bComplex);
262 for (int i = 0 ; i < getSize() ; i++)
264 get(i)->setComplex(_bComplex);
270 Polynom* Polynom::clone()
272 Polynom* pMP = new Polynom(getVariableName(), getDims(), getDimsArray());
273 for (int i = 0 ; i < getSize() ; i++)
275 pMP->set(i, m_pRealData[i]);
281 bool Polynom::transpose(InternalType *& out)
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());
302 bool Polynom::adjoint(InternalType *& out)
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());
321 return transpose(out);
325 Double* Polynom::evaluate(Double* _pdblValue)
327 double *pR = _pdblValue->getReal();
328 double *pI = _pdblValue->getImg();
329 int iRows = _pdblValue->getRows();
330 int iCols = _pdblValue->getCols();
332 double *pReturnR = NULL;
333 double *pReturnI = NULL;
334 Double *pReturn = new Double(getRows() * iRows, getCols() * iCols, &pReturnR, &pReturnI);
335 pReturn->setComplex(_pdblValue->isComplex());
338 //all lines of the matrix remplacement
339 for (int iCol = 0 ; iCol < iCols ; iCol++)
341 for (int iPolyCol = 0 ; iPolyCol < getCols() ; iPolyCol++)
343 for (int iRow = 0 ; iRow < iRows ; iRow++)
345 for (int iPolyRow = 0 ; iPolyRow < getRows() ; iPolyRow++)
350 SinglePoly *pPoly = get(iPolyRow, iPolyCol);
351 if (pReturn->isComplex())
353 pPoly->evaluate(pR[iCol * iRows + iRow], pI[iCol * iRows + iRow], &OutR, &OutI);
359 pPoly->evaluate(pR[iCol * iRows + iRow], 0, &OutR, &OutI);
370 void Polynom::updateRank(void)
372 for (int i = 0 ; i < getSize() ; i++)
374 m_pRealData[i]->updateRank();
378 int Polynom::getMaxRank(void)
380 int *piRank = new int[getSize()];
383 for (int i = 0 ; i < getSize() ; i++)
385 iMaxRank = std::max(iMaxRank, piRank[i]);
391 Double* Polynom::getCoef(void)
393 int iMaxRank = getMaxRank();
394 int iColsOut = getCols() * (iMaxRank + 1);
396 Double *pCoef = new Double(getRows(), iColsOut, isComplex());
398 double *pCoefR = pCoef->getReal();
402 double *pCoefI = pCoef->getImg();
403 for (int i = 0 ; i < m_iSize ; i++)
405 SinglePoly *pPoly = m_pRealData[i];
406 int iSize = pPoly->getSize();
407 double *pR = pPoly->get();
408 double *pI = pPoly->getImg();
410 for (int iRank = 0 ; iRank < iSize ; iRank++)
412 pCoefR[iRank * m_iSize + i] = pR[iRank];
413 pCoefI[iRank * m_iSize + i] = pI[iRank];
419 for (int i = 0 ; i < m_iSize ; i++)
421 SinglePoly *pPoly = m_pRealData[i];
422 int iSize = pPoly->getSize();
423 double *pR = pPoly->get();
424 for (int iRank = 0 ; iRank < iSize ; iRank++)
426 pCoefR[iRank * m_iSize + i] = pR[iRank];
434 Polynom* Polynom::setCoef(Double *_pCoef)
436 typedef Polynom* (Polynom::*setCoef_t)(Double*);
437 Polynom* pIT = checkRef(this, (setCoef_t)&Polynom::setCoef, _pCoef);
443 setComplex(_pCoef->isComplex());
444 double *pR = _pCoef->getReal();
448 double *pI = _pCoef->getImg();
449 for (int i = 0 ; i < m_iSize ; i++)
451 SinglePoly *pPoly = m_pRealData[i];
452 int iSize = pPoly->getSize();
453 double* pTempR = pPoly->get();
454 double* pTempI = pPoly->getImg();
456 for (int iRank = 0 ; iRank < iSize ; iRank++)
458 pTempR[iRank] = pR[iRank * m_iSize + i];
459 pTempI[iRank] = pI[iRank * m_iSize + i];
465 for (int i = 0 ; i < m_iSize ; i++)
467 SinglePoly *pPoly = m_pRealData[i];
468 int iSize = pPoly->getSize();
469 double* pTempR = pPoly->get();
471 for (int iRank = 0 ; iRank < iSize ; iRank++)
473 pTempR[iRank] = pR[iRank * m_iSize + i];
481 bool Polynom::subMatrixToString(std::wostringstream& ostr, int* _piDims, int _iDims)
483 std::wostringstream osExp;
484 std::wostringstream osPoly;
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;
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);
500 ostr << getMatrixString(_piDims, _iDims, false);
505 std::wstring Polynom::getMatrixString(int* _piDims, int /*_iDims*/, bool _bComplex)
507 int iLineLen = ConfigVariable::getConsoleWidth();
509 std::wostringstream ostr;
510 std::wostringstream osPoly;
512 std::list<std::wstring>::const_iterator it_Coef;
513 std::list<std::wstring> listWstPoly;
517 bool bWordWarp = false;
519 int *piMaxLen = new int[abs(getCols())];
520 memset(piMaxLen, 0x00, sizeof(int) * abs(getCols()));
522 //find the largest row for each col
523 for (int iCols1 = 0 ; iCols1 < abs(getCols()) ; iCols1++)
525 for (int iRows1 = 0 ; iRows1 < abs(getRows()) ; iRows1++)
530 int iPos = getIndex(_piDims);
533 get(iPos)->toStringImg(getVariableName(), &listWstPoly);
537 get(iPos)->toStringReal(getVariableName(), &listWstPoly);
540 for (auto it : listWstPoly)
542 iLength += static_cast<int>(it.size());
544 piMaxLen[iCols1] = std::min(std::max(piMaxLen[iCols1], iLength), iLineLen);
548 //We know the length of the column
549 if (static_cast<int>(iLen + piMaxLen[iCols1]) >= iLineLen && iLen != 0)
551 //if the max length exceeded
552 std::wostringstream ostemp;
554 for (int iRows2 = 0 ; iRows2 < abs(getRows()) ; iRows2++)
556 bool bMultiLine = false;
557 for (int iCols2 = iLastCol ; iCols2 < iCols1; iCols2++)
562 int iPos = getIndex(_piDims);
565 get(iPos)->toStringImg(getVariableName(), &listWstPoly);
569 get(iPos)->toStringReal(getVariableName(), &listWstPoly);
572 if (listWstPoly.size() > 1)
574 for (auto it : listWstPoly)
576 osPoly << it << std::endl;
582 osPoly << listWstPoly.front();
583 addSpaces(&osPoly, piMaxLen[iCols2] - static_cast<int>(listWstPoly.front().size()));
589 if (bMultiLine == false)
593 ostemp << osPoly.str() << std::endl;
597 iLen = piMaxLen[iCols1];
599 //write "column x to y"
600 addColumnString(ostr, iLastCol + 1, iCols1);
601 ostr << ostemp.str() << std::endl;
605 else //if((int)(iLen + piMaxLen[iCols1]) <= iLineLen)
607 iLen += piMaxLen[iCols1];
609 }//for(int iCols1 = 0 ; iCols1 < getCols() ; iCols1++)
613 addColumnString(ostr, iLastCol + 1, getCols());
617 for (int iRows2 = 0 ; iRows2 < abs(getRows()) ; iRows2++)
619 for (int iCols2 = iLastCol ; iCols2 < abs(getCols()) ; iCols2++)
624 int iPos = getIndex(_piDims);
627 get(iPos)->toStringImg(getVariableName(), &listWstPoly);
631 get(iPos)->toStringReal(getVariableName(), &listWstPoly);
634 if (listWstPoly.size() > 1)
636 for (auto it : listWstPoly)
638 osPoly << it << std::endl;
643 osPoly << listWstPoly.front();
644 addSpaces(&osPoly, piMaxLen[iCols2] - static_cast<int>(listWstPoly.front().size()));
652 ostr << L"eye *" << std::endl << std::endl;
654 ostr << osPoly.str() << std::endl;
663 Double* Polynom::extractCoef(int _iRank)
665 Double *pdbl = new Double(getRows(), getCols(), isComplex());
667 double *pReal = pdbl->getReal();
671 double *pImg = pdbl->getImg();
672 for (int i = 0 ; i < getSize() ; i++)
674 SinglePoly *pPoly = m_pRealData[i];
675 if (pPoly->getRank() >= _iRank)
677 pReal[i] = pPoly->get()[_iRank];
678 pImg[i] = pPoly->getImg()[_iRank];
684 for (int i = 0 ; i < getSize() ; i++)
686 SinglePoly *pPoly = m_pRealData[i];
687 if (pPoly->getRank() >= _iRank)
689 pReal[i] = pPoly->get()[_iRank];
697 bool Polynom::insertCoef(int _iRank, Double* _pCoef)
699 double *pReal = _pCoef->getReal();
702 double *pImg = _pCoef->getImg();
703 for (int i = 0 ; i < getSize() ; i++)
705 SinglePoly *pPoly = m_pRealData[i];
706 if (pPoly->getRank() <= _iRank)
711 pPoly->get()[_iRank] = pReal[i];
712 pPoly->getImg()[_iRank] = pImg[i];
717 for (int i = 0 ; i < getSize() ; i++)
719 SinglePoly *pPoly = m_pRealData[i];
720 if (pPoly->getRank() <= _iRank)
725 pPoly->get()[_iRank] = pReal[i];
732 bool Polynom::operator==(const InternalType& it)
734 if (const_cast<InternalType &>(it).isPoly() == false)
739 Polynom* pM = const_cast<InternalType &>(it).getAs<types::Polynom>();
741 if (pM->getRows() != getRows() || pM->getCols() != getCols())
746 for (int i = 0 ; i < getSize() ; i++)
748 SinglePoly* p1 = get(i);
749 SinglePoly* p2 = pM->get(i);
759 bool Polynom::operator!=(const InternalType& it)
761 return !(*this == it);
764 SinglePoly* Polynom::getNullValue()
766 return new SinglePoly();
769 Polynom* Polynom::createEmpty(int _iDims, int* _piDims, bool /*_bComplex*/)
771 return new Polynom(getVariableName(), _iDims, _piDims, NULL);
774 SinglePoly* Polynom::copyValue(SinglePoly* _pData)
780 return _pData->clone();
783 void Polynom::deleteAll()
785 for (int i = 0 ; i < m_iSizeMax ; i++)
787 m_pRealData[i]->killMe();
789 delete[] m_pRealData;
794 void Polynom::deleteImg()
799 SinglePoly** Polynom::allocData(int _iSize)
801 SinglePoly** pData = new SinglePoly*[_iSize];
802 memset(pData, 0x00, _iSize * sizeof(SinglePoly*));
806 void Polynom::deleteData(SinglePoly* data)
814 //overload to check variable name and call arrayof<>::insert after
815 Polynom* Polynom::insert(typed_list* _pArgs, InternalType* _pSource)
817 Polynom* p = _pSource->getAs<Polynom>();
818 if (p->getVariableName() != getVariableName())
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);
825 throw ast::InternalError(wstError);
828 return ArrayOf<SinglePoly*>::insert(_pArgs, _pSource)->getAs<Polynom>();
831 Polynom* Polynom::Dollar()
834 Polynom* pDollar = new Polynom(L"$", 1, 1, &iRank);
835 double* pdblCoef = pDollar->get(0)->get();
842 bool Polynom::isDollar()
844 if (m_szVarName != L"$" || getSize() != 1)
849 double* pCoef = get(0)->get();
851 if (pCoef[0] != 0 && pCoef[1] != 1)