* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
* Copyright (C) 2008-2008 - DIGITEO - Antoine ELIAS
*
-* This file must be used under the terms of the CeCILL.
-* This source file is licensed as described in the file COPYING, which
-* you should have received as part of this distribution. The terms
-* are also available at
-* http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ * Copyright (C) 2012 - 2016 - Scilab Enterprises
+ *
+ * This file is hereby licensed under the terms of the GNU GPL v2.0,
+ * pursuant to article 5.3.4 of the CeCILL v.2.1.
+ * This file was originally licensed under the terms of the CeCILL v2.1,
+ * and continues to be available under such terms.
+ * For more information, see the COPYING file which you should have received
+ * along with this program.
*
*/
#include <sstream>
-#include <math.h>
+#include <cmath>
#include "singlepoly.hxx"
#include "double.hxx"
#include "tostring_common.hxx"
#include "configvariable.hxx"
+#include "scilabWrite.hxx"
extern "C"
{
#include "elem_common.h"
}
-using namespace std;
-
namespace types
{
SinglePoly::SinglePoly()
{
- int iRank = 1;
double* pdblCoefR = NULL;
- createPoly(&pdblCoefR, NULL, iRank);
+ int piDims[2] = {1, 1};
+ create(piDims, 2, &pdblCoefR, NULL);
pdblCoefR[0] = 0;
+#ifndef NDEBUG
+ Inspector::addItem(this);
+#endif
}
SinglePoly::SinglePoly(double** _pdblCoefR, int _iRank)
{
- createPoly(_pdblCoefR, NULL, _iRank);
+ int piDims[2] = {_iRank + 1, 1};
+ create(piDims, 2, _pdblCoefR, NULL);
+#ifndef NDEBUG
+ Inspector::addItem(this);
+#endif
}
SinglePoly::SinglePoly(double** _pdblCoefR, double** _pdblCoefI, int _iRank)
{
- createPoly(_pdblCoefR, _pdblCoefI, _iRank);
+ int piDims[2] = {_iRank + 1, 1};
+ create(piDims, 2, _pdblCoefR, _pdblCoefI);
+#ifndef NDEBUG
+ Inspector::addItem(this);
+#endif
}
-SinglePoly::SinglePoly(Double** _poCoefR, int _iRank)
+SinglePoly::~SinglePoly()
{
- double *pR = NULL;
- double *pI = NULL;
- createPoly(&pR, &pI, _iRank);
- *_poCoefR = m_pdblCoef;
+ deleteAll();
+#ifndef NDEBUG
+ Inspector::removeItem(this);
+#endif
}
+void SinglePoly::deleteAll()
+{
+ delete[] m_pRealData;
+ m_pRealData = NULL;
+ deleteImg();
+}
-SinglePoly::~SinglePoly()
+void SinglePoly::deleteImg()
{
- if (m_pdblCoef)
+ if (m_pImgData != NULL)
{
- delete m_pdblCoef;
+ delete[] m_pImgData;
+ m_pImgData = NULL;
}
}
-/*Real constructor, private only*/
-void SinglePoly::createPoly(double** _pdblCoefR, double** _pdblCoefI, int _iRank)
+double SinglePoly::getNullValue()
{
- double *pR = NULL;
- double *pI = NULL;
- m_bComplex = false;
- m_iRank = _iRank;
+ return 0;
+}
- if (m_iRank == 0)
- {
- m_pdblCoef = NULL;
- return;
- }
+SinglePoly* SinglePoly::createEmpty(int /*_iDims*/, int* _piDims, bool _bComplex)
+{
+ double* pdblData = NULL;
+ SinglePoly* pSP = new SinglePoly(&pdblData, _piDims[0] - 1);
+ pSP->setComplex(_bComplex);
- if (_pdblCoefI != NULL)
+ return pSP;
+}
+
+double* SinglePoly::allocData(int _iSize)
+{
+ double* pDbl = NULL;
+ try
{
- m_pdblCoef = new Double(1, _iRank, &pR, &pI);
+ if (_iSize < 0)
+ {
+ m_pRealData = NULL;
+ m_pImgData = NULL;
+ char message[bsiz];
+ os_sprintf(message, _("Can not allocate negative size (%d).\n"), _iSize);
+ throw ast::InternalError(message);
+ }
+ else
+ {
+ pDbl = new double[_iSize];
+ }
}
- else
+ catch (std::bad_alloc &/*e*/)
{
- m_pdblCoef = new Double(1, _iRank, &pR);
+ char message[bsiz];
+ char byteString[9];
+ humanReadableByteCount(((size_t) m_iSize) * sizeof(double), byteString);
+ os_sprintf(message, _("Can not allocate %s memory.\n"), byteString);
+ throw ast::InternalError(message);
}
- m_pdblCoef->IncreaseRef();
- m_pdblCoef->setZeros();
- if (_pdblCoefR != NULL)
- {
- *_pdblCoefR = pR;
- }
+ return pDbl;
+}
- if (_pdblCoefI != NULL)
- {
- m_bComplex = true;
- *_pdblCoefI = pI;
- }
+double SinglePoly::copyValue(double _dblData)
+{
+ return _dblData;
}
int SinglePoly::getRank()
{
- return m_iRank;
+ return m_iSize - 1;
}
-int SinglePoly::getRealRank()
+double SinglePoly::getDegree()
{
- return m_iRank - 1;
+ return m_iSize == 1 && m_pRealData[0] == 0 && (m_pImgData == NULL || m_pImgData[0] == 0) ? -INFINITY : m_iSize - 1;
}
bool SinglePoly::setRank(int _iRank, bool bSave)
{
- double *pR = NULL;
- double *pI = NULL;
+ double *pR = NULL;
+ double *pI = NULL;
if (bSave == false)
{
- if (m_iRank != _iRank)
+ if (getRank() != _iRank)
{
- delete m_pdblCoef;
-
- if (m_bComplex == false)
+ int piDims[2] = {_iRank + 1, 1};
+ if (m_pImgData == NULL)
{
- createPoly(&pR, NULL, _iRank);
+ deleteAll();
+ create(piDims, 2, &pR, NULL);
}
else
{
- createPoly(&pR, &pI, _iRank);
+ deleteAll();
+ create(piDims, 2, &pR, &pI);
}
+
return true;
}
+
return true;
}
else
{
- Double *pCoef = NULL;
- if (_iRank != 0)
+ double* pdblOldReal = m_pRealData;
+ double* pdblOldImg = m_pImgData;
+ int iMinSize = Min(m_iSize, _iRank + 1);
+ int piDims[2] = {_iRank + 1, 1};
+
+ if (m_pImgData == NULL)
{
- pCoef = new Double(1, _iRank, &pR, &pI);
- pCoef->set(m_pdblCoef->getReal());
- pCoef->setComplex(m_pdblCoef->isComplex());
- if (m_pdblCoef->isComplex())
- {
- pCoef->setImg(m_pdblCoef->getImg());
- }
- m_iRank = _iRank;
+ create(piDims, 2, &pR, NULL);
}
else
{
- m_iRank = 1;
- pCoef = new Double(1, 1, &pR, &pI);
- pCoef->setComplex(m_pdblCoef->isComplex());
- pCoef->set(0, 0, 0);
+ create(piDims, 2, &pR, &pI);
+ memcpy(m_pImgData, pdblOldImg, iMinSize * sizeof(double));
}
- m_pdblCoef->DecreaseRef();
- if (m_pdblCoef->isDeletable())
+ memcpy(m_pRealData, pdblOldReal, iMinSize * sizeof(double));
+
+ if (pdblOldImg)
{
- delete m_pdblCoef;
+ delete[] pdblOldImg;
+ pdblOldImg = NULL;
}
- m_pdblCoef = pCoef;
- m_pdblCoef->IncreaseRef();
+ delete[] pdblOldReal;
+ pdblOldReal = NULL;
+
return true;
}
+
return false;
}
-Double* SinglePoly::getCoef()
+bool SinglePoly::setZeros()
{
- return m_pdblCoef;
-}
+ if (m_pRealData != NULL)
+ {
+ memset(m_pRealData, 0x00, m_iSize * sizeof(double));
+ }
+ else
+ {
+ return false;
+ }
-double* SinglePoly::getCoefReal()
-{
- return m_pdblCoef->getReal();
-}
+ if (isComplex() == true)
+ {
+ if (m_pImgData != NULL)
+ {
+ memset(m_pImgData, 0x00, m_iSize * sizeof(double));
+ }
+ else
+ {
+ return false;
+ }
+ }
-double* SinglePoly::getCoefImg()
-{
- return m_pdblCoef->getImg();
+ return true;
}
bool SinglePoly::setCoef(Double* _pdblCoefR)
{
- if (m_pdblCoef == NULL || _pdblCoefR == NULL)
+ if (m_pRealData == NULL || _pdblCoefR == NULL)
{
return false;
}
- double *pInR = _pdblCoefR->getReal();
- double *pInI = _pdblCoefR->getImg();
+ double *pInR = _pdblCoefR->getReal();
+ double *pInI = _pdblCoefR->getImg();
return setCoef(pInR, pInI);
}
-void SinglePoly::setComplex(bool _bComplex)
-{
- m_pdblCoef->setComplex(_bComplex);
- m_bComplex = _bComplex;
-}
-
-bool SinglePoly::setCoef(double* _pdblCoefR, double* _pdblCoefI)
+bool SinglePoly::setCoef(const double* _pdblCoefR, const double* _pdblCoefI)
{
- if (m_pdblCoef == NULL)
- {
- return false;
- }
-
if (_pdblCoefI != NULL && isComplex() == false)
{
- m_pdblCoef->setComplex(true);
- m_bComplex = true;
+ setComplex(true);
}
- double *pR = m_pdblCoef->getReal();
- double *pI = m_pdblCoef->getImg();
-
- if (_pdblCoefR != NULL && pR != NULL)
+ if (_pdblCoefR != NULL)
{
- memcpy(pR, _pdblCoefR, m_iRank * sizeof(double));
+ memcpy(m_pRealData, _pdblCoefR, m_iSize * sizeof(double));
}
- if (_pdblCoefI != NULL && pI != NULL)
+ if (_pdblCoefI != NULL)
{
- memcpy(pI, _pdblCoefI, m_iRank * sizeof(double));
+ memcpy(m_pImgData, _pdblCoefI, m_iSize * sizeof(double));
}
return true;
std::cout << "types::SinglePoly";
}
-bool SinglePoly::isComplex()
-{
- return m_bComplex;
-}
-
-GenericType* SinglePoly::getColumnValues(int _iPos)
-{
- return NULL;
-}
-
bool SinglePoly::evaluate(double _dblInR, double _dblInI, double *_pdblOutR, double *_pdblOutI)
{
- double *pCoefR = m_pdblCoef->getReal();
- double *pCoefI = m_pdblCoef->getImg();
-
*_pdblOutR = 0;
*_pdblOutI = 0;
- if (m_iRank == 0)
+ if (m_iSize == 0)
{
return true;
}
- for (int i = 0 ; i < m_iRank ; i++)
+ for (int i = 0 ; i < m_iSize ; i++)
{
//real part
- *_pdblOutR += pCoefR[i] * pow(_dblInR, i);
+ *_pdblOutR += m_pRealData[i] * std::pow(_dblInR, i);
//only if variable is complex
- if (m_pdblCoef->isComplex())
+ if (isComplex())
{
- *_pdblOutR -= pCoefI[i] * pow(_dblInI, i);
+ *_pdblOutR -= m_pImgData[i] * std::pow(_dblInI, i);
//img part
- *_pdblOutI += pCoefI[i] * pow(_dblInR, i);
+ *_pdblOutI += m_pRealData[i] * std::pow(_dblInR, i);
}
- *_pdblOutI += pCoefR[i] * pow(_dblInI, i);
- }
-
- //old version, does not work
- //for(int i = m_iRank - 1 ; i >= 0 ; i--)
- //{
- // //(a1 + ib1)(a2 + ib2)**n = (a1 + ib1) * exp(n * log(a2 + ib2))
- // double dblLogR = 0;
- // double dblLogI = 0;
- // double dblExpR = 0;
- // double dblExpI = 0;
-
- // //log(a2 + ib2)
- // if(_dblInI != 0)
- // {
- // wlog(_dblInR, _dblInI, &dblLogR, &dblLogI);
- // }
- // else
- // {
- // dblLogR = dlogs(_dblInR);
- // }
-
- // //n * log(a2 + ib2)
- // dblLogR *= i;
- // dblLogI *= i;
-
- // //exp(n * log(a2 + ib2))
- // if(dblLogI != 0)
- // {
- // zexps(dblLogR, dblLogI, &dblExpR, &dblExpI);
- // }
- // else
- // {
- // dblExpR = dexps(dblLogR);
- // }
-
- // //(a1 + ib1) * exp(n * log(a2 + ib2))
- // if(m_pdblCoef->isComplex())
- // {
- // *_pdblOutR += (dblExpR * pCoefR[i] - dblExpI * pCoefI[i]);
- // *_pdblOutI += (dblExpR * pCoefI[i] + dblExpI * pCoefR[i]);
- // }
- // else
- // {
- // *_pdblOutR += (dblExpR * pCoefR[i]);
- // *_pdblOutI += (dblExpI * pCoefR[i]);
- // }
- //}
+ *_pdblOutI += m_pRealData[i] * std::pow(_dblInI, i);
+ }
+
return true;
}
void SinglePoly::updateRank(void)
{
- double dblEps = getRelativeMachinePrecision();
- int iNewRank = m_iRank;
- double *pCoefR = getCoef()->getReal();
- double *pCoefI = getCoef()->getImg();
- for (int i = m_iRank - 1; i > 0 ; i--)
+ int iNewRank = getRank();
+ if (m_pImgData)
{
- if (fabs(pCoefR[i]) <= dblEps && (pCoefI != NULL ? fabs(pCoefI[i]) : 0) <= dblEps)
+ for (int i = getRank(); i > 0 ; i--)
{
- iNewRank--;
+ if (std::fabs(m_pRealData[i]) == 0.0 && std::fabs(m_pImgData[i]) == 0.0)
+ {
+ iNewRank--;
+ }
+ else
+ {
+ break;
+ }
}
- else
+ }
+ else
+ {
+ for (int i = getRank(); i > 0 ; i--)
{
- break;
+ if (std::fabs(m_pRealData[i]) == 0.0)
+ {
+ iNewRank--;
+ }
+ else
+ {
+ break;
+ }
}
}
- if (iNewRank < m_iRank)
+
+ if (iNewRank < getRank())
{
setRank(iNewRank, true);
}
return true;
}
-void SinglePoly::toStringReal(wstring _szVar, list<wstring>* _pListExp , list<wstring>* _pListCoef)
+void SinglePoly::toStringReal(const std::wstring& _szVar, std::list<std::wstring>* _pListWstPoly)
{
- toStringInternal(m_pdblCoef->getReal(), _szVar, _pListExp, _pListCoef);
+ toStringInternal(m_pRealData, _szVar, _pListWstPoly);
}
-void SinglePoly::toStringImg(wstring _szVar, list<wstring>* _pListExp , list<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_pdblCoef->getImg(), _szVar, _pListExp, _pListCoef);
+ toStringInternal(m_pImgData, _szVar, _pListWstPoly);
}
-void SinglePoly::toStringInternal(double *_pdblVal, wstring _szVar, list<wstring>* _pListExp , list<wstring>* _pListCoef)
+bool SinglePoly::subMatrixToString(std::wostringstream& /*ostr*/, int* /*_piDims*/, int /*_iDims*/)
{
- int iPrecision = ConfigVariable::getFormatSize();
- int iLineLen = ConfigVariable::getConsoleWidth();
+ return false;
+}
- wostringstream ostemp;
- wostringstream ostemp2;
+void SinglePoly::toStringInternal(double *_pdblVal, const std::wstring& _szVar, std::list<std::wstring>* _pListWstPoly)
+{
+ int iLineLen = ConfigVariable::getConsoleWidth();
- ostemp << L" ";
- ostemp2 << L"";
+ std::wstring strExponentDigits (L"\u2070\u00B9\u00B2\u00B3\u2074\u2075\u2076\u2077\u2078\u2079");
+ std::vector<int> iExponentsDigits = {0};
+ std::wostringstream ostemp;
+ bool bFirst = true;
- //to add exponant value a the good place
- int *piIndexExp = new int[m_iRank];
+ ostemp << L" ";
- int iLen = 0;
- int iLastFlush = 2;
- for (int i = 0 ; i < m_iRank ; i++)
+ int k;
+ int iLen = 0;
+ int iLastFlush = 2;
+ for (int i = 0 ; i < m_iSize ; i++)
{
- piIndexExp[i] = 0;
- if (isRealZero(_pdblVal[i]) == false)
+ if (_pdblVal[i] != 0)
{
DoubleFormat df;
getDoubleFormat(_pdblVal[i], &df);
- if (iLen + df.iWidth + 2 >= iLineLen)
+ if (iLen + df.iWidth + df.iSignLen >= iLineLen - 1)
{
- //flush
- for (int j = iLastFlush ; j < i ; j++)
- {
- if (piIndexExp[j] == 0)
- {
- continue;
- }
-
- addSpaces(&ostemp2, piIndexExp[j] - static_cast<int>(ostemp2.str().size()));
- if (isRealZero(_pdblVal[j]) == false)
- {
- ostemp2 << j;
- }
- }
iLastFlush = i;
- _pListExp->push_back(ostemp2.str());
- ostemp2.str(L""); //reset stream
- addSpaces(&ostemp2, 12); //take from scilab ... why not ...
-
- _pListCoef->push_back(ostemp.str());
+ _pListWstPoly->push_back(ostemp.str());
ostemp.str(L""); //reset stream
- addSpaces(&ostemp, 12); //take from scilab ... why not ...
+ addSpaces(&ostemp, 1); //take from scilab ... why not ...
}
- bool bFirst = ostemp.str().size() == 2;
-
- df.bPrintPoint = false;
- df.bPrintPlusSign = ostemp.str().size() != 2;
+ // 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)
+
+ if (i == 0)
{
- ostemp << _szVar;
- piIndexExp[i] = static_cast<int>(ostemp.str().size());
+ iLen = static_cast<int>(ostemp.str().size());
}
- ostemp << L" ";
- iLen = static_cast<int>(ostemp.str().size());
- }
- }
-
- if (iLastFlush != 0)
- {
- for (int j = iLastFlush ; j < m_iRank ; j++)
- {
- if (piIndexExp[j] == 0)
+ else if (i == 1)
{
- continue;
+ // add polynomial variable
+ ostemp << _szVar;
+ iLen = static_cast<int>(ostemp.str().size());
}
-
- addSpaces(&ostemp2, piIndexExp[j] - static_cast<int>(ostemp2.str().size()));
- if (isRealZero(_pdblVal[j]) == false)
+ else
{
- ostemp2 << j;
- }
+ // add polynomial variable and exponent
+ ostemp << _szVar;
+ for (auto it = iExponentsDigits.rbegin(); it != iExponentsDigits.rend(); ++it)
+ {
+ ostemp << strExponentDigits[*it];
+ }
+ iLen = static_cast<int>(ostemp.str().size());
+ }
}
- if (ostemp.str() == L" ")
+ for (k=0; k < iExponentsDigits.size() && iExponentsDigits[k] == 9; k++)
{
- ostemp << L" 0";
- addSpaces(&ostemp2, static_cast<int>(ostemp.str().size()));
+ iExponentsDigits[k] = 0;
+ }
+ if (k == iExponentsDigits.size())
+ {
+ iExponentsDigits.push_back(0);
}
+ iExponentsDigits[k]++;
+ }
- if (ostemp2.str() == L"")
+ if (iLastFlush != 0)
+ {
+ if (ostemp.str() == L" ")
{
- addSpaces(&ostemp2, static_cast<int>(ostemp.str().size()));
+ ostemp << L" 0";
}
- _pListExp->push_back(ostemp2.str());
- _pListCoef->push_back(ostemp.str());
+ _pListWstPoly->push_back(ostemp.str());
}
- delete[] piIndexExp;
return;
}
return false;
}
- return *(getCoef()) == *(pP->getCoef());
+ double *pdblReal = pP->get();
+ for (int i = 0 ; i < getSize() ; i++)
+ {
+ if (m_pRealData[i] != pdblReal[i])
+ {
+ return false;
+ }
+ }
+
+ //both complex
+ if (isComplex() && pP->isComplex())
+ {
+ double *pdblImg = pP->getImg();
+ for (int i = 0 ; i < m_iSize ; i++)
+ {
+ if (m_pImgData[i] != pdblImg[i])
+ {
+ return false;
+ }
+ }
+ }
+ //pdbl complex check all img values == 0
+ else if (pP->isComplex())
+ {
+ double *pdblImg = pP->getImg();
+ for (int i = 0 ; i < m_iSize ; i++)
+ {
+ if (pdblImg[i])
+ {
+ return false;
+ }
+ }
+ }
+ //complex check all img values == 0
+ else if (isComplex())
+ {
+ for (int i = 0 ; i < m_iSize ; i++)
+ {
+ if (m_pImgData[i])
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
}
bool SinglePoly::operator!=(const InternalType& it)
{
double *pI = NULL;
pPoly = new SinglePoly(&pR, &pI, getRank());
- pPoly->setCoef(getCoefReal(), getCoefImg());
+ pPoly->setCoef(m_pRealData, m_pImgData);
}
else
{
pPoly = new SinglePoly(&pR, getRank());
- pPoly->setCoef(getCoefReal(), NULL);
+ pPoly->setCoef(m_pRealData, NULL);
}
return pPoly;
}
SinglePoly* SinglePoly::conjugate()
{
- SinglePoly* pPoly = NULL;
if (isComplex())
{
double *pR = NULL;
double *pI = NULL;
SinglePoly * pPoly = new SinglePoly(&pR, &pI, getRank());
- Transposition::conjugate(getRank(), getCoefReal(), pR, getCoefImg(), pI);
+ Transposition::conjugate(m_iSize, m_pRealData, pR, m_pImgData, pI);
return pPoly;
}
return clone();
}
}
+
+SinglePoly* operator*(const SinglePoly& _lhs, const SinglePoly& _rhs)
+{
+ SinglePoly& lhs = const_cast<SinglePoly &>(_lhs);
+ SinglePoly& rhs = const_cast<SinglePoly &>(_rhs);
+ SinglePoly* pOut = NULL;
+
+ bool isComplexL = lhs.isComplex();
+ bool isComplexR = rhs.isComplex();
+ bool isComplexOut = isComplexL || isComplexR;
+
+ int iRankL = lhs.getRank();
+ int iRankR = rhs.getRank();
+ int iRankOut = lhs.getRank() + rhs.getRank();
+
+ double* pdblOutR = NULL;
+ double* pdblOutI = NULL;
+ double* pdblLR = lhs.get();
+ double* pdblLI = lhs.getImg();
+ double* pdblRR = rhs.get();
+ double* pdblRI = rhs.getImg();
+
+ if (isComplexOut)
+ {
+ pOut = new SinglePoly(&pdblOutR, &pdblOutI, iRankOut);
+ memset(pdblOutR, 0x00, sizeof(double) * (iRankOut + 1));
+ memset(pdblOutI, 0x00, sizeof(double) * (iRankOut + 1));
+ }
+ else
+ {
+ pOut = new SinglePoly(&pdblOutR, iRankOut);
+ memset(pdblOutR, 0x00, sizeof(double) * (iRankOut + 1));
+ }
+
+ if (isComplexL)
+ {
+ if (isComplexR)
+ {
+ for (int i = 0 ; i < iRankL + 1; ++i)
+ {
+ for (int j = 0 ; j < iRankR + 1; ++j)
+ {
+ pdblOutR[i + j] += pdblLR[i] * pdblRR[j] - pdblLI[i] * pdblRI[j];
+ pdblOutI[i + j] += pdblLI[i] * pdblRR[j] + pdblLR[i] * pdblRI[j];
+ }
+ }
+ }
+ else
+ {
+ for (int i = 0 ; i < iRankL + 1 ; ++i)
+ {
+ for (int j = 0 ; j < iRankR + 1 ; ++j)
+ {
+ pdblOutR[i + j] += pdblLR[i] * pdblRR[j];
+ pdblOutI[i + j] += pdblLI[i] * pdblRR[j];
+ }
+ }
+ }
+ }
+ else
+ {
+ if (isComplexR)
+ {
+ for (int i = 0 ; i < iRankL + 1 ; ++i)
+ {
+ for (int j = 0 ; j < iRankR + 1 ; ++j)
+ {
+ pdblOutR[i + j] += pdblLR[i] * pdblRR[j];
+ pdblOutI[i + j] += pdblLR[i] * pdblRI[j];
+ }
+ }
+ }
+ else
+ {
+ for (int i = 0 ; i < iRankL + 1 ; ++i)
+ {
+ for (int j = 0 ; j < iRankR + 1 ; ++j)
+ {
+ pdblOutR[i + j] += pdblLR[i] * pdblRR[j];
+ }
+ }
+ }
+ }
+
+ return pOut;
}
+}
+