20 #include <rtl/math.hxx>
24 #ifdef DEBUG_SC_LUP_DECOMPOSITION
34 #include <document.hxx>
37 #include <globstr.hrc>
52 double operator() (
const double& lhs,
const double& rhs)
const
54 return ::rtl::math::approxAdd( lhs,rhs);
60 double operator() (
const double& lhs,
const double& rhs)
const
62 return ::rtl::math::approxSub( lhs,rhs);
68 double operator() (
const double& lhs,
const double& rhs)
const
76 double operator() (
const double& lhs,
const double& rhs)
const
84 double operator() (
const double& lhs,
const double& rhs)
const
86 return ::pow( lhs,rhs);
94 for (
SCSIZE row = 0; row < n; row++)
96 for (
SCSIZE col = 0; col < l; col++)
99 for (
SCSIZE k = 0; k < m; k++)
100 fSum += pA->GetDouble(k,row) * pB->GetDouble(col,k);
101 pR->PutDouble(fSum.
get(), col, row);
118 double fz = fmod(fx, fy);
132 if ( !MustHaveParamCountMin( nParamCount, 1 ) )
137 size_t nRefInList = 0;
138 while (nGlobalError == FormulaError::NONE && nParamCount-- > 0)
140 switch (GetStackType())
146 fx = ::rtl::math::approxFloor( GetDouble());
149 PushIllegalArgument();
152 fy = ScGetGCD(fx, fy);
159 PopDoubleRef( aRange, nParamCount, nRefInList);
162 if (aValIter.
GetFirst(nCellVal, nErr))
166 fx = ::rtl::math::approxFloor( nCellVal);
169 PushIllegalArgument();
172 fy = ScGetGCD(fx, fy);
173 }
while (nErr == FormulaError::NONE && aValIter.
GetNext(nCellVal, nErr));
186 pMat->GetDimensions(nC, nR);
187 if (nC == 0 || nR == 0)
188 SetError(FormulaError::IllegalArgument);
191 double nVal = pMat->GetGcd();
192 fy = ScGetGCD(nVal,fy);
197 default :
SetError(FormulaError::IllegalParameter);
break;
206 if ( !MustHaveParamCountMin( nParamCount, 1 ) )
211 size_t nRefInList = 0;
212 while (nGlobalError == FormulaError::NONE && nParamCount-- > 0)
214 switch (GetStackType())
220 fx = ::rtl::math::approxFloor( GetDouble());
223 PushIllegalArgument();
226 if (fx == 0.0 || fy == 0.0)
229 fy = fx * fy / ScGetGCD(fx, fy);
236 PopDoubleRef( aRange, nParamCount, nRefInList);
239 if (aValIter.
GetFirst(nCellVal, nErr))
243 fx = ::rtl::math::approxFloor( nCellVal);
246 PushIllegalArgument();
249 if (fx == 0.0 || fy == 0.0)
252 fy = fx * fy / ScGetGCD(fx, fy);
253 }
while (nErr == FormulaError::NONE && aValIter.
GetNext(nCellVal, nErr));
266 pMat->GetDimensions(nC, nR);
267 if (nC == 0 || nR == 0)
268 SetError(FormulaError::IllegalArgument);
271 double nVal = pMat->GetLcm();
272 fy = (nVal * fy ) / ScGetGCD(nVal, fy);
277 default :
SetError(FormulaError::IllegalParameter);
break;
285 rMat->SetErrorInterpreter(
this);
290 rMat->GetDimensions( nCols, nRows);
291 if ( nCols != nC || nRows != nR )
293 SetError( FormulaError::MatrixSize);
305 MakeMatNew(pMat, nC, nR);
312 MakeMatNew(pMat, nC, nR);
320 if (nTab1 != nTab2 || nGlobalError != FormulaError::NONE)
323 SetError(FormulaError::IllegalParameter);
327 if (nTab1 == nTab2 && pToken)
338 SCCOL nTempCol = nCol1;
339 SCROW nTempRow = nRow1;
340 mrDoc.ShrinkToDataArea(nTab1, nTempCol, nTempRow, nCol2, nRow2);
344 SCSIZE nMatCols =
static_cast<SCSIZE>(nCol2 - nCol1 + 1);
345 SCSIZE nMatRows =
static_cast<SCSIZE>(nRow2 - nRow1 + 1);
353 ScTokenMatrixMap::const_iterator aIter;
354 if (pToken && ((aIter = maTokenMatrixMap.find( pToken)) != maTokenMatrixMap.end()))
362 return const_cast<FormulaToken*
>((*aIter).second.get())->GetMatrix();
365 ScMatrixRef pMat = GetNewMat( nMatCols, nMatRows,
true);
366 if (!pMat || nGlobalError != FormulaError::NONE)
372 mrDoc.FillMatrix(*pMat, nTab1, nCol1, nRow1, nCol2, nRow2);
385 SCROW nNextRow = nRow1;
386 SCCOL nNextCol = nCol1;
388 SCROW nThisRow = nRow2;
389 SCCOL nThisCol = nCol1 - 1;
392 for (
bool bHas = aCellIter.
first(); bHas; bHas = aCellIter.
next())
396 if (nThisCol != nNextCol || nThisRow != nNextRow)
399 for ( ; nNextCol <= nThisCol; ++nNextCol)
401 const SCSIZE nC = nNextCol - nCol1;
402 const SCSIZE nMatStopRow = ((nNextCol < nThisCol) ? nMatRows : nThisRow - nRow1);
403 for (
SCSIZE nR = nNextRow - nRow1; nR < nMatStopRow; ++nR)
405 pMat->PutEmpty( nC, nR);
410 if (nThisRow == nRow2)
412 nNextCol = nThisCol + 1;
418 nNextRow = nThisRow + 1;
421 const SCSIZE nMatCol =
static_cast<SCSIZE>(nThisCol - nCol1);
422 const SCSIZE nMatRow =
static_cast<SCSIZE>(nThisRow - nRow1);
424 if (aCellIter.
isEmpty() || aCell.hasEmptyValue())
426 pMat->PutEmpty( nMatCol, nMatRow);
428 else if (aCell.hasError())
430 pMat->PutError( aCell.mpFormula->GetErrCode(), nMatCol, nMatRow);
432 else if (aCell.hasNumeric())
440 const ScAddress aAdr( nThisCol, nThisRow, nTab1);
441 const sal_uInt32 nNumFormat = mrDoc.GetNumberFormat(
mrContext, aAdr);
442 fVal = mrDoc.RoundValueAsShown( fVal, nNumFormat, &
mrContext);
444 pMat->PutDouble( fVal, nMatCol, nMatRow);
446 else if (aCell.hasString())
448 pMat->PutString( mrStrPool.intern( aCell.getString(&mrDoc)), nMatCol, nMatRow);
452 assert(!
"aCell.what?");
453 pMat->PutEmpty( nMatCol, nMatRow);
458 if (nThisCol != nCol2 || nThisRow != nRow2)
460 for ( ; nNextCol <= nCol2; ++nNextCol)
462 SCSIZE nC = nNextCol - nCol1;
463 for (
SCSIZE nR = nNextRow - nRow1; nR < nMatRows; ++nR)
465 pMat->PutEmpty( nC, nR);
481 switch (GetRawStackType())
486 PopSingleRef( aAdr );
487 pMat = GetNewMat(1, 1);
492 pMat->PutEmpty(0, 0);
494 pMat->PutDouble(GetCellValue(aAdr, aCell), 0);
498 GetCellString(aStr, aCell);
499 pMat->PutString(aStr, 0);
510 PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
511 pMat = CreateMatrixFromDoubleRef( p, nCol1, nRow1, nTab1,
512 nCol2, nRow2, nTab2);
522 double fVal = GetDouble();
523 pMat = GetNewMat( 1, 1);
526 if ( nGlobalError != FormulaError::NONE )
529 nGlobalError = FormulaError::NONE;
531 pMat->PutDouble( fVal, 0);
538 pMat = GetNewMat( 1, 1);
541 if ( nGlobalError != FormulaError::NONE )
544 pMat->PutDouble( fVal, 0);
545 nGlobalError = FormulaError::NONE;
548 pMat->PutString(aStr, 0);
555 PopExternalSingleRef(pToken);
556 pMat = GetNewMat( 1, 1,
true);
559 if (nGlobalError != FormulaError::NONE)
561 pMat->PutError( nGlobalError, 0, 0);
562 nGlobalError = FormulaError::NONE;
565 switch (pToken->GetType())
568 pMat->PutError( pToken->GetError(), 0, 0);
571 pMat->PutDouble( pToken->GetDouble(), 0, 0);
574 pMat->PutString( pToken->GetString(), 0, 0);
582 PopExternalDoubleRef(pMat);
586 SetError( FormulaError::IllegalArgument);
594 switch (GetRawStackType())
599 PopDoubleRef( aRange, rParam, rRefInList);
600 if (nGlobalError != FormulaError::NONE)
606 aRange.
GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
607 return CreateMatrixFromDoubleRef(
nullptr, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
618 switch (GetRawStackType())
621 aRet = PopRangeMatrix();
624 aRet.
mpMat = GetMatrix();
631 if ( !MustHaveParamCount( GetByte(), 3 ) )
639 if (nGlobalError != FormulaError::NONE)
641 PushError( nGlobalError);
644 switch (GetStackType())
649 PopSingleRef( aAdr );
654 if (nErrCode != FormulaError::NONE)
655 PushError( nErrCode);
659 CalculateMatrixValue(pMat,nC,nR);
663 PushIllegalParameter();
674 PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
675 if (nCol2 - nCol1 >= static_cast<SCCOL>(nR) &&
676 nRow2 - nRow1 >= static_cast<SCROW>(nC) &&
679 ScAddress aAdr( sal::static_int_cast<SCCOL>( nCol1 + nR ),
680 sal::static_int_cast<SCROW>( nRow1 + nC ), nTab1 );
683 PushDouble(GetCellValue(aAdr, aCell));
687 GetCellString(aStr, aCell);
698 CalculateMatrixValue(pMat.get(),nC,nR);
703 PushIllegalParameter();
713 if (nC < nCl && nR < nRw)
720 PushDouble(nMatVal.
fVal);
732 if ( !MustHaveParamCount( GetByte(), 1 ) )
736 if (nGlobalError != FormulaError::NONE || nDim == 0)
737 PushIllegalArgument();
739 PushError( FormulaError::MatrixSize);
749 PushIllegalArgument();
755 mM->FillDouble(0.0, 0, 0, n-1, n-1);
757 mM->PutDouble(1.0,
i,
i);
780 ::std::vector< SCSIZE> & P )
784 ::std::vector< double> aScale(n);
788 for (
SCSIZE j=0; j < n; ++j)
796 aScale[
i] = 1.0 / fMax;
803 for (
SCSIZE k=0; k < l; ++k)
808 double fScale = aScale[k];
812 double fTmp = fScale * fabs( mA->
GetDouble( k,
i));
830 double fTmp = aScale[k];
831 aScale[k] = aScale[kp];
847 for (
SCSIZE j = k+1; j < n; ++j)
852 #ifdef DEBUG_SC_LUP_DECOMPOSITION
853 fprintf( stderr,
"\n%s\n",
"lcl_LUP_decompose(): LU");
856 for (
SCSIZE j=0; j < n; ++j)
857 fprintf( stderr,
"%8.2g ", mA->
GetDouble( j,
i));
858 fprintf( stderr,
"\n%s\n",
"");
860 fprintf( stderr,
"\n%s\n",
"lcl_LUP_decompose(): P");
861 for (
SCSIZE j=0; j < n; ++j)
862 fprintf( stderr,
"%5u ", (
unsigned)P[j]);
863 fprintf( stderr,
"\n%s\n",
"");
866 bool bSingular=
false;
881 const ::std::vector< SCSIZE> & P, const ::std::vector< double> & B,
882 ::std::vector< double> & X )
896 for (
SCSIZE j = nFirst; j <
i; ++j)
907 for (
SCSIZE j =
i+1; j < n; ++j)
911 #ifdef DEBUG_SC_LUP_DECOMPOSITION
912 fprintf( stderr,
"\n%s\n",
"lcl_LUP_solve():");
914 fprintf( stderr,
"%8.2g ", X[
i]);
915 fprintf( stderr,
"%s\n",
"");
921 if ( !MustHaveParamCount( GetByte(), 1 ) )
927 PushIllegalParameter();
930 if ( !pMat->IsNumeric() )
936 pMat->GetDimensions(nC, nR);
937 if ( nC != nR || nC == 0 )
938 PushIllegalArgument();
940 PushError( FormulaError::MatrixSize);
946 PushError( FormulaError::CodeOverflow);
949 ::std::vector< SCSIZE> P(nR);
957 double fDet = nDetSign;
959 fDet *= xLU->GetDouble(
i,
i);
968 if ( !MustHaveParamCount( GetByte(), 1 ) )
974 PushIllegalParameter();
977 if ( !pMat->IsNumeric() )
983 pMat->GetDimensions(nC, nR);
988 if (pInterpreter !=
nullptr)
999 if ( nC != nR || nC == 0 )
1000 PushIllegalArgument();
1002 PushError( FormulaError::MatrixSize);
1010 PushError( FormulaError::CodeOverflow);
1013 ::std::vector< SCSIZE> P(nR);
1016 PushIllegalArgument();
1020 ::std::vector< double>
B(nR);
1021 ::std::vector< double>
X(nR);
1022 for (
SCSIZE j=0; j < nR; ++j)
1029 xY->PutDouble( X[
i], j, i);
1031 #ifdef DEBUG_SC_LUP_DECOMPOSITION
1049 const double fInvEpsilon = 1.0E-7;
1054 lcl_MFastMult( pMat, xY.get(), pR, nR, nR, nR);
1055 fprintf( stderr,
"\n%s\n",
"ScMatInv(): mult-identity");
1058 for (
SCSIZE j=0; j < nR; ++j)
1061 fprintf( stderr,
"%8.2g ", fTmp);
1062 if (fabs( fTmp - (
i == j)) > fInvEpsilon)
1063 SetError( FormulaError::IllegalArgument);
1065 fprintf( stderr,
"\n%s\n",
"");
1069 if (nGlobalError != FormulaError::NONE)
1070 PushError( nGlobalError);
1080 if ( !MustHaveParamCount( GetByte(), 2 ) )
1088 if ( pMat1->IsNumeric() && pMat2->IsNumeric() )
1092 pMat1->GetDimensions(nC1, nR1);
1093 pMat2->GetDimensions(nC2, nR2);
1095 PushIllegalArgument();
1098 pRMat = GetNewMat(nC2, nR1,
true);
1104 for (
SCSIZE j = 0; j < nC2; j++)
1107 for (
SCSIZE k = 0; k < nC1; k++)
1109 fSum += pMat1->GetDouble(k,
i)*pMat2->GetDouble(j,k);
1111 pRMat->PutDouble(fSum.
get(), j,
i);
1117 PushIllegalArgument();
1124 PushIllegalParameter();
1129 if ( !MustHaveParamCount( GetByte(), 1 ) )
1137 pMat->GetDimensions(nC, nR);
1138 pRMat = GetNewMat(nR, nC,
true);
1141 pMat->MatTrans(*pRMat);
1145 PushIllegalArgument();
1148 PushIllegalParameter();
1167 template<
class Function>
1183 for (i = 0; i < nMinC; i++)
1185 for (j = 0; j < nMinR; j++)
1193 xResMat->PutDouble( d, i, j);
1198 xResMat->PutError( nErr, i, j);
1204 double fVal1 = (bVal1 ? rMat1.
GetDouble(i,j) :
1209 double fVal2 = (bVal2 ? rMat2.
GetDouble(i,j) :
1212 if (nError1 != FormulaError::NONE)
1213 xResMat->PutError( nError1, i, j);
1214 else if (nError2 != FormulaError::NONE)
1215 xResMat->PutError( nError2, i, j);
1218 double d =
Op( fVal1, fVal2);
1219 xResMat->PutDouble( d, i, j);
1223 xResMat->PutError( FormulaError::NoValue, i, j);
1234 pMat1->GetDimensions(nC1, nR1);
1235 pMat2->GetDimensions(nC2, nR2);
1238 ScMatrixRef xResMat = GetNewMat(nMinC, nMinR,
true);
1241 xResMat->MatConcat(nMinC, nMinR, pMat1, pMat2, *pFormatter, mrDoc.GetSharedStringPool());
1249 if ( nFmt1 == SvNumFormatType::UNDEFINED && nFmt2 == SvNumFormatType::UNDEFINED )
1252 if ( nFmt1 == nFmt2 )
1254 if ( nFmt1 == SvNumFormatType::TIME || nFmt1 == SvNumFormatType::DATETIME
1255 || nFmt1 == SvNumFormatType::DURATION )
1256 nFuncFmt = SvNumFormatType::DURATION;
1259 else if ( nFmt1 == SvNumFormatType::UNDEFINED )
1261 else if ( nFmt2 == SvNumFormatType::UNDEFINED )
1265 if ( nFmt1 == SvNumFormatType::DATE || nFmt2 == SvNumFormatType::DATE ||
1266 nFmt1 == SvNumFormatType::DATETIME || nFmt2 == SvNumFormatType::DATETIME )
1268 if ( nFmt1 == SvNumFormatType::TIME || nFmt2 == SvNumFormatType::TIME )
1269 nFuncFmt = SvNumFormatType::DATETIME;
1276 CalculateAddSub(
false);
1283 double fVal1 = 0.0, fVal2 = 0.0;
1285 nFmt1 = nFmt2 = SvNumFormatType::UNDEFINED;
1287 sal_uLong nFmtCurrencyIndex = nCurFmtIndex;
1290 pMat2 = GetMatrix();
1293 fVal2 = GetDouble();
1294 switch ( nCurFmtType )
1296 case SvNumFormatType::DATE :
1297 case SvNumFormatType::TIME :
1298 case SvNumFormatType::DATETIME :
1299 case SvNumFormatType::DURATION :
1300 nFmt2 = nCurFmtType;
1302 case SvNumFormatType::CURRENCY :
1303 nFmtCurrencyType = nCurFmtType;
1304 nFmtCurrencyIndex = nCurFmtIndex;
1306 case SvNumFormatType::PERCENT :
1307 nFmtPercentType = SvNumFormatType::PERCENT;
1313 pMat1 = GetMatrix();
1316 fVal1 = GetDouble();
1317 switch ( nCurFmtType )
1319 case SvNumFormatType::DATE :
1320 case SvNumFormatType::TIME :
1321 case SvNumFormatType::DATETIME :
1322 case SvNumFormatType::DURATION :
1323 nFmt1 = nCurFmtType;
1325 case SvNumFormatType::CURRENCY :
1326 nFmtCurrencyType = nCurFmtType;
1327 nFmtCurrencyIndex = nCurFmtIndex;
1329 case SvNumFormatType::PERCENT :
1330 nFmtPercentType = SvNumFormatType::PERCENT;
1340 pResMat = lcl_MatrixCalculation<MatrixSub>( *pMat1, *pMat2,
this);
1344 pResMat = lcl_MatrixCalculation<MatrixAdd>( *pMat1, *pMat2,
this);
1350 PushMatrix(pResMat);
1352 else if (pMat1 || pMat2)
1369 pMat->GetDimensions(nC, nR);
1375 pMat->SubOp( bFlag, fVal, *pResMat);
1379 pMat->AddOp( fVal, *pResMat);
1381 PushMatrix(pResMat);
1384 PushIllegalArgument();
1389 if ( nFmtCurrencyType == SvNumFormatType::CURRENCY )
1391 nFuncFmtType = nFmtCurrencyType;
1392 nFuncFmtIndex = nFmtCurrencyIndex;
1397 if (nFmtPercentType == SvNumFormatType::PERCENT && nFuncFmtType == SvNumFormatType::NUMBER)
1398 nFuncFmtType = SvNumFormatType::PERCENT;
1401 PushDouble( ::rtl::math::approxSub( fVal1, fVal2 ) );
1403 PushDouble( ::rtl::math::approxAdd( fVal1, fVal2 ) );
1411 OUString sStr1, sStr2;
1413 pMat2 = GetMatrix();
1417 pMat1 = GetMatrix();
1426 PushMatrix(pResMat);
1428 else if (pMat1 || pMat2)
1445 pMat->GetDimensions(nC, nR);
1449 if (nGlobalError != FormulaError::NONE)
1452 for (
SCSIZE j = 0; j < nR; ++j)
1453 pResMat->PutError( nGlobalError,
i, j);
1458 for (
SCSIZE j = 0; j < nR; ++j)
1461 if (nErr != FormulaError::NONE)
1462 pResMat->PutError( nErr,
i, j);
1465 OUString aTmp = sStr + pMat->GetString(*pFormatter,
i, j).getString();
1466 pResMat->PutString(mrStrPool.intern(aTmp),
i, j);
1473 for (
SCSIZE j = 0; j < nR; ++j)
1476 if (nErr != FormulaError::NONE)
1477 pResMat->PutError( nErr,
i, j);
1480 OUString aTmp = pMat->GetString(*pFormatter,
i, j).getString() + sStr;
1481 pResMat->PutString(mrStrPool.intern(aTmp),
i, j);
1485 PushMatrix(pResMat);
1488 PushIllegalArgument();
1492 if ( CheckStringResultLen( sStr1, sStr2.getLength() ) )
1500 CalculateAddSub(
true);
1507 double fVal1 = 0.0, fVal2 = 0.0;
1509 sal_uLong nFmtCurrencyIndex = nCurFmtIndex;
1511 pMat2 = GetMatrix();
1514 fVal2 = GetDouble();
1515 switch ( nCurFmtType )
1517 case SvNumFormatType::CURRENCY :
1518 nFmtCurrencyType = nCurFmtType;
1519 nFmtCurrencyIndex = nCurFmtIndex;
1525 pMat1 = GetMatrix();
1528 fVal1 = GetDouble();
1529 switch ( nCurFmtType )
1531 case SvNumFormatType::CURRENCY :
1532 nFmtCurrencyType = nCurFmtType;
1533 nFmtCurrencyIndex = nCurFmtIndex;
1540 ScMatrixRef pResMat = lcl_MatrixCalculation<MatrixMul>( *pMat1, *pMat2,
this);
1544 PushMatrix(pResMat);
1546 else if (pMat1 || pMat2)
1558 pMat->GetDimensions(nC, nR);
1562 pMat->MulOp( fVal, *pResMat);
1563 PushMatrix(pResMat);
1566 PushIllegalArgument();
1571 if ( nFmtCurrencyType == SvNumFormatType::CURRENCY )
1573 nFuncFmtType = nFmtCurrencyType;
1574 nFuncFmtIndex = nFmtCurrencyIndex;
1576 PushDouble(fVal1 * fVal2);
1584 double fVal1 = 0.0, fVal2 = 0.0;
1586 sal_uLong nFmtCurrencyIndex = nCurFmtIndex;
1589 pMat2 = GetMatrix();
1592 fVal2 = GetDouble();
1594 nFmtCurrencyType2 = nCurFmtType;
1597 pMat1 = GetMatrix();
1600 fVal1 = GetDouble();
1601 switch ( nCurFmtType )
1603 case SvNumFormatType::CURRENCY :
1604 nFmtCurrencyType = nCurFmtType;
1605 nFmtCurrencyIndex = nCurFmtIndex;
1612 ScMatrixRef pResMat = lcl_MatrixCalculation<MatrixDiv>( *pMat1, *pMat2,
this);
1616 PushMatrix(pResMat);
1618 else if (pMat1 || pMat2)
1635 pMat->GetDimensions(nC, nR);
1639 pMat->DivOp( bFlag, fVal, *pResMat);
1640 PushMatrix(pResMat);
1643 PushIllegalArgument();
1648 if ( nFmtCurrencyType == SvNumFormatType::CURRENCY &&
1649 nFmtCurrencyType2 != SvNumFormatType::CURRENCY)
1651 nFuncFmtType = nFmtCurrencyType;
1652 nFuncFmtIndex = nFmtCurrencyIndex;
1654 PushDouble(
div( fVal1, fVal2) );
1660 if ( MustHaveParamCount( GetByte(), 2 ) )
1668 double fVal1 = 0.0, fVal2 = 0.0;
1670 pMat2 = GetMatrix();
1672 fVal2 = GetDouble();
1674 pMat1 = GetMatrix();
1676 fVal1 = GetDouble();
1679 ScMatrixRef pResMat = lcl_MatrixCalculation<MatrixPow>( *pMat1, *pMat2,
this);
1683 PushMatrix(pResMat);
1685 else if (pMat1 || pMat2)
1702 pMat->GetDimensions(nC, nR);
1706 pMat->PowOp( bFlag, fVal, *pResMat);
1707 PushMatrix(pResMat);
1710 PushIllegalArgument();
1721 if ( !MustHaveParamCountMin( nParamCount, 1) )
1728 size_t nInRefList = 0;
1732 pMatLast = GetMatrix( --nParamCount, nInRefList);
1735 PushIllegalParameter();
1739 SCSIZE nC, nCLast, nR, nRLast;
1740 pMatLast->GetDimensions(nCLast, nRLast);
1741 std::vector<double> aResArray;
1742 pMatLast->GetDoubleArray(aResArray);
1744 while (nParamCount--)
1746 pMat = GetMatrix( nParamCount, nInRefList);
1749 PushIllegalParameter();
1752 pMat->GetDimensions(nC, nR);
1753 if (nC != nCLast || nR != nRLast)
1759 pMat->MergeDoubleArrayMultiply(aResArray);
1763 for(
double fPosArray : aResArray )
1766 if (nErr == FormulaError::NONE)
1768 else if (nErr != FormulaError::ElementNaN)
1776 PushDouble(fSum.
get());
1781 CalculateSumX2MY2SumX2DY2(
false);
1785 if ( !MustHaveParamCount( GetByte(), 2 ) )
1791 pMat2 = GetMatrix();
1792 pMat1 = GetMatrix();
1793 if (!pMat2 || !pMat1)
1795 PushIllegalParameter();
1800 pMat2->GetDimensions(nC2, nR2);
1801 pMat1->GetDimensions(nC1, nR1);
1802 if (nC1 != nC2 || nR1 != nR2)
1809 for (i = 0; i < nC1; i++)
1810 for (j = 0; j < nR1; j++)
1811 if (!pMat1->IsStringOrEmpty(i,j) && !pMat2->IsStringOrEmpty(i,j))
1813 fVal = pMat1->GetDouble(i,j);
1814 fSum += fVal * fVal;
1815 fVal = pMat2->GetDouble(i,j);
1817 fSum += fVal * fVal;
1819 fSum -= fVal * fVal;
1821 PushDouble(fSum.
get());
1826 CalculateSumX2MY2SumX2DY2(
true);
1831 if ( !MustHaveParamCount( GetByte(), 2 ) )
1836 if (!pMat2 || !pMat1)
1838 PushIllegalParameter();
1843 pMat2->GetDimensions(nC2, nR2);
1844 pMat1->GetDimensions(nC1, nR1);
1845 if (nC1 != nC2 || nR1 != nR2)
1850 ScMatrixRef pResMat = lcl_MatrixCalculation<MatrixSub>( *pMat1, *pMat2,
this);
1857 PushDouble(pResMat->SumSquare(
false).maAccumulator.get());
1863 if ( !MustHaveParamCount( GetByte(), 2 ) )
1866 vector<double> aBinArray;
1867 vector<tools::Long> aBinIndexOrder;
1869 GetSortArray( 1, aBinArray, &aBinIndexOrder,
false,
false );
1870 SCSIZE nBinSize = aBinArray.size();
1871 if (nGlobalError != FormulaError::NONE)
1877 vector<double> aDataArray;
1878 GetSortArray( 1, aDataArray,
nullptr,
false,
false );
1879 SCSIZE nDataSize = aDataArray.size();
1881 if (aDataArray.empty() || nGlobalError != FormulaError::NONE)
1886 ScMatrixRef pResMat = GetNewMat(1, nBinSize+1,
true);
1889 PushIllegalArgument();
1893 if (nBinSize != aBinIndexOrder.size())
1895 PushIllegalArgument();
1901 for (j = 0; j < nBinSize; ++j)
1904 while (i < nDataSize && aDataArray[i] <= aBinArray[j])
1909 pResMat->PutDouble(static_cast<double>(nCount), aBinIndexOrder[j]);
1911 pResMat->PutDouble(static_cast<double>(nDataSize-i), j);
1912 PushMatrix(pResMat);
1928 fSum += pMatA->GetDouble(i) * pMatB->GetDouble(i);
1938 for (
SCSIZE row=nR; row<nN; row++)
1939 fNorm += (pMatA->GetDouble(nC,row)) * (pMatA->GetDouble(nC,row));
1940 return sqrt(fNorm.
get());
1948 for (
SCSIZE col=nC; col<nN; col++)
1949 fNorm += (pMatA->GetDouble(col,nR)) * (pMatA->GetDouble(col,nR));
1950 return sqrt(fNorm.
get());
1959 for (
SCSIZE row=nR; row<nN; row++)
1961 double fVal = fabs(pMatA->GetDouble(nC,row));
1973 for (
SCSIZE col=nC; col<nN; col++)
1975 double fVal = fabs(pMatA->GetDouble(col,nR));
1989 for (
SCSIZE row=nR; row<nN; row++)
1990 fResult += pMatA->GetDouble(nCa,row) * pMatB->GetDouble(nCb,row);
1991 return fResult.
get();
2000 for (
SCSIZE col=nC; col<nN; col++)
2001 fResult += pMatA->GetDouble(col,nRa) * pMatB->GetDouble(col,nRb);
2002 return fResult.
get();
2006 double lcl_GetSign(
double fValue)
2008 return (fValue >= 0.0 ? 1.0 : -1.0 );
2024 bool lcl_CalculateQRdecomposition(
const ScMatrixRef& pMatA,
2028 for (
SCSIZE col = 0; col <nK; col++)
2031 const double fScale = lcl_GetColumnMaximumNorm(pMatA, col, col, nN);
2037 for (
SCSIZE row = col; row <nN; row++)
2038 pMatA->PutDouble( pMatA->GetDouble(col,row)/fScale, col, row);
2040 const double fEuclid = lcl_GetColumnEuclideanNorm(pMatA, col, col, nN);
2041 const double fFactor = 1.0/fEuclid/(fEuclid + fabs(pMatA->GetDouble(col,col)));
2042 const double fSignum = lcl_GetSign(pMatA->GetDouble(col,col));
2043 pMatA->PutDouble( pMatA->GetDouble(col,col) + fSignum*fEuclid, col,col);
2044 pVecR[col] = -fSignum * fScale * fEuclid;
2047 for (
SCSIZE c=col+1; c<nK; c++)
2049 const double fSum =lcl_GetColumnSumProduct(pMatA, col, pMatA, c, col, nN);
2050 for (
SCSIZE row = col; row <nN; row++)
2051 pMatA->PutDouble( pMatA->GetDouble(c,row) - fSum * fFactor * pMatA->GetDouble(col,row), c, row);
2058 bool lcl_TCalculateQRdecomposition(
const ScMatrixRef& pMatA,
2063 for (
SCSIZE row = 0; row <nK; row++)
2066 const double fScale = lcl_TGetColumnMaximumNorm(pMatA, row, row, nN);
2072 for (
SCSIZE col = row; col <nN; col++)
2073 pMatA->PutDouble( pMatA->GetDouble(col,row)/fScale, col, row);
2075 const double fEuclid = lcl_TGetColumnEuclideanNorm(pMatA, row, row, nN);
2076 const double fFactor = 1.0/fEuclid/(fEuclid + fabs(pMatA->GetDouble(row,row)));
2077 const double fSignum = lcl_GetSign(pMatA->GetDouble(row,row));
2078 pMatA->PutDouble( pMatA->GetDouble(row,row) + fSignum*fEuclid, row,row);
2079 pVecR[row] = -fSignum * fScale * fEuclid;
2082 for (
SCSIZE r=row+1; r<nK; r++)
2084 fSum =lcl_TGetColumnSumProduct(pMatA, row, pMatA, r, row, nN);
2085 for (
SCSIZE col = row; col <nN; col++)
2087 pMatA->GetDouble(col,r) - fSum * fFactor * pMatA->GetDouble(col,row), col, r);
2103 double fDenominator = lcl_GetColumnSumProduct(pMatA, nC, pMatA, nC, nC, nN);
2104 double fNumerator = lcl_GetColumnSumProduct(pMatA, nC, pMatY, 0, nC, nN);
2105 double fFactor = 2.0 * (fNumerator/fDenominator);
2106 for (
SCSIZE row = nC; row < nN; row++)
2108 pMatY->GetDouble(row) - fFactor * pMatA->GetDouble(nC,row), row);
2116 double fDenominator = lcl_TGetColumnSumProduct(pMatA, nR, pMatA, nR, nR, nN);
2117 double fNumerator = lcl_TGetColumnSumProduct(pMatA, nR, pMatY, 0, nR, nN);
2118 double fFactor = 2.0 * (fNumerator/fDenominator);
2119 for (
SCSIZE col = nR; col < nN; col++)
2121 pMatY->GetDouble(col) - fFactor * pMatA->GetDouble(col,nR), col);
2130 void lcl_SolveWithUpperRightTriangle(
const ScMatrixRef& pMatA,
2131 ::std::vector< double>& pVecR,
const ScMatrixRef& pMatS,
2132 SCSIZE nK,
bool bIsTransposed)
2137 for (
SCSIZE rowp1 = nK; rowp1>0; rowp1--)
2140 KahanSum fSum = pMatS->GetDouble(row);
2141 for (
SCSIZE col = rowp1; col<nK ; col++)
2143 fSum -= pMatA->GetDouble(row,col) * pMatS->GetDouble(col);
2145 fSum -= pMatA->GetDouble(col,row) * pMatS->GetDouble(col);
2146 pMatS->PutDouble( fSum.
get() / pVecR[row] , row);
2156 void lcl_SolveWithLowerLeftTriangle(
const ScMatrixRef& pMatA,
2157 ::std::vector< double>& pVecR,
const ScMatrixRef& pMatT,
2158 SCSIZE nK,
bool bIsTransposed)
2161 for (
SCSIZE row = 0; row < nK; row++)
2163 KahanSum fSum = pMatT -> GetDouble(row);
2164 for (
SCSIZE col=0; col < row; col++)
2167 fSum -= pMatA->GetDouble(col,row) * pMatT->GetDouble(col);
2169 fSum -= pMatA->GetDouble(row,col) * pMatT->GetDouble(col);
2171 pMatT->PutDouble( fSum.
get() / pVecR[row] , row);
2181 void lcl_ApplyUpperRightTriangle(
const ScMatrixRef& pMatA,
2182 ::std::vector< double>& pVecR,
const ScMatrixRef& pMatB,
2186 for (
SCSIZE row = 0; row < nK; row++)
2188 KahanSum fSum = pVecR[row] * pMatB->GetDouble(row);
2189 for (
SCSIZE col = row+1; col < nK; col++)
2191 fSum += pMatA->GetDouble(row,col) * pMatB->GetDouble(col);
2193 fSum += pMatA->GetDouble(col,row) * pMatB->GetDouble(col);
2194 pMatZ->PutDouble( fSum.
get(), row);
2202 fSum += pMat->GetDouble(i);
2203 return fSum.
get()/
static_cast<double>(nN);
2214 for (
SCSIZE k=0; k < nR; k++)
2215 fSum += pX->GetDouble(i,k);
2216 pResMat ->PutDouble( fSum.
get()/
static_cast<double>(nR),i);
2225 for (
SCSIZE k=0; k < nR; k++)
2229 fSum += pX->GetDouble(i,k);
2230 pResMat ->PutDouble( fSum.
get()/
static_cast<double>(nC),k);
2238 for (
SCSIZE k = 0; k < nR; k++)
2239 pMat->PutDouble( ::rtl::math::approxSub
2240 (pMat->GetDouble(i,k) , pColumnMeans->GetDouble(i) ) , i, k);
2246 for (
SCSIZE k = 0; k < nR; k++)
2248 pMat->PutDouble( ::rtl::math::approxSub
2249 ( pMat->GetDouble(i,k) , pRowMeans->GetDouble(k) ) , i, k);
2261 const double fTemp = pMatY->GetDouble(i) - fSlope * pMatX->GetDouble(i);
2262 fSum += fTemp * fTemp;
2283 pMatY->GetDimensions(nCY, nRY);
2284 const SCSIZE nCountY = nCY * nRY;
2287 if (!pMatY->IsValue(
i))
2289 PushIllegalArgument();
2297 for (
SCSIZE nElem = 0; nElem < nCountY; nElem++)
2299 const double fVal = pNewY->GetDouble(nElem);
2302 PushIllegalArgument();
2306 pNewY->PutDouble(
log(fVal), nElem);
2313 pMatX->GetDimensions(nCX, nRX);
2314 const SCSIZE nCountX = nCX * nRX;
2316 if (!pMatX->IsValue(
i))
2318 PushIllegalArgument();
2321 if (nCX == nCY && nRX == nRY)
2327 else if (nCY != 1 && nRY != 1)
2329 PushIllegalArgument();
2336 PushIllegalArgument();
2346 else if (nCX != nCY)
2348 PushIllegalArgument();
2360 pMatX = GetNewMat(nCY, nRY,
true);
2365 PushIllegalArgument();
2369 pMatX->PutDouble(static_cast<double>(
i),
i-1);
2380 CalculateRGPRKP(
false);
2386 CalculateRGPRKP(
true);
2392 if (!MustHaveParamCount( nParamCount, 1, 4 ))
2394 bool bConstant, bStats;
2397 if (nParamCount == 4)
2404 if (nParamCount >= 3)
2414 bConstant = GetBool();
2420 if (nParamCount >= 2)
2429 pMatX = GetMatrix();
2438 PushIllegalParameter();
2448 if (!CheckMatrix(_bRKP,nCase,nCX,nCY,nRX,nRY,K,
N,pMatX,pMatY))
2450 PushIllegalParameter();
2455 if ((bConstant && (
N<K+1)) || (!bConstant && (
N<K)) || (
N<1) || (K<1))
2457 PushIllegalParameter();
2463 pResMat = GetNewMat(K+1,5,
true);
2465 pResMat = GetNewMat(K+1,1,
true);
2468 PushError(FormulaError::CodeOverflow);
2476 pResMat->PutError( FormulaError::NotAvailable,
i, 2);
2477 pResMat->PutError( FormulaError::NotAvailable,
i, 3);
2478 pResMat->PutError( FormulaError::NotAvailable,
i, 4);
2484 double fMeanY = 0.0;
2489 if (!pNewX || !pNewY)
2491 PushError(FormulaError::CodeOverflow);
2497 fMeanY = lcl_GetMeanOverAll(pMatY,
N);
2500 pMatY->PutDouble( ::rtl::math::approxSub(pMatY->GetDouble(
i),fMeanY),
i );
2507 double fMeanX = 0.0;
2510 fMeanX = lcl_GetMeanOverAll(pMatX,
N);
2513 pMatX->PutDouble( ::rtl::math::approxSub(pMatX->GetDouble(
i),fMeanX),
i );
2516 double fSumXY = lcl_GetSumProduct(pMatX,pMatY,
N);
2517 double fSumX2 = lcl_GetSumProduct(pMatX,pMatX,
N);
2523 double fSlope = fSumXY / fSumX2;
2524 double fIntercept = 0.0;
2526 fIntercept = fMeanY - fSlope * fMeanX;
2527 pResMat->PutDouble(_bRKP ? exp(fIntercept) : fIntercept, 1, 0);
2528 pResMat->PutDouble(_bRKP ? exp(fSlope) : fSlope, 0, 0);
2532 double fSSreg = fSlope * fSlope * fSumX2;
2533 pResMat->PutDouble(fSSreg, 0, 4);
2535 double fDegreesFreedom =
static_cast<double>( bConstant ?
N-2 :
N-1 );
2536 pResMat->PutDouble(fDegreesFreedom, 1, 3);
2538 double fSSresid = lcl_GetSSresid(pMatX,pMatY,fSlope,
N);
2539 pResMat->PutDouble(fSSresid, 1, 4);
2541 if (fDegreesFreedom == 0.0 || fSSresid == 0.0 || fSSreg == 0.0)
2544 pResMat->PutDouble(0.0, 1, 4);
2545 pResMat->PutError( FormulaError::NotAvailable, 0, 3);
2546 pResMat->PutDouble(0.0, 1, 2);
2547 pResMat->PutDouble(0.0, 0, 1);
2549 pResMat->PutDouble(0.0, 1, 1);
2551 pResMat->PutError( FormulaError::NotAvailable, 1, 1);
2552 pResMat->PutDouble(1.0, 0, 2);
2556 double fFstatistic = (fSSreg /
static_cast<double>(K))
2557 / (fSSresid / fDegreesFreedom);
2558 pResMat->PutDouble(fFstatistic, 0, 3);
2561 double fRMSE = sqrt(fSSresid / fDegreesFreedom);
2562 pResMat->PutDouble(fRMSE, 1, 2);
2564 double fSigmaSlope = fRMSE / sqrt(fSumX2);
2565 pResMat->PutDouble(fSigmaSlope, 0, 1);
2569 double fSigmaIntercept = fRMSE
2570 * sqrt(fMeanX*fMeanX/fSumX2 + 1.0/static_cast<double>(
N));
2571 pResMat->PutDouble(fSigmaIntercept, 1, 1);
2575 pResMat->PutError( FormulaError::NotAvailable, 1, 1);
2578 double fR2 = fSSreg / (fSSreg + fSSresid);
2579 pResMat->PutDouble(fR2, 0, 2);
2582 PushMatrix(pResMat);
2590 ::std::vector< double> aVecR(
N);
2595 pMatZ = pMatY->Clone();
2599 if (!pMeans || !pMatZ || !pSlopes)
2601 PushError(FormulaError::CodeOverflow);
2606 lcl_CalculateColumnMeans(pMatX, pMeans, K,
N);
2607 lcl_CalculateColumnsDelta(pMatX, pMeans, K,
N);
2609 if (!lcl_CalculateQRdecomposition(pMatX, aVecR, K,
N))
2616 bool bIsSingular=
false;
2617 for (
SCSIZE row=0; row < K && !bIsSingular; row++)
2618 bIsSingular = aVecR[row] == 0.0;
2625 for (
SCSIZE col = 0; col < K; col++)
2627 lcl_ApplyHouseholderTransformation(pMatX, col, pMatZ,
N);
2631 for (
SCSIZE col = 0; col < K ; col++)
2633 pSlopes->PutDouble( pMatZ->GetDouble(col), col);
2635 lcl_SolveWithUpperRightTriangle(pMatX, aVecR, pSlopes, K,
false);
2636 double fIntercept = 0.0;
2638 fIntercept = fMeanY - lcl_GetSumProduct(pMeans,pSlopes,K);
2640 pResMat->PutDouble(_bRKP ? exp(fIntercept) : fIntercept, K, 0 );
2642 pResMat->PutDouble(_bRKP ? exp(pSlopes->GetDouble(
i))
2643 : pSlopes->GetDouble(
i) , K-1-
i, 0);
2647 double fSSreg = 0.0;
2648 double fSSresid = 0.0;
2650 pMatZ->FillDouble(0.0, 0, 0, 0,
N-1);
2652 lcl_ApplyUpperRightTriangle(pMatX, aVecR, pSlopes, pMatZ, K,
false);
2654 for (
SCSIZE colp1 = K; colp1 > 0; colp1--)
2656 lcl_ApplyHouseholderTransformation(pMatX, colp1-1, pMatZ,
N);
2658 fSSreg =lcl_GetSumProduct(pMatZ, pMatZ,
N);
2660 for (
SCSIZE row = 0; row <
N; row++)
2661 pMatY->PutDouble(pMatY->GetDouble(row) - pMatZ->GetDouble(row), row);
2662 fSSresid = lcl_GetSumProduct(pMatY, pMatY, N);
2663 pResMat->PutDouble(fSSreg, 0, 4);
2664 pResMat->PutDouble(fSSresid, 1, 4);
2666 double fDegreesFreedom =
static_cast<double>( bConstant ? N-K-1 : N-K );
2667 pResMat->PutDouble(fDegreesFreedom, 1, 3);
2669 if (fDegreesFreedom == 0.0 || fSSresid == 0.0 || fSSreg == 0.0)
2671 pResMat->PutDouble(0.0, 1, 4);
2673 pResMat->PutError( FormulaError::NotAvailable, 0, 3);
2675 pResMat->PutDouble(0.0, 1, 2);
2677 for (
SCSIZE i=0; i<K; i++)
2678 pResMat->PutDouble(0.0, K-1-i, 1);
2682 pResMat->PutDouble(0.0, K, 1);
2684 pResMat->PutError( FormulaError::NotAvailable, K, 1);
2687 pResMat->PutDouble(1.0, 0, 2);
2691 double fFstatistic = (fSSreg /
static_cast<double>(K))
2692 / (fSSresid / fDegreesFreedom);
2693 pResMat->PutDouble(fFstatistic, 0, 3);
2696 double fRMSE = sqrt(fSSresid / fDegreesFreedom);
2697 pResMat->PutDouble(fRMSE, 1, 2);
2707 for (
SCSIZE col = 0; col < K; col++)
2710 pMatZ->FillDouble(0.0,0,0,0,K-1);
2711 pMatZ->PutDouble(1.0, col);
2713 lcl_SolveWithLowerLeftTriangle(pMatX, aVecR, pMatZ, K,
false);
2715 lcl_SolveWithUpperRightTriangle(pMatX, aVecR, pMatZ, K,
false);
2717 double fSigmaSlope = fRMSE * sqrt(pMatZ->GetDouble(col));
2718 pResMat->PutDouble(fSigmaSlope, K-1-col, 1);
2722 fPart = lcl_GetSumProduct(pMeans, pMatZ, K);
2723 aSigmaIntercept += fPart * pMeans->GetDouble(col);
2728 double fSigmaIntercept = fRMSE
2729 * sqrt( (aSigmaIntercept + 1.0 / static_cast<double>(N) ).
get() );
2730 pResMat->PutDouble(fSigmaIntercept, K, 1);
2734 pResMat->PutError( FormulaError::NotAvailable, K, 1);
2737 double fR2 = fSSreg / (fSSreg + fSSresid);
2738 pResMat->PutDouble(fR2, 0, 2);
2741 PushMatrix(pResMat);
2745 ::std::vector< double> aVecR(
N);
2750 pMatZ = pMatY->Clone();
2754 if (!pMeans || !pMatZ || !pSlopes)
2756 PushError(FormulaError::CodeOverflow);
2761 lcl_CalculateRowMeans(pMatX, pMeans,
N, K);
2762 lcl_CalculateRowsDelta(pMatX, pMeans,
N, K);
2765 if (!lcl_TCalculateQRdecomposition(pMatX, aVecR, K,
N))
2773 bool bIsSingular=
false;
2774 for (
SCSIZE row=0; row < K && !bIsSingular; row++)
2775 bIsSingular = aVecR[row] == 0.0;
2782 for (
SCSIZE row = 0; row < K; row++)
2784 lcl_TApplyHouseholderTransformation(pMatX, row, pMatZ,
N);
2788 for (
SCSIZE col = 0; col < K ; col++)
2790 pSlopes->PutDouble( pMatZ->GetDouble(col), col);
2792 lcl_SolveWithUpperRightTriangle(pMatX, aVecR, pSlopes, K,
true);
2793 double fIntercept = 0.0;
2795 fIntercept = fMeanY - lcl_GetSumProduct(pMeans,pSlopes,K);
2797 pResMat->PutDouble(_bRKP ? exp(fIntercept) : fIntercept, K, 0 );
2799 pResMat->PutDouble(_bRKP ? exp(pSlopes->GetDouble(
i))
2800 : pSlopes->GetDouble(
i) , K-1-
i, 0);
2804 double fSSreg = 0.0;
2805 double fSSresid = 0.0;
2807 pMatZ->FillDouble(0.0, 0, 0,
N-1, 0);
2809 lcl_ApplyUpperRightTriangle(pMatX, aVecR, pSlopes, pMatZ, K,
true);
2811 for (
SCSIZE rowp1 = K; rowp1 > 0; rowp1--)
2813 lcl_TApplyHouseholderTransformation(pMatX, rowp1-1, pMatZ,
N);
2815 fSSreg =lcl_GetSumProduct(pMatZ, pMatZ,
N);
2817 for (
SCSIZE col = 0; col <
N; col++)
2818 pMatY->PutDouble(pMatY->GetDouble(col) - pMatZ->GetDouble(col), col);
2819 fSSresid = lcl_GetSumProduct(pMatY, pMatY, N);
2820 pResMat->PutDouble(fSSreg, 0, 4);
2821 pResMat->PutDouble(fSSresid, 1, 4);
2823 double fDegreesFreedom =
static_cast<double>( bConstant ? N-K-1 : N-K );
2824 pResMat->PutDouble(fDegreesFreedom, 1, 3);
2826 if (fDegreesFreedom == 0.0 || fSSresid == 0.0 || fSSreg == 0.0)
2828 pResMat->PutDouble(0.0, 1, 4);
2830 pResMat->PutError( FormulaError::NotAvailable, 0, 3);
2832 pResMat->PutDouble(0.0, 1, 2);
2834 for (
SCSIZE i=0; i<K; i++)
2835 pResMat->PutDouble(0.0, K-1-i, 1);
2839 pResMat->PutDouble(0.0, K, 1);
2841 pResMat->PutError( FormulaError::NotAvailable, K, 1);
2844 pResMat->PutDouble(1.0, 0, 2);
2848 double fFstatistic = (fSSreg /
static_cast<double>(K))
2849 / (fSSresid / fDegreesFreedom);
2850 pResMat->PutDouble(fFstatistic, 0, 3);
2853 double fRMSE = sqrt(fSSresid / fDegreesFreedom);
2854 pResMat->PutDouble(fRMSE, 1, 2);
2865 for (
SCSIZE row = 0; row < K; row++)
2868 pMatZ->FillDouble(0.0,0,0,K-1,0);
2869 pMatZ->PutDouble(1.0, row);
2871 lcl_SolveWithLowerLeftTriangle(pMatX, aVecR, pMatZ, K,
true);
2873 lcl_SolveWithUpperRightTriangle(pMatX, aVecR, pMatZ, K,
true);
2875 double fSigmaSlope = fRMSE * sqrt(pMatZ->GetDouble(row));
2876 pResMat->PutDouble(fSigmaSlope, K-1-row, 1);
2879 fPart = lcl_GetSumProduct(pMeans, pMatZ, K);
2880 aSigmaIntercept += fPart * pMeans->GetDouble(row);
2885 double fSigmaIntercept = fRMSE
2886 * sqrt( (aSigmaIntercept + 1.0 / static_cast<double>(N) ).
get() );
2887 pResMat->PutDouble(fSigmaIntercept, K, 1);
2891 pResMat->PutError( FormulaError::NotAvailable, K, 1);
2894 double fR2 = fSSreg / (fSSreg + fSSresid);
2895 pResMat->PutDouble(fR2, 0, 2);
2898 PushMatrix(pResMat);
2905 CalculateTrendGrowth(
false);
2910 CalculateTrendGrowth(
true);
2916 if (!MustHaveParamCount( nParamCount, 1, 4 ))
2921 if (nParamCount == 4)
2922 bConstant = GetBool();
2929 if (nParamCount >= 3)
2937 pMatNewX = GetMatrix();
2945 if (nParamCount >= 2)
2954 pMatX = GetMatrix();
2963 PushIllegalParameter();
2973 if (!CheckMatrix(_bGrowth,nCase,nCX,nCY,nRX,nRY,K,
N,pMatX,pMatY))
2975 PushIllegalParameter();
2980 if ((bConstant && (
N<K+1)) || (!bConstant && (
N<K)) || (
N<1) || (K<1))
2982 PushIllegalParameter();
2993 nCountXN = nCXN * nRXN;
2994 pMatNewX = pMatX->Clone();
2998 pMatNewX->GetDimensions(nCXN, nRXN);
2999 if ((nCase == 2 && K != nCXN) || (nCase == 3 && K != nRXN))
3001 PushIllegalArgument();
3004 nCountXN = nCXN * nRXN;
3006 if (!pMatNewX->IsValue(
i))
3008 PushIllegalArgument();
3014 pResMat = GetNewMat(nCXN,nRXN,
true);
3018 pResMat = GetNewMat(1,nRXN,
true);
3020 pResMat = GetNewMat(nCXN,1,
true);
3024 PushError(FormulaError::CodeOverflow);
3029 double fMeanY = 0.0;
3034 if (!pCopyX || !pCopyY)
3036 PushError(FormulaError::MatrixSize);
3042 fMeanY = lcl_GetMeanOverAll(pMatY,
N);
3045 pMatY->PutDouble( ::rtl::math::approxSub(pMatY->GetDouble(
i),fMeanY),
i );
3052 double fMeanX = 0.0;
3055 fMeanX = lcl_GetMeanOverAll(pMatX,
N);
3058 pMatX->PutDouble( ::rtl::math::approxSub(pMatX->GetDouble(
i),fMeanX),
i );
3061 double fSumXY = lcl_GetSumProduct(pMatX,pMatY,
N);
3062 double fSumX2 = lcl_GetSumProduct(pMatX,pMatX,
N);
3068 double fSlope = fSumXY / fSumX2;
3072 double fIntercept = fMeanY - fSlope * fMeanX;
3075 fHelp = pMatNewX->GetDouble(
i)*fSlope + fIntercept;
3076 pResMat->PutDouble(_bGrowth ? exp(fHelp) : fHelp,
i);
3083 fHelp = pMatNewX->GetDouble(
i)*fSlope;
3084 pResMat->PutDouble(_bGrowth ? exp(fHelp) : fHelp,
i);
3092 ::std::vector< double> aVecR(
N);
3096 if (!pMeans || !pSlopes)
3098 PushError(FormulaError::CodeOverflow);
3103 lcl_CalculateColumnMeans(pMatX, pMeans, K,
N);
3104 lcl_CalculateColumnsDelta(pMatX, pMeans, K,
N);
3106 if (!lcl_CalculateQRdecomposition(pMatX, aVecR, K,
N))
3113 bool bIsSingular=
false;
3114 for (
SCSIZE row=0; row < K && !bIsSingular; row++)
3115 bIsSingular = aVecR[row] == 0.0;
3122 for (
SCSIZE col = 0; col < K; col++)
3124 lcl_ApplyHouseholderTransformation(pMatX, col, pMatY,
N);
3128 for (
SCSIZE col = 0; col < K ; col++)
3130 pSlopes->PutDouble( pMatY->GetDouble(col), col);
3132 lcl_SolveWithUpperRightTriangle(pMatX, aVecR, pSlopes, K,
false);
3135 lcl_MFastMult(pMatNewX,pSlopes,pResMat,nRXN,K,1);
3138 double fIntercept = fMeanY - lcl_GetSumProduct(pMeans,pSlopes,K);
3139 for (
SCSIZE row = 0; row < nRXN; row++)
3140 pResMat->PutDouble(pResMat->GetDouble(row)+fIntercept, row);
3145 pResMat->PutDouble(exp(pResMat->GetDouble(
i)),
i);
3151 ::std::vector< double> aVecR(
N);
3155 if (!pMeans || !pSlopes)
3157 PushError(FormulaError::CodeOverflow);
3162 lcl_CalculateRowMeans(pMatX, pMeans,
N, K);
3163 lcl_CalculateRowsDelta(pMatX, pMeans,
N, K);
3165 if (!lcl_TCalculateQRdecomposition(pMatX, aVecR, K,
N))
3172 bool bIsSingular=
false;
3173 for (
SCSIZE row=0; row < K && !bIsSingular; row++)
3174 bIsSingular = aVecR[row] == 0.0;
3181 for (
SCSIZE row = 0; row < K; row++)
3183 lcl_TApplyHouseholderTransformation(pMatX, row, pMatY,
N);
3187 for (
SCSIZE col = 0; col < K ; col++)
3189 pSlopes->PutDouble( pMatY->GetDouble(col), col);
3191 lcl_SolveWithUpperRightTriangle(pMatX, aVecR, pSlopes, K,
true);
3194 lcl_MFastMult(pSlopes,pMatNewX,pResMat,1,K,nCXN);
3197 double fIntercept = fMeanY - lcl_GetSumProduct(pMeans,pSlopes,K);
3198 for (
SCSIZE col = 0; col < nCXN; col++)
3199 pResMat->PutDouble(pResMat->GetDouble(col)+fIntercept, col);
3204 pResMat->PutDouble(exp(pResMat->GetDouble(
i)),
i);
3208 PushMatrix(pResMat);
3216 PopSingleRef( aAdr );
3222 PushError( FormulaError::NoRef );
3232 PushError( FormulaError::RetryCircular );
3262 if ((nCols <= nC && nCols != 1) || (nRows <= nR && nRows != 1))
3273 nFuncFmtType = SvNumFormatType::LOGICAL;
3287 mrDoc.GetNumberFormatInfo(
mrContext, nCurFmtType, nCurFmtIndex, aAdr);
3288 nFuncFmtType = nCurFmtType;
3289 nFuncFmtIndex = nCurFmtIndex;
3290 PushDouble(nMatVal.
fVal);
3297 mrDoc.GetNumberFormatInfo(
mrContext, nCurFmtType, nCurFmtIndex, aAdr);
3298 nFuncFmtType = nCurFmtType;
3299 nFuncFmtIndex = nCurFmtIndex;
3302 if (nErr != FormulaError::NONE)
3316 if( !MustHaveParamCount( GetByte(), 1 ) )
3321 if( aStr ==
"SYSTEM" )
3322 PushString( SC_INFO_OSVERSION );
3323 else if( aStr ==
"OSVERSION" )
3324 #if (defined LINUX || defined __FreeBSD__)
3326 #elif defined MACOSX
3328 PushString(
"Windows (32-bit) NT 5.01");
3329 #else // handle Windows (WNT, WIN_NT, WIN32, _WIN32)
3331 PushString(
"Windows (32-bit) NT 5.01" );
3333 else if( aStr ==
"RELEASE" )
3335 else if( aStr ==
"NUMFILE" )
3337 else if( aStr ==
"RECALC" )
3338 PushString(
ScResId( mrDoc.GetAutoCalc() ? STR_RECALC_AUTO : STR_RECALC_MANUAL ) );
3339 else if (aStr ==
"DIRECTORY" || aStr ==
"MEMAVAIL" || aStr ==
"MEMUSED" || aStr ==
"ORIGIN" || aStr ==
"TOTMEM")
3342 PushIllegalArgument();
static bool IsNonValueType(ScMatValType nType)
String, empty or empty path, but not value nor boolean.
Matrix data type that can store values of mixed types.
void CalculateMatrixValue(const ScMatrix *pMat, SCSIZE nC, SCSIZE nR)
OUString getString() const
void CalculateAddSub(bool _bSub)
OUString ScResId(TranslateId aId)
void CalculateSumX2MY2SumX2DY2(bool _bSumX2DY2)
static void lcl_LUP_solve(const ScMatrix *mLU, const SCSIZE n, const ::std::vector< SCSIZE > &P, const ::std::vector< double > &B,::std::vector< double > &X)
void PutDouble(double fVal, SCSIZE nC, SCSIZE nR)
ScMatrixValue Get(SCSIZE nC, SCSIZE nR) const
: If bString the ScMatrixValue->pS may still be NULL to indicate an empty string! ...
static ScMatrixRef lcl_MatrixCalculation(const ScMatrix &rMat1, const ScMatrix &rMat2, ScInterpreter *pInterpreter)
void CalculateRGPRKP(bool _bRKP)
This is very similar to ScCellValue, except that it references the original value instead of copying ...
FormulaError GetErrorIfNotString(SCSIZE nC, SCSIZE nR) const
Use in ScInterpreter to obtain the error code, if any.
Try NOT to use this struct.
double GetDouble(SCSIZE nC, SCSIZE nR) const
static OUString GetOSVersion()
OUString GetString(int nId)
This class provides LO with Kahan summation algorithm About this algorithm: https://en.wikipedia.org/wiki/Kahan_summation_algorithm For general purpose software we assume first order error is enough.
static SCSIZE lcl_GetMinExtent(SCSIZE n1, SCSIZE n2)
Minimum extent of one result matrix dimension.
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
ScMatrixRef GetNewMat(SCSIZE nC, SCSIZE nR, bool bEmpty=false)
const ScRefCellValue & getRefCellValue() const
::boost::intrusive_ptr< ScMatrix > ScMatrixRef
Walk through all cells in an area.
ScFormulaCell * mpFormula
bool IsStringOrEmpty(SCSIZE nIndex) const
FormulaError GetDoubleErrorValue(double fVal)
static void lcl_GetDiffDateTimeFmtType(SvNumFormatType &nFuncFmt, SvNumFormatType nFmt1, SvNumFormatType nFmt2)
void MakeMatNew(ScMatrixRef &rMat, SCSIZE nC, SCSIZE nR)
static bool IsEmptyType(ScMatValType nType)
Empty, but not empty path or any other type.
static double div(const double &fNumerator, const double &fDenominator)
Fail safe division, returning a FormulaError::DivisionByZero coded into a double if denominator is 0...
double ConvertStringToValue(const OUString &)
static bool IsEmptyPathType(ScMatValType nType)
Empty path, but not empty or any other type.
svl::SharedString GetString(SCSIZE nC, SCSIZE nR) const
void GetDimensions(SCSIZE &rC, SCSIZE &rR) const
ScMatrixRef CreateMatrixFromDoubleRef(const formula::FormulaToken *pToken, SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2)
bool IsTrimToData() const
void GetVars(SCCOL &nCol1, SCROW &nRow1, SCTAB &nTab1, SCCOL &nCol2, SCROW &nRow2, SCTAB &nTab2) const
bool CheckMatrix(bool _bLOG, sal_uInt8 &nCase, SCSIZE &nCX, SCSIZE &nCY, SCSIZE &nRX, SCSIZE &nRY, SCSIZE &M, SCSIZE &N, ScMatrixRef &pMatX, ScMatrixRef &pMatY)
Op_< std::function< void(double &, double)>, double > Op
const NodeContext & mrContext
void CalculateTrendGrowth(bool _bGrowth)
static bool isOpenCLEnabled()
double power(const double &fVal1, const double &fVal2)
Return pow(fVal1,fVal2) with error handling.
const ScAddress & GetPos() const
const svl::SharedString & GetString() const
Only valid if ScMatrix methods indicate so!
::formula::FormulaTokenRef TokenRef
static void transKeyword(OUString &rName, const css::lang::Locale *pLocale, OpCode eOpCode)
double CreateDoubleError(FormulaError nErr)
static int lcl_LUP_decompose(ScMatrix *mA, const SCSIZE n,::std::vector< SCSIZE > &P)
bool GetFirst(double &rValue, FormulaError &rErr)
Does NOT reset rValue if no value found!
ScMatrixRef MatConcat(const ScMatrixRef &pMat1, const ScMatrixRef &pMat2)
bool GetNext(double &rValue, FormulaError &rErr)
Does NOT reset rValue if no value found!
Complex reference (a range) into the sheet.
sc::RangeMatrix GetRangeMatrix()
double get() const
Returns the final sum.
static css::lang::Locale & GetLocale()
static void MEMat(const ScMatrixRef &mM, SCSIZE n)
static OUString getBuildIdData(OUString const &_sDefault)
bool IsValueOrEmpty(SCSIZE nC, SCSIZE nR) const
double div(const double &fNumerator, const double &fDenominator)
Return fNumerator/fDenominator if fDenominator!=0 else #DIV/0! error coded into double.
static double ScGetGCD(double fx, double fy)
static bool IsSizeAllocatable(SCSIZE nC, SCSIZE nR)
Checks nC or nR for zero and uses GetElementsMax() whether a matrix of the size of nC*nR could be all...