20 #include <rtl/math.hxx>
24 #ifdef DEBUG_SC_LUP_DECOMPOSITION
34 #include <document.hxx>
37 #include <globstr.hrc>
51 double operator() (
const double& lhs,
const double& rhs)
const
53 return ::rtl::math::approxAdd( lhs,rhs);
59 double operator() (
const double& lhs,
const double& rhs)
const
61 return ::rtl::math::approxSub( lhs,rhs);
67 double operator() (
const double& lhs,
const double& rhs)
const
75 double operator() (
const double& lhs,
const double& rhs)
const
83 double operator() (
const double& lhs,
const double& rhs)
const
85 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 sum += pA->GetDouble(k,row) * pB->GetDouble(col,k);
101 pR->PutDouble(sum, 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 && pTokenMatrixMap && ((aIter = pTokenMatrixMap->find( pToken)) != pTokenMatrixMap->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);
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);
472 if (pToken && pTokenMatrixMap)
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 )
889 double fSum = B[P[
i]];
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);
1104 for (
SCSIZE j = 0; j < nC2; j++)
1107 for (
SCSIZE k = 0; k < nC1; k++)
1109 sum += pMat1->GetDouble(k,
i)*pMat2->GetDouble(j,k);
1111 pRMat->PutDouble(sum, j,
i);
1117 PushIllegalArgument();
1124 PushIllegalParameter();
1129 if ( !MustHaveParamCount( GetByte(), 1 ) )
1137 pMat->GetDimensions(nC, nR);
1138 pRMat = GetNewMat(nR, nC);
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);
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 ) )
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();
1725 SumValues() : mfSum(0.0), mbError(false) {}
1727 void operator() (
double f)
1733 if (nErr == FormulaError::NONE)
1735 else if (nErr != FormulaError::ElementNaN)
1744 double getValue()
const {
return mfSum; }
1752 if ( !MustHaveParamCountMin( nParamCount, 1) )
1759 size_t nInRefList = 0;
1763 pMatLast = GetMatrix( --nParamCount, nInRefList);
1766 PushIllegalParameter();
1770 SCSIZE nC, nCLast, nR, nRLast;
1771 pMatLast->GetDimensions(nCLast, nRLast);
1772 std::vector<double> aResArray;
1773 pMatLast->GetDoubleArray(aResArray);
1775 while (nParamCount--)
1777 pMat = GetMatrix( nParamCount, nInRefList);
1780 PushIllegalParameter();
1783 pMat->GetDimensions(nC, nR);
1784 if (nC != nCLast || nR != nRLast)
1790 pMat->MergeDoubleArrayMultiply(aResArray);
1793 double fSum = std::for_each(aResArray.begin(), aResArray.end(), SumValues()).
getValue();
1799 CalculateSumX2MY2SumX2DY2(
false);
1803 if ( !MustHaveParamCount( GetByte(), 2 ) )
1809 pMat2 = GetMatrix();
1810 pMat1 = GetMatrix();
1811 if (!pMat2 || !pMat1)
1813 PushIllegalParameter();
1818 pMat2->GetDimensions(nC2, nR2);
1819 pMat1->GetDimensions(nC1, nR1);
1820 if (nC1 != nC2 || nR1 != nR2)
1825 double fVal, fSum = 0.0;
1826 for (i = 0; i < nC1; i++)
1827 for (j = 0; j < nR1; j++)
1828 if (!pMat1->IsStringOrEmpty(i,j) && !pMat2->IsStringOrEmpty(i,j))
1830 fVal = pMat1->GetDouble(i,j);
1831 fSum += fVal * fVal;
1832 fVal = pMat2->GetDouble(i,j);
1834 fSum += fVal * fVal;
1836 fSum -= fVal * fVal;
1843 CalculateSumX2MY2SumX2DY2(
true);
1848 if ( !MustHaveParamCount( GetByte(), 2 ) )
1853 if (!pMat2 || !pMat1)
1855 PushIllegalParameter();
1860 pMat2->GetDimensions(nC2, nR2);
1861 pMat1->GetDimensions(nC1, nR1);
1862 if (nC1 != nC2 || nR1 != nR2)
1867 ScMatrixRef pResMat = lcl_MatrixCalculation<MatrixSub>( *pMat1, *pMat2,
this);
1882 if ( !MustHaveParamCount( GetByte(), 2 ) )
1885 vector<double> aBinArray;
1886 vector<tools::Long> aBinIndexOrder;
1888 GetSortArray( 1, aBinArray, &aBinIndexOrder,
false,
false );
1889 SCSIZE nBinSize = aBinArray.size();
1890 if (nGlobalError != FormulaError::NONE)
1896 vector<double> aDataArray;
1897 GetSortArray( 1, aDataArray,
nullptr,
false,
false );
1898 SCSIZE nDataSize = aDataArray.size();
1900 if (aDataArray.empty() || nGlobalError != FormulaError::NONE)
1908 PushIllegalArgument();
1912 if (nBinSize != aBinIndexOrder.size())
1914 PushIllegalArgument();
1920 for (j = 0; j < nBinSize; ++j)
1923 while (i < nDataSize && aDataArray[i] <= aBinArray[j])
1928 pResMat->PutDouble(static_cast<double>(nCount), aBinIndexOrder[j]);
1930 pResMat->PutDouble(static_cast<double>(nDataSize-i), j);
1931 PushMatrix(pResMat);
1947 fSum += pMatA->GetDouble(i) * pMatB->GetDouble(i);
1957 for (
SCSIZE row=nR; row<nN; row++)
1958 fNorm += (pMatA->GetDouble(nC,row)) * (pMatA->GetDouble(nC,row));
1967 for (
SCSIZE col=nC; col<nN; col++)
1968 fNorm += (pMatA->GetDouble(col,nR)) * (pMatA->GetDouble(col,nR));
1978 for (
SCSIZE row=nR; row<nN; row++)
1980 double fVal = fabs(pMatA->GetDouble(nC,row));
1992 for (
SCSIZE col=nC; col<nN; col++)
1994 double fVal = fabs(pMatA->GetDouble(col,nR));
2007 double fResult = 0.0;
2008 for (
SCSIZE row=nR; row<nN; row++)
2009 fResult += pMatA->GetDouble(nCa,row) * pMatB->GetDouble(nCb,row);
2018 double fResult = 0.0;
2019 for (
SCSIZE col=nC; col<nN; col++)
2020 fResult += pMatA->GetDouble(col,nRa) * pMatB->GetDouble(col,nRb);
2025 double lcl_GetSign(
double fValue)
2027 return (fValue >= 0.0 ? 1.0 : -1.0 );
2043 bool lcl_CalculateQRdecomposition(
const ScMatrixRef& pMatA,
2047 for (
SCSIZE col = 0; col <nK; col++)
2050 const double fScale = lcl_GetColumnMaximumNorm(pMatA, col, col, nN);
2056 for (
SCSIZE row = col; row <nN; row++)
2057 pMatA->PutDouble( pMatA->GetDouble(col,row)/fScale, col, row);
2059 const double fEuclid = lcl_GetColumnEuclideanNorm(pMatA, col, col, nN);
2060 const double fFactor = 1.0/fEuclid/(fEuclid + fabs(pMatA->GetDouble(col,col)));
2061 const double fSignum = lcl_GetSign(pMatA->GetDouble(col,col));
2062 pMatA->PutDouble( pMatA->GetDouble(col,col) + fSignum*fEuclid, col,col);
2063 pVecR[col] = -fSignum * fScale * fEuclid;
2066 for (
SCSIZE c=col+1; c<nK; c++)
2068 const double fSum =lcl_GetColumnSumProduct(pMatA, col, pMatA, c, col, nN);
2069 for (
SCSIZE row = col; row <nN; row++)
2070 pMatA->PutDouble( pMatA->GetDouble(c,row) - fSum * fFactor * pMatA->GetDouble(col,row), c, row);
2077 bool lcl_TCalculateQRdecomposition(
const ScMatrixRef& pMatA,
2082 for (
SCSIZE row = 0; row <nK; row++)
2085 const double fScale = lcl_TGetColumnMaximumNorm(pMatA, row, row, nN);
2091 for (
SCSIZE col = row; col <nN; col++)
2092 pMatA->PutDouble( pMatA->GetDouble(col,row)/fScale, col, row);
2094 const double fEuclid = lcl_TGetColumnEuclideanNorm(pMatA, row, row, nN);
2095 const double fFactor = 1.0/fEuclid/(fEuclid + fabs(pMatA->GetDouble(row,row)));
2096 const double fSignum = lcl_GetSign(pMatA->GetDouble(row,row));
2097 pMatA->PutDouble( pMatA->GetDouble(row,row) + fSignum*fEuclid, row,row);
2098 pVecR[row] = -fSignum * fScale * fEuclid;
2101 for (
SCSIZE r=row+1; r<nK; r++)
2103 fSum =lcl_TGetColumnSumProduct(pMatA, row, pMatA, r, row, nN);
2104 for (
SCSIZE col = row; col <nN; col++)
2106 pMatA->GetDouble(col,r) - fSum * fFactor * pMatA->GetDouble(col,row), col, r);
2122 double fDenominator = lcl_GetColumnSumProduct(pMatA, nC, pMatA, nC, nC, nN);
2123 double fNumerator = lcl_GetColumnSumProduct(pMatA, nC, pMatY, 0, nC, nN);
2124 double fFactor = 2.0 * (fNumerator/fDenominator);
2125 for (
SCSIZE row = nC; row < nN; row++)
2127 pMatY->GetDouble(row) - fFactor * pMatA->GetDouble(nC,row), row);
2135 double fDenominator = lcl_TGetColumnSumProduct(pMatA, nR, pMatA, nR, nR, nN);
2136 double fNumerator = lcl_TGetColumnSumProduct(pMatA, nR, pMatY, 0, nR, nN);
2137 double fFactor = 2.0 * (fNumerator/fDenominator);
2138 for (
SCSIZE col = nR; col < nN; col++)
2140 pMatY->GetDouble(col) - fFactor * pMatA->GetDouble(col,nR), col);
2149 void lcl_SolveWithUpperRightTriangle(
const ScMatrixRef& pMatA,
2150 ::std::vector< double>& pVecR,
const ScMatrixRef& pMatS,
2151 SCSIZE nK,
bool bIsTransposed)
2156 for (
SCSIZE rowp1 = nK; rowp1>0; rowp1--)
2159 double fSum = pMatS->GetDouble(row);
2160 for (
SCSIZE col = rowp1; col<nK ; col++)
2162 fSum -= pMatA->GetDouble(row,col) * pMatS->GetDouble(col);
2164 fSum -= pMatA->GetDouble(col,row) * pMatS->GetDouble(col);
2165 pMatS->PutDouble( fSum / pVecR[row] , row);
2175 void lcl_SolveWithLowerLeftTriangle(
const ScMatrixRef& pMatA,
2176 ::std::vector< double>& pVecR,
const ScMatrixRef& pMatT,
2177 SCSIZE nK,
bool bIsTransposed)
2180 for (
SCSIZE row = 0; row < nK; row++)
2182 double fSum = pMatT -> GetDouble(row);
2183 for (
SCSIZE col=0; col < row; col++)
2186 fSum -= pMatA->GetDouble(col,row) * pMatT->GetDouble(col);
2188 fSum -= pMatA->GetDouble(row,col) * pMatT->GetDouble(col);
2190 pMatT->PutDouble( fSum / pVecR[row] , row);
2200 void lcl_ApplyUpperRightTriangle(
const ScMatrixRef& pMatA,
2201 ::std::vector< double>& pVecR,
const ScMatrixRef& pMatB,
2205 for (
SCSIZE row = 0; row < nK; row++)
2207 double fSum = pVecR[row] * pMatB->GetDouble(row);
2208 for (
SCSIZE col = row+1; col < nK; col++)
2210 fSum += pMatA->GetDouble(row,col) * pMatB->GetDouble(col);
2212 fSum += pMatA->GetDouble(col,row) * pMatB->GetDouble(col);
2213 pMatZ->PutDouble( fSum, row);
2221 fSum += pMat->GetDouble(i);
2222 return fSum/
static_cast<double>(nN);
2233 for (
SCSIZE k=0; k < nR; k++)
2234 fSum += pX->GetDouble(i,k);
2235 pResMat ->PutDouble( fSum/static_cast<double>(nR),i);
2244 for (
SCSIZE k=0; k < nR; k++)
2248 fSum += pX->GetDouble(i,k);
2249 pResMat ->PutDouble( fSum/static_cast<double>(nC),k);
2257 for (
SCSIZE k = 0; k < nR; k++)
2258 pMat->PutDouble( ::rtl::math::approxSub
2259 (pMat->GetDouble(i,k) , pColumnMeans->GetDouble(i) ) , i, k);
2265 for (
SCSIZE k = 0; k < nR; k++)
2267 pMat->PutDouble( ::rtl::math::approxSub
2268 ( pMat->GetDouble(i,k) , pRowMeans->GetDouble(k) ) , i, k);
2280 const double fTemp = pMatY->GetDouble(i) - fSlope * pMatX->GetDouble(i);
2281 fSum += fTemp * fTemp;
2302 pMatY->GetDimensions(nCY, nRY);
2303 const SCSIZE nCountY = nCY * nRY;
2306 if (!pMatY->IsValue(
i))
2308 PushIllegalArgument();
2316 for (
SCSIZE nElem = 0; nElem < nCountY; nElem++)
2318 const double fVal = pNewY->GetDouble(nElem);
2321 PushIllegalArgument();
2325 pNewY->PutDouble(
log(fVal), nElem);
2332 pMatX->GetDimensions(nCX, nRX);
2333 const SCSIZE nCountX = nCX * nRX;
2335 if (!pMatX->IsValue(
i))
2337 PushIllegalArgument();
2340 if (nCX == nCY && nRX == nRY)
2346 else if (nCY != 1 && nRY != 1)
2348 PushIllegalArgument();
2355 PushIllegalArgument();
2365 else if (nCX != nCY)
2367 PushIllegalArgument();
2379 pMatX = GetNewMat(nCY, nRY);
2384 PushIllegalArgument();
2388 pMatX->PutDouble(static_cast<double>(
i),
i-1);
2399 CalculateRGPRKP(
false);
2405 CalculateRGPRKP(
true);
2411 if (!MustHaveParamCount( nParamCount, 1, 4 ))
2413 bool bConstant, bStats;
2416 if (nParamCount == 4)
2423 if (nParamCount >= 3)
2433 bConstant = GetBool();
2439 if (nParamCount >= 2)
2448 pMatX = GetMatrix();
2457 PushIllegalParameter();
2467 if (!CheckMatrix(_bRKP,nCase,nCX,nCY,nRX,nRY,K,
N,pMatX,pMatY))
2469 PushIllegalParameter();
2474 if ((bConstant && (
N<K+1)) || (!bConstant && (
N<K)) || (
N<1) || (K<1))
2476 PushIllegalParameter();
2482 pResMat = GetNewMat(K+1,5);
2484 pResMat = GetNewMat(K+1,1);
2487 PushError(FormulaError::CodeOverflow);
2495 pResMat->PutError( FormulaError::NotAvailable,
i, 2);
2496 pResMat->PutError( FormulaError::NotAvailable,
i, 3);
2497 pResMat->PutError( FormulaError::NotAvailable,
i, 4);
2503 double fMeanY = 0.0;
2508 if (!pNewX || !pNewY)
2510 PushError(FormulaError::CodeOverflow);
2516 fMeanY = lcl_GetMeanOverAll(pMatY,
N);
2519 pMatY->PutDouble( ::rtl::math::approxSub(pMatY->GetDouble(
i),fMeanY),
i );
2526 double fMeanX = 0.0;
2529 fMeanX = lcl_GetMeanOverAll(pMatX,
N);
2532 pMatX->PutDouble( ::rtl::math::approxSub(pMatX->GetDouble(
i),fMeanX),
i );
2535 double fSumXY = lcl_GetSumProduct(pMatX,pMatY,
N);
2536 double fSumX2 = lcl_GetSumProduct(pMatX,pMatX,
N);
2542 double fSlope = fSumXY / fSumX2;
2543 double fIntercept = 0.0;
2545 fIntercept = fMeanY - fSlope * fMeanX;
2546 pResMat->PutDouble(_bRKP ? exp(fIntercept) : fIntercept, 1, 0);
2547 pResMat->PutDouble(_bRKP ? exp(fSlope) : fSlope, 0, 0);
2551 double fSSreg = fSlope * fSlope * fSumX2;
2552 pResMat->PutDouble(fSSreg, 0, 4);
2554 double fDegreesFreedom =
static_cast<double>( bConstant ?
N-2 :
N-1 );
2555 pResMat->PutDouble(fDegreesFreedom, 1, 3);
2557 double fSSresid = lcl_GetSSresid(pMatX,pMatY,fSlope,
N);
2558 pResMat->PutDouble(fSSresid, 1, 4);
2560 if (fDegreesFreedom == 0.0 || fSSresid == 0.0 || fSSreg == 0.0)
2563 pResMat->PutDouble(0.0, 1, 4);
2564 pResMat->PutError( FormulaError::NotAvailable, 0, 3);
2565 pResMat->PutDouble(0.0, 1, 2);
2566 pResMat->PutDouble(0.0, 0, 1);
2568 pResMat->PutDouble(0.0, 1, 1);
2570 pResMat->PutError( FormulaError::NotAvailable, 1, 1);
2571 pResMat->PutDouble(1.0, 0, 2);
2575 double fFstatistic = (fSSreg /
static_cast<double>(K))
2576 / (fSSresid / fDegreesFreedom);
2577 pResMat->PutDouble(fFstatistic, 0, 3);
2580 double fRMSE = sqrt(fSSresid / fDegreesFreedom);
2581 pResMat->PutDouble(fRMSE, 1, 2);
2583 double fSigmaSlope = fRMSE / sqrt(fSumX2);
2584 pResMat->PutDouble(fSigmaSlope, 0, 1);
2588 double fSigmaIntercept = fRMSE
2589 * sqrt(fMeanX*fMeanX/fSumX2 + 1.0/static_cast<double>(
N));
2590 pResMat->PutDouble(fSigmaIntercept, 1, 1);
2594 pResMat->PutError( FormulaError::NotAvailable, 1, 1);
2597 double fR2 = fSSreg / (fSSreg + fSSresid);
2598 pResMat->PutDouble(fR2, 0, 2);
2601 PushMatrix(pResMat);
2609 ::std::vector< double> aVecR(
N);
2614 pMatZ = pMatY->Clone();
2618 if (!pMeans || !pMatZ || !pSlopes)
2620 PushError(FormulaError::CodeOverflow);
2625 lcl_CalculateColumnMeans(pMatX, pMeans, K,
N);
2626 lcl_CalculateColumnsDelta(pMatX, pMeans, K,
N);
2628 if (!lcl_CalculateQRdecomposition(pMatX, aVecR, K,
N))
2635 bool bIsSingular=
false;
2636 for (
SCSIZE row=0; row < K && !bIsSingular; row++)
2637 bIsSingular = aVecR[row] == 0.0;
2644 for (
SCSIZE col = 0; col < K; col++)
2646 lcl_ApplyHouseholderTransformation(pMatX, col, pMatZ,
N);
2650 for (
SCSIZE col = 0; col < K ; col++)
2652 pSlopes->PutDouble( pMatZ->GetDouble(col), col);
2654 lcl_SolveWithUpperRightTriangle(pMatX, aVecR, pSlopes, K,
false);
2655 double fIntercept = 0.0;
2657 fIntercept = fMeanY - lcl_GetSumProduct(pMeans,pSlopes,K);
2659 pResMat->PutDouble(_bRKP ? exp(fIntercept) : fIntercept, K, 0 );
2661 pResMat->PutDouble(_bRKP ? exp(pSlopes->GetDouble(
i))
2662 : pSlopes->GetDouble(
i) , K-1-
i, 0);
2666 double fSSreg = 0.0;
2667 double fSSresid = 0.0;
2669 pMatZ->FillDouble(0.0, 0, 0, 0,
N-1);
2671 lcl_ApplyUpperRightTriangle(pMatX, aVecR, pSlopes, pMatZ, K,
false);
2673 for (
SCSIZE colp1 = K; colp1 > 0; colp1--)
2675 lcl_ApplyHouseholderTransformation(pMatX, colp1-1, pMatZ,
N);
2677 fSSreg =lcl_GetSumProduct(pMatZ, pMatZ,
N);
2679 for (
SCSIZE row = 0; row <
N; row++)
2680 pMatY->PutDouble(pMatY->GetDouble(row) - pMatZ->GetDouble(row), row);
2681 fSSresid = lcl_GetSumProduct(pMatY, pMatY, N);
2682 pResMat->PutDouble(fSSreg, 0, 4);
2683 pResMat->PutDouble(fSSresid, 1, 4);
2685 double fDegreesFreedom =
static_cast<double>( bConstant ? N-K-1 : N-K );
2686 pResMat->PutDouble(fDegreesFreedom, 1, 3);
2688 if (fDegreesFreedom == 0.0 || fSSresid == 0.0 || fSSreg == 0.0)
2690 pResMat->PutDouble(0.0, 1, 4);
2692 pResMat->PutError( FormulaError::NotAvailable, 0, 3);
2694 pResMat->PutDouble(0.0, 1, 2);
2696 for (
SCSIZE i=0; i<K; i++)
2697 pResMat->PutDouble(0.0, K-1-i, 1);
2701 pResMat->PutDouble(0.0, K, 1);
2703 pResMat->PutError( FormulaError::NotAvailable, K, 1);
2706 pResMat->PutDouble(1.0, 0, 2);
2710 double fFstatistic = (fSSreg /
static_cast<double>(K))
2711 / (fSSresid / fDegreesFreedom);
2712 pResMat->PutDouble(fFstatistic, 0, 3);
2715 double fRMSE = sqrt(fSSresid / fDegreesFreedom);
2716 pResMat->PutDouble(fRMSE, 1, 2);
2724 double fSigmaIntercept = 0.0;
2726 for (
SCSIZE col = 0; col < K; col++)
2729 pMatZ->FillDouble(0.0,0,0,0,K-1);
2730 pMatZ->PutDouble(1.0, col);
2732 lcl_SolveWithLowerLeftTriangle(pMatX, aVecR, pMatZ, K,
false);
2734 lcl_SolveWithUpperRightTriangle(pMatX, aVecR, pMatZ, K,
false);
2736 double fSigmaSlope = fRMSE * sqrt(pMatZ->GetDouble(col));
2737 pResMat->PutDouble(fSigmaSlope, K-1-col, 1);
2741 fPart = lcl_GetSumProduct(pMeans, pMatZ, K);
2742 fSigmaIntercept += fPart * pMeans->GetDouble(col);
2747 fSigmaIntercept = fRMSE
2748 * sqrt(fSigmaIntercept + 1.0 / static_cast<double>(N));
2749 pResMat->PutDouble(fSigmaIntercept, K, 1);
2753 pResMat->PutError( FormulaError::NotAvailable, K, 1);
2756 double fR2 = fSSreg / (fSSreg + fSSresid);
2757 pResMat->PutDouble(fR2, 0, 2);
2760 PushMatrix(pResMat);
2764 ::std::vector< double> aVecR(
N);
2769 pMatZ = pMatY->Clone();
2773 if (!pMeans || !pMatZ || !pSlopes)
2775 PushError(FormulaError::CodeOverflow);
2780 lcl_CalculateRowMeans(pMatX, pMeans,
N, K);
2781 lcl_CalculateRowsDelta(pMatX, pMeans,
N, K);
2784 if (!lcl_TCalculateQRdecomposition(pMatX, aVecR, K,
N))
2792 bool bIsSingular=
false;
2793 for (
SCSIZE row=0; row < K && !bIsSingular; row++)
2794 bIsSingular = aVecR[row] == 0.0;
2801 for (
SCSIZE row = 0; row < K; row++)
2803 lcl_TApplyHouseholderTransformation(pMatX, row, pMatZ,
N);
2807 for (
SCSIZE col = 0; col < K ; col++)
2809 pSlopes->PutDouble( pMatZ->GetDouble(col), col);
2811 lcl_SolveWithUpperRightTriangle(pMatX, aVecR, pSlopes, K,
true);
2812 double fIntercept = 0.0;
2814 fIntercept = fMeanY - lcl_GetSumProduct(pMeans,pSlopes,K);
2816 pResMat->PutDouble(_bRKP ? exp(fIntercept) : fIntercept, K, 0 );
2818 pResMat->PutDouble(_bRKP ? exp(pSlopes->GetDouble(
i))
2819 : pSlopes->GetDouble(
i) , K-1-
i, 0);
2823 double fSSreg = 0.0;
2824 double fSSresid = 0.0;
2826 pMatZ->FillDouble(0.0, 0, 0,
N-1, 0);
2828 lcl_ApplyUpperRightTriangle(pMatX, aVecR, pSlopes, pMatZ, K,
true);
2830 for (
SCSIZE rowp1 = K; rowp1 > 0; rowp1--)
2832 lcl_TApplyHouseholderTransformation(pMatX, rowp1-1, pMatZ,
N);
2834 fSSreg =lcl_GetSumProduct(pMatZ, pMatZ,
N);
2836 for (
SCSIZE col = 0; col <
N; col++)
2837 pMatY->PutDouble(pMatY->GetDouble(col) - pMatZ->GetDouble(col), col);
2838 fSSresid = lcl_GetSumProduct(pMatY, pMatY, N);
2839 pResMat->PutDouble(fSSreg, 0, 4);
2840 pResMat->PutDouble(fSSresid, 1, 4);
2842 double fDegreesFreedom =
static_cast<double>( bConstant ? N-K-1 : N-K );
2843 pResMat->PutDouble(fDegreesFreedom, 1, 3);
2845 if (fDegreesFreedom == 0.0 || fSSresid == 0.0 || fSSreg == 0.0)
2847 pResMat->PutDouble(0.0, 1, 4);
2849 pResMat->PutError( FormulaError::NotAvailable, 0, 3);
2851 pResMat->PutDouble(0.0, 1, 2);
2853 for (
SCSIZE i=0; i<K; i++)
2854 pResMat->PutDouble(0.0, K-1-i, 1);
2858 pResMat->PutDouble(0.0, K, 1);
2860 pResMat->PutError( FormulaError::NotAvailable, K, 1);
2863 pResMat->PutDouble(1.0, 0, 2);
2867 double fFstatistic = (fSSreg /
static_cast<double>(K))
2868 / (fSSresid / fDegreesFreedom);
2869 pResMat->PutDouble(fFstatistic, 0, 3);
2872 double fRMSE = sqrt(fSSresid / fDegreesFreedom);
2873 pResMat->PutDouble(fRMSE, 1, 2);
2882 double fSigmaIntercept = 0.0;
2884 for (
SCSIZE row = 0; row < K; row++)
2887 pMatZ->FillDouble(0.0,0,0,K-1,0);
2888 pMatZ->PutDouble(1.0, row);
2890 lcl_SolveWithLowerLeftTriangle(pMatX, aVecR, pMatZ, K,
true);
2892 lcl_SolveWithUpperRightTriangle(pMatX, aVecR, pMatZ, K,
true);
2894 double fSigmaSlope = fRMSE * sqrt(pMatZ->GetDouble(row));
2895 pResMat->PutDouble(fSigmaSlope, K-1-row, 1);
2898 fPart = lcl_GetSumProduct(pMeans, pMatZ, K);
2899 fSigmaIntercept += fPart * pMeans->GetDouble(row);
2904 fSigmaIntercept = fRMSE
2905 * sqrt(fSigmaIntercept + 1.0 / static_cast<double>(N));
2906 pResMat->PutDouble(fSigmaIntercept, K, 1);
2910 pResMat->PutError( FormulaError::NotAvailable, K, 1);
2913 double fR2 = fSSreg / (fSSreg + fSSresid);
2914 pResMat->PutDouble(fR2, 0, 2);
2917 PushMatrix(pResMat);
2924 CalculateTrendGrowth(
false);
2929 CalculateTrendGrowth(
true);
2935 if (!MustHaveParamCount( nParamCount, 1, 4 ))
2940 if (nParamCount == 4)
2941 bConstant = GetBool();
2948 if (nParamCount >= 3)
2956 pMatNewX = GetMatrix();
2964 if (nParamCount >= 2)
2973 pMatX = GetMatrix();
2982 PushIllegalParameter();
2992 if (!CheckMatrix(_bGrowth,nCase,nCX,nCY,nRX,nRY,K,
N,pMatX,pMatY))
2994 PushIllegalParameter();
2999 if ((bConstant && (
N<K+1)) || (!bConstant && (
N<K)) || (
N<1) || (K<1))
3001 PushIllegalParameter();
3012 nCountXN = nCXN * nRXN;
3013 pMatNewX = pMatX->Clone();
3017 pMatNewX->GetDimensions(nCXN, nRXN);
3018 if ((nCase == 2 && K != nCXN) || (nCase == 3 && K != nRXN))
3020 PushIllegalArgument();
3023 nCountXN = nCXN * nRXN;
3025 if (!pMatNewX->IsValue(
i))
3027 PushIllegalArgument();
3033 pResMat = GetNewMat(nCXN,nRXN);
3037 pResMat = GetNewMat(1,nRXN);
3039 pResMat = GetNewMat(nCXN,1);
3043 PushError(FormulaError::CodeOverflow);
3048 double fMeanY = 0.0;
3053 if (!pCopyX || !pCopyY)
3055 PushError(FormulaError::MatrixSize);
3061 fMeanY = lcl_GetMeanOverAll(pMatY,
N);
3064 pMatY->PutDouble( ::rtl::math::approxSub(pMatY->GetDouble(
i),fMeanY),
i );
3071 double fMeanX = 0.0;
3074 fMeanX = lcl_GetMeanOverAll(pMatX,
N);
3077 pMatX->PutDouble( ::rtl::math::approxSub(pMatX->GetDouble(
i),fMeanX),
i );
3080 double fSumXY = lcl_GetSumProduct(pMatX,pMatY,
N);
3081 double fSumX2 = lcl_GetSumProduct(pMatX,pMatX,
N);
3087 double fSlope = fSumXY / fSumX2;
3091 double fIntercept = fMeanY - fSlope * fMeanX;
3094 fHelp = pMatNewX->GetDouble(
i)*fSlope + fIntercept;
3095 pResMat->PutDouble(_bGrowth ? exp(fHelp) : fHelp,
i);
3102 fHelp = pMatNewX->GetDouble(
i)*fSlope;
3103 pResMat->PutDouble(_bGrowth ? exp(fHelp) : fHelp,
i);
3111 ::std::vector< double> aVecR(
N);
3115 if (!pMeans || !pSlopes)
3117 PushError(FormulaError::CodeOverflow);
3122 lcl_CalculateColumnMeans(pMatX, pMeans, K,
N);
3123 lcl_CalculateColumnsDelta(pMatX, pMeans, K,
N);
3125 if (!lcl_CalculateQRdecomposition(pMatX, aVecR, K,
N))
3132 bool bIsSingular=
false;
3133 for (
SCSIZE row=0; row < K && !bIsSingular; row++)
3134 bIsSingular = aVecR[row] == 0.0;
3141 for (
SCSIZE col = 0; col < K; col++)
3143 lcl_ApplyHouseholderTransformation(pMatX, col, pMatY,
N);
3147 for (
SCSIZE col = 0; col < K ; col++)
3149 pSlopes->PutDouble( pMatY->GetDouble(col), col);
3151 lcl_SolveWithUpperRightTriangle(pMatX, aVecR, pSlopes, K,
false);
3154 lcl_MFastMult(pMatNewX,pSlopes,pResMat,nRXN,K,1);
3157 double fIntercept = fMeanY - lcl_GetSumProduct(pMeans,pSlopes,K);
3158 for (
SCSIZE row = 0; row < nRXN; row++)
3159 pResMat->PutDouble(pResMat->GetDouble(row)+fIntercept, row);
3164 pResMat->PutDouble(exp(pResMat->GetDouble(
i)),
i);
3170 ::std::vector< double> aVecR(
N);
3174 if (!pMeans || !pSlopes)
3176 PushError(FormulaError::CodeOverflow);
3181 lcl_CalculateRowMeans(pMatX, pMeans,
N, K);
3182 lcl_CalculateRowsDelta(pMatX, pMeans,
N, K);
3184 if (!lcl_TCalculateQRdecomposition(pMatX, aVecR, K,
N))
3191 bool bIsSingular=
false;
3192 for (
SCSIZE row=0; row < K && !bIsSingular; row++)
3193 bIsSingular = aVecR[row] == 0.0;
3200 for (
SCSIZE row = 0; row < K; row++)
3202 lcl_TApplyHouseholderTransformation(pMatX, row, pMatY,
N);
3206 for (
SCSIZE col = 0; col < K ; col++)
3208 pSlopes->PutDouble( pMatY->GetDouble(col), col);
3210 lcl_SolveWithUpperRightTriangle(pMatX, aVecR, pSlopes, K,
true);
3213 lcl_MFastMult(pSlopes,pMatNewX,pResMat,1,K,nCXN);
3216 double fIntercept = fMeanY - lcl_GetSumProduct(pMeans,pSlopes,K);
3217 for (
SCSIZE col = 0; col < nCXN; col++)
3218 pResMat->PutDouble(pResMat->GetDouble(col)+fIntercept, col);
3223 pResMat->PutDouble(exp(pResMat->GetDouble(
i)),
i);
3227 PushMatrix(pResMat);
3235 PopSingleRef( aAdr );
3241 PushError( FormulaError::NoRef );
3251 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 PushString(
"Windows (32-bit) NT 5.01" );
3325 else if( aStr ==
"RELEASE" )
3327 else if( aStr ==
"NUMFILE" )
3329 else if( aStr ==
"RECALC" )
3330 PushString(
ScResId( mrDoc.GetAutoCalc() ? STR_RECALC_AUTO : STR_RECALC_MANUAL ) );
3331 else if (aStr ==
"DIRECTORY" || aStr ==
"MEMAVAIL" || aStr ==
"MEMUSED" || aStr ==
"ORIGIN" || aStr ==
"TOTMEM")
3334 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)
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
OUString GetString(int nId)
Op_< std::function< void(double &, double)>> Op
static css::lang::Locale * GetLocale()
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 ...
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
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)
OUString ScResId(const char *pId)
bool IsTrimToData() const
void GetVars(SCCOL &nCol1, SCROW &nRow1, SCTAB &nTab1, SCCOL &nCol2, SCROW &nRow2, SCTAB &nTab2) const
css::beans::Optional< css::uno::Any > getValue(std::u16string_view id)
bool CheckMatrix(bool _bLOG, sal_uInt8 &nCase, SCSIZE &nCX, SCSIZE &nCY, SCSIZE &nRX, SCSIZE &nRY, SCSIZE &M, SCSIZE &N, ScMatrixRef &pMatX, ScMatrixRef &pMatY)
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)
When adding all numerical matrix elements for a scalar result such as summation, the interpreter want...
bool GetNext(double &rValue, FormulaError &rErr)
Does NOT reset rValue if no value found!
Complex reference (a range) into the sheet.
sc::RangeMatrix GetRangeMatrix()
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...