[ast] improved polynomial display with unicode superscripts 00/21100/3
Stéphane MOTTELET [Thu, 3 Oct 2019 14:58:32 +0000 (16:58 +0200)]
Example:

--> [(1+%s)^7; 1+%s^12]
 ans  =

   1 +7s +21s² +35s³ +35s⁴ +21s⁵ +7s⁶ +s⁷

   1 +s¹²

Change-Id: I122941b9e35eb622ad36718e0e9ee311603bb8ae

scilab/modules/ast/includes/types/polynom.hxx
scilab/modules/ast/includes/types/singlepoly.hxx
scilab/modules/ast/src/cpp/types/polynom.cpp
scilab/modules/ast/src/cpp/types/singlepoly.cpp

index d3653a4..b548b17 100644 (file)
@@ -95,11 +95,8 @@ public :
     Polynom*                set(int _iRows, int _iCols, SinglePoly* _pS) override;
     Polynom*                set(SinglePoly** _pS) override;
 
-    std::wstring            getRowString(int* _piDims, int _iDims, bool _bComplex);
-    std::wstring            getColString(int* _piDims, int _iDims, bool _bComplex);
     std::wstring            getMatrixString(int* _piDims, int _iDims, bool _bComplex);
 
-
     bool                    operator==(const InternalType& it) override;
     bool                    operator!=(const InternalType& it) override;
 
index 1a9a50f..dec00f5 100644 (file)
@@ -59,8 +59,8 @@ public :
     bool                    evaluate(double _dblInR, double _dblInI, double *_pdblOutR, double *_pdblOutI);
     void                    updateRank(void);
 
-    void                    toStringReal(const std::wstring& _szVar, std::list<std::wstring>* _pListExp, std::list<std::wstring>* _pListCoef);
-    void                    toStringImg(const std::wstring& _szVar, std::list<std::wstring>* _pListExp, std::list<std::wstring>* _pListCoef);
+    void                    toStringReal(const std::wstring& _szVar, std::list<std::wstring>* _pListCoef);
+    void                    toStringImg(const std::wstring& _szVar, std::list<std::wstring>* _pListCoef);
 
     bool                    toString(std::wostringstream& ostr) override;
 
@@ -88,7 +88,7 @@ protected :
     }
 
 private :
-    void                    toStringInternal(double *_pdblVal, const std::wstring& _szVar, std::list<std::wstring>* _pListExp, std::list<std::wstring>* _pListCoef);
+    void                    toStringInternal(double *_pdblVal, const std::wstring& _szVar, std::list<std::wstring>* _pListCoef);
 
 };
 
index 535ad80..5ac4d43 100644 (file)
@@ -479,83 +479,23 @@ Polynom* Polynom::setCoef(Double *_pCoef)
 bool Polynom::subMatrixToString(std::wostringstream& ostr, int* _piDims, int _iDims)
 {
     std::wostringstream osExp;
-    std::wostringstream osCoef;
+    std::wostringstream osPoly;
 
     std::list<std::wstring>::const_iterator it_Exp;
     std::list<std::wstring>::const_iterator it_Coef;
-    std::list<std::wstring> listExpR, listCoefR, listExpI, listCoefI;
+    std::list<std::wstring> listExpR, listWstPoly, listExpI, listCoefI;
 
-
-    if (isScalar())
-    {
-        if (isComplex())
-        {
-            ostr << L"Real part" << std::endl << std::endl << std::endl;
-            get(0)->toStringReal(getVariableName(), &listExpR, &listCoefR);
-            for (it_Coef = listCoefR.begin(), it_Exp = listExpR.begin() ; it_Coef != listCoefR.end() ; it_Coef++, it_Exp++)
-            {
-                ostr << *it_Exp << std::endl << *it_Coef << std::endl;
-            }
-
-            ostr << L"Imaginary part" << std::endl << std::endl << std::endl ;
-            get(0)->toStringImg(getVariableName(), &listExpI, &listCoefI);
-            for (it_Coef = listCoefI.begin(), it_Exp = listExpI.begin() ; it_Coef != listCoefI.end() ; it_Coef++, it_Exp++)
-            {
-                ostr << *it_Exp << std::endl << *it_Coef << std::endl;
-            }
-        }
-        else
-        {
-            get(0)->toStringReal(getVariableName(), &listExpR, &listCoefR);
-
-            for (it_Coef = listCoefR.begin(), it_Exp = listExpR.begin() ; it_Coef != listCoefR.end() ; it_Coef++, it_Exp++)
-            {
-                ostr << *it_Exp << std::endl << *it_Coef << std::endl;
-            }
-        }
-    }
-    else if (getRows() == 1)
-    {
-        if (isComplex())
-        {
-            ostr << L"Real part" << std::endl << std::endl;
-            ostr << getRowString(_piDims, _iDims, false);
-            ostr << L"Imaginary part" << std::endl << std::endl;
-            ostr << getRowString(_piDims, _iDims, true);
-        }
-        else
-        {
-            ostr << getRowString(_piDims, _iDims, false);
-        }
-    }
-    else if (getCols() == 1)
+    //Matrix
+    if (isComplex())
     {
-        if (isComplex())
-        {
-            ostr << L"Real part" << std::endl << std::endl;
-            ostr << getColString(_piDims, _iDims, false);
-            ostr << L"Imaginary part" << std::endl << std::endl;
-            ostr << getColString(_piDims, _iDims, true);
-        }
-        else
-        {
-            ostr << getColString(_piDims, _iDims, false);
-        }
+        ostr << L"Real part" << std::endl << std::endl;
+        ostr << getMatrixString(_piDims, _iDims, false);
+        ostr << L"Imaginary part" << std::endl << std::endl;
+        ostr << getMatrixString(_piDims, _iDims, true);
     }
     else
     {
-        //Matrix
-        if (isComplex())
-        {
-            ostr << L"Real part" << std::endl << std::endl;
-            ostr << getMatrixString(_piDims, _iDims, false);
-            ostr << L"Imaginary part" << std::endl << std::endl;
-            ostr << getMatrixString(_piDims, _iDims, true);
-        }
-        else
-        {
-            ostr << getMatrixString(_piDims, _iDims, false);
-        }
+        ostr << getMatrixString(_piDims, _iDims, false);
     }
     return true;
 }
@@ -565,20 +505,15 @@ std::wstring Polynom::getMatrixString(int* _piDims, int /*_iDims*/, bool _bCompl
     int iLineLen = ConfigVariable::getConsoleWidth();
 
     std::wostringstream ostr;
-    std::wostringstream osExp;
-    std::wostringstream osCoef;
+    std::wostringstream osPoly;
 
-    std::list<std::wstring>::const_iterator it_Exp;
     std::list<std::wstring>::const_iterator it_Coef;
-    std::list<std::wstring> listExpR, listCoefR, listExpI, listCoefI;
+    std::list<std::wstring> listWstPoly;
 
     int iLen        = 0;
     int iLastCol    = 0;
     bool bWordWarp  = false;
 
-    std::wstring szExp, szCoef;
-
-
     int *piMaxLen = new int[abs(getCols())];
     memset(piMaxLen, 0x00, sizeof(int) * abs(getCols()));
 
@@ -593,34 +528,19 @@ std::wstring Polynom::getMatrixString(int* _piDims, int /*_iDims*/, bool _bCompl
             int iPos = getIndex(_piDims);
             if (_bComplex)
             {
-                get(iPos)->toStringImg(getVariableName(), &listExpR, &listCoefR);
+                get(iPos)->toStringImg(getVariableName(), &listWstPoly);
             }
             else
             {
-                get(iPos)->toStringReal(getVariableName(), &listExpR, &listCoefR);
+                get(iPos)->toStringReal(getVariableName(), &listWstPoly);
             }
 
-            if (listExpR.size() > 1)
+            for (auto it : listWstPoly)
             {
-                for (it_Exp = listExpR.begin() ; it_Exp != listExpR.end() ; it_Exp++)
-                {
-                    iLength += static_cast<int>((*it_Exp).size());
-                }
-            }
-            else
-            {
-                if (listExpR.front().size() != 0)
-                {
-                    iLength = static_cast<int>(listExpR.front().size());
-                }
-                else
-                {
-                    iLength = static_cast<int>(listCoefR.front().size());
-                }
+                iLength += static_cast<int>(it.size());
             }
             piMaxLen[iCols1] = std::min(std::max(piMaxLen[iCols1], iLength), iLineLen);
-            listExpR.clear();
-            listCoefR.clear();
+            listWstPoly.clear();
         }
 
         //We know the length of the column
@@ -640,51 +560,39 @@ std::wstring Polynom::getMatrixString(int* _piDims, int /*_iDims*/, bool _bCompl
                     int iPos = getIndex(_piDims);
                     if (_bComplex)
                     {
-                        get(iPos)->toStringImg(getVariableName(), &listExpR, &listCoefR);
+                        get(iPos)->toStringImg(getVariableName(),  &listWstPoly);
                     }
                     else
                     {
-                        get(iPos)->toStringReal(getVariableName(), &listExpR, &listCoefR);
+                        get(iPos)->toStringReal(getVariableName(),  &listWstPoly);
                     }
 
-                    if (listCoefR.size() > 1)
+                    if (listWstPoly.size() > 1)
                     {
-                        for (it_Coef = listCoefR.begin(), it_Exp = listExpR.begin() ; it_Coef != listCoefR.end() ; it_Coef++, it_Exp++)
+                        for (auto it : listWstPoly)
                         {
-                            osExp << *it_Exp;
-                            addSpaces(&osExp, piMaxLen[iCols2] - static_cast<int>((*it_Exp).size()));
-                            osExp << std::endl;
-                            osExp << *it_Coef;
-                            addSpaces(&osExp, piMaxLen[iCols2] - static_cast<int>((*it_Coef).size()));
-                            osExp << std::endl;
+                            osPoly << it << std::endl;
                             bMultiLine = true;
                         }
                     }
                     else
                     {
-
-                        osExp << listExpR.front();
-                        addSpaces(&osExp, piMaxLen[iCols2] - static_cast<int>(listExpR.front().size()));
-                        osCoef << listCoefR.front();
-                        addSpaces(&osCoef, piMaxLen[iCols2] - static_cast<int>(listCoefR.front().size()));
+                        osPoly << listWstPoly.front();
+                        addSpaces(&osPoly, piMaxLen[iCols2] - static_cast<int>(listWstPoly.front().size()));
                         bMultiLine = false;
                     }
-                    listExpR.clear();
-                    listCoefR.clear();
+                    listWstPoly.clear();
                 }
 
                 if (bMultiLine == false)
                 {
-                    osExp << std::endl;
-                    osCoef << std::endl;
+                    osPoly << std::endl;
                 }
-                ostemp << osExp.str();
-                ostemp << osCoef.str() << std::endl;
-                osExp.str(L"");
-                osCoef.str(L"");
+                ostemp << osPoly.str() << std::endl;
+                osPoly.str(L"");
 
             }
-            iLen    = piMaxLen[iCols1];
+            iLen = piMaxLen[iCols1];
 
             //write "column x to y"
             addColumnString(ostr, iLastCol + 1, iCols1);
@@ -714,176 +622,41 @@ std::wstring Polynom::getMatrixString(int* _piDims, int /*_iDims*/, bool _bCompl
             int iPos = getIndex(_piDims);
             if (_bComplex)
             {
-                get(iPos)->toStringImg( getVariableName(), &listExpR, &listCoefR);
+                get(iPos)->toStringImg(getVariableName(), &listWstPoly);
             }
             else
             {
-                get(iPos)->toStringReal(getVariableName(), &listExpR, &listCoefR);
+                get(iPos)->toStringReal(getVariableName(), &listWstPoly);
             }
 
-            if (listCoefR.size() > 1)
+            if (listWstPoly.size() > 1)
             {
-                for (it_Coef = listCoefR.begin(), it_Exp = listExpR.begin() ; it_Coef != listCoefR.end() ; it_Coef++, it_Exp++)
+                for (auto it : listWstPoly)
                 {
-                    //normally useless ...
-                    osExp << *it_Exp;
-                    addSpaces(&osExp, piMaxLen[iCols2] - static_cast<int>((*it_Exp).size()));
-                    osExp << std::endl;
-
-                    osExp << *it_Coef;
-                    addSpaces(&osExp, piMaxLen[iCols2] - static_cast<int>((*it_Coef).size()));
-                    osExp << std::endl;
+                    osPoly << it << std::endl;
                 }
             }
             else
             {
-                if (listExpR.front().size() != 0)
-                {
-                    osExp << listExpR.front();
-                }
-
-                addSpaces(&osExp, piMaxLen[iCols2] - static_cast<int>(listExpR.front().size()));
-                osCoef << listCoefR.front();
-                addSpaces(&osCoef, piMaxLen[iCols2] - static_cast<int>(listCoefR.front().size()));
+                osPoly << listWstPoly.front();
+                addSpaces(&osPoly, piMaxLen[iCols2] - static_cast<int>(listWstPoly.front().size()));
             }
-            listExpR.clear();
-            listCoefR.clear();
+            listWstPoly.clear();
         }
 
-        if (osExp.str().size() != 0)
-        {
-            osExp << std::endl;
-        }
-        osCoef << std::endl;
+        osPoly << std::endl;
         if (isIdentity())
         {
             ostr << L"eye *" << std::endl << std::endl;
         }
-        ostr << osExp.str();
-        ostr << osCoef.str() << std::endl;
-        osExp.str(L"");
-        osCoef.str(L"");
+        ostr << osPoly.str() << std::endl;
+        osPoly.str(L"");
     }
 
     delete[] piMaxLen;
     return ostr.str();
 }
 
-std::wstring Polynom::getRowString(int* _piDims, int /*_iDims*/, bool _bComplex)
-{
-    int iLineLen = ConfigVariable::getConsoleWidth();
-
-    int iLen        = 0;
-    int iLastFlush  = 0;
-
-    std::wostringstream ostr;
-    std::wostringstream osExp;
-    std::wostringstream osCoef;
-
-    std::list<std::wstring>::const_iterator it_Exp;
-    std::list<std::wstring>::const_iterator it_Coef;
-    std::list<std::wstring> listExpR, listCoefR, listExpI, listCoefI;
-
-    for (int i = 0 ; i < getCols() ; i++)
-    {
-        std::wstring szExp, szCoef;
-
-        _piDims[1] = 0;
-        _piDims[0] = i;
-        int iPos = getIndex(_piDims);
-        if (_bComplex)
-        {
-            get(iPos)->toStringImg(getVariableName(), &listExpR, &listCoefR);
-        }
-        else
-        {
-            get(iPos)->toStringReal(getVariableName(), &listExpR, &listCoefR);
-        }
-
-        if (iLen != 0 && static_cast<int>(listExpR.front().size()) + iLen >= iLineLen - 1)
-        {
-            //flush strean
-            addColumnString(ostr, iLastFlush + 1, i);
-            iLastFlush = i;
-            iLen = 0;
-            ostr << osExp.str() << std::endl;
-            ostr << osCoef.str() << std::endl;
-            osExp.str(L" ");
-            osCoef.str(L" ");
-        }
-
-        if (listCoefR.size() > 1)
-        {
-            for (it_Coef = listCoefR.begin(), it_Exp = listExpR.begin() ; it_Coef != listCoefR.end() ; it_Coef++, it_Exp++)
-            {
-                osExp << *it_Exp << std::endl << *it_Coef << std::endl;
-            }
-        }
-        else
-        {
-            osExp << listExpR.front();
-            osCoef << listCoefR.front();
-        }
-
-        if (osExp.str().size() != 0)
-        {
-            iLen = static_cast<int>(osExp.str().size());
-        }
-        else
-        {
-            iLen = static_cast<int>(osCoef.str().size());
-        }
-
-        listCoefR.clear();
-        listExpR.clear();
-    }
-
-    if (iLastFlush != 0)
-    {
-        //last line of a multiline output
-        addColumnString(ostr, iLastFlush + 1, getSize());
-    }
-    ostr << osExp.str() << std::endl;
-    ostr << osCoef.str() << std::endl;
-    return ostr.str();
-}
-
-std::wstring Polynom::getColString(int* _piDims, int /*_iDims*/, bool _bComplex)
-{
-    std::wostringstream ostr;
-    std::wostringstream osExp;
-    std::wostringstream osCoef;
-
-    std::list<std::wstring>::const_iterator it_Exp;
-    std::list<std::wstring>::const_iterator it_Coef;
-    std::list<std::wstring> listExpR, listCoefR, listExpI, listCoefI;
-
-    for (int i = 0 ; i < getRows() ; i++)
-    {
-        std::wstring szExp, szCoef;
-
-        _piDims[0] = i;
-        _piDims[1] = 0;
-        int iPos = getIndex(_piDims);
-        if (_bComplex)
-        {
-            get(iPos)->toStringImg(getVariableName(), &listExpR, &listCoefR);
-        }
-        else
-        {
-            get(iPos)->toStringReal(getVariableName(), &listExpR, &listCoefR);
-        }
-
-        for (it_Coef = listCoefR.begin(), it_Exp = listExpR.begin() ; it_Coef != listCoefR.end() ; it_Coef++, it_Exp++)
-        {
-            ostr << *it_Exp << std::endl << *it_Coef << std::endl;
-        }
-        ostr << std::endl;
-        listCoefR.clear();
-        listExpR.clear();
-    }
-    return ostr.str();
-}
 
 Double* Polynom::extractCoef(int _iRank)
 {
index 6361219..04a15cf 100644 (file)
@@ -334,21 +334,20 @@ bool SinglePoly::toString(std::wostringstream& ostr)
     return true;
 }
 
-void SinglePoly::toStringReal(const std::wstring& _szVar, std::list<std::wstring>* _pListExp, std::list<std::wstring>* _pListCoef)
+void SinglePoly::toStringReal(const std::wstring& _szVar, std::list<std::wstring>* _pListWstPoly)
 {
-    toStringInternal(m_pRealData, _szVar, _pListExp, _pListCoef);
+    toStringInternal(m_pRealData, _szVar, _pListWstPoly);
 }
 
-void SinglePoly::toStringImg(const std::wstring& _szVar, std::list<std::wstring>* _pListExp, std::list<std::wstring>* _pListCoef)
+void SinglePoly::toStringImg(const std::wstring& _szVar, std::list<std::wstring>* _pListWstPoly)
 {
     if (isComplex() == false)
     {
-        _pListExp->clear();
-        _pListCoef->clear();
+        _pListWstPoly->clear();
         return;
     }
 
-    toStringInternal(m_pImgData, _szVar, _pListExp, _pListCoef);
+    toStringInternal(m_pImgData, _szVar, _pListWstPoly);
 }
 
 bool SinglePoly::subMatrixToString(std::wostringstream& /*ostr*/, int* /*_piDims*/, int /*_iDims*/)
@@ -356,16 +355,18 @@ bool SinglePoly::subMatrixToString(std::wostringstream& /*ostr*/, int* /*_piDims
     return false;
 }
 
-void SinglePoly::toStringInternal(double *_pdblVal, const std::wstring& _szVar, std::list<std::wstring>* _pListExp, std::list<std::wstring>* _pListCoef)
+void SinglePoly::toStringInternal(double *_pdblVal, const std::wstring& _szVar, std::list<std::wstring>* _pListWstPoly)
 {
     int iLineLen = ConfigVariable::getConsoleWidth();
 
+    std::wstring strExponentDigits (L"\u2070\u00B9\u00B2\u00B3\u2074\u2075\u2076\u2077\u2078\u2079");
+    std::vector<int> iExponentsDigits = {0};
     std::wostringstream ostemp;
-    std::wostringstream ostemp2;
+    bool bFirst = true;
 
     ostemp << L" ";
-    ostemp2 << L" ";
 
+    int k;
     int iLen = 0;
     int iLastFlush = 2;
     for (int i = 0 ; i < m_iSize ; i++)
@@ -378,45 +379,50 @@ void SinglePoly::toStringInternal(double *_pdblVal, const std::wstring& _szVar,
             if (iLen + df.iWidth + df.iSignLen >= iLineLen - 1)
             {
                 iLastFlush = i;
-                _pListExp->push_back(ostemp2.str());
-                ostemp2.str(L""); //reset stream
-                addSpaces(&ostemp2, 11); //take from scilab ... why not ...
-
-                _pListCoef->push_back(ostemp.str());
+                _pListWstPoly->push_back(ostemp.str());
                 ostemp.str(L""); //reset stream
-                addSpaces(&ostemp, 11); //take from scilab ... why not ...
+                addSpaces(&ostemp, 1); //take from scilab ... why not ...
             }
 
-            bool bFirst = ostemp.str().size() == 1;
-
             // In scientific notation case bExp == true, so we have to print point (2.000D+10s)
             // In other case don't print point (2s)
             df.bPrintPoint = df.bExp;
             df.bPrintPlusSign = bFirst == false;
             df.bPrintOne = i == 0;
+            bFirst = false;
             addDoubleValue(&ostemp, _pdblVal[i], &df);
-
+            
             if (i == 0)
             {
                 iLen = static_cast<int>(ostemp.str().size());
             }
             else if (i == 1)
             {
-                // add polynom name
+                // add polynomial variable
                 ostemp << _szVar;
                 iLen = static_cast<int>(ostemp.str().size());
             }
             else
             {
-                // add polynom name and exponent
+                // add polynomial variable and exponent
                 ostemp << _szVar;
-                iLen = static_cast<int>(ostemp.str().size());
-                addSpaces(&ostemp2, iLen - static_cast<int>(ostemp2.str().size()));
-                ostemp2 << i;
-                int iSize = static_cast<int>(ostemp2.str().size()) - iLen;
-                addSpaces(&ostemp, iSize);
-            }
+                for (auto it = iExponentsDigits.rbegin(); it != iExponentsDigits.rend(); ++it)
+                {
+                    ostemp << strExponentDigits[*it];
+                }
+                iLen = static_cast<int>(ostemp.str().size());            
+            }            
         }
+
+        for (k=0; k < iExponentsDigits.size() && iExponentsDigits[k] == 9; k++)
+        {
+            iExponentsDigits[k] = 0;
+        }
+        if (k == iExponentsDigits.size())
+        {
+            iExponentsDigits.push_back(0);
+        }
+        iExponentsDigits[k]++;
     }
 
     if (iLastFlush != 0)
@@ -424,17 +430,9 @@ void SinglePoly::toStringInternal(double *_pdblVal, const std::wstring& _szVar,
         if (ostemp.str() == L" ")
         {
             ostemp << L"  0";
-            addSpaces(&ostemp2, static_cast<int>(ostemp.str().size()));
-        }
-
-        if (ostemp2.str() == L" ")
-        {
-            // -1 because ostemp2 have already a space
-            addSpaces(&ostemp2, static_cast<int>(ostemp.str().size()) - 1);
         }
 
-        _pListExp->push_back(ostemp2.str());
-        _pListCoef->push_back(ostemp.str());
+        _pListWstPoly->push_back(ostemp.str());
     }
 
     return;