23#include <document.hxx>
35double const fHalfMachEps = 0.5 * ::std::numeric_limits<double>::epsilon();
47 double const fBigInv = ::std::numeric_limits<double>::epsilon();
48 double const fBig = 1.0/fBigInv;
51 double fDenom = fX + 2.0-fA;
52 double fPkm1 = fX + 1.0;
54 double fQkm1 = fDenom * fX;
56 double fApprox = fPkm1/fQkm1;
57 bool bFinished =
false;
62 const double fNum = fY * fCount;
64 double fPk = fPkm1 * fDenom - fPkm2 * fNum;
65 const double fQk = fQkm1 * fDenom - fQkm2 * fNum;
68 const double fR = fPk/fQk;
79 fPkm2 = fPkm2 * fBigInv;
80 fPkm1 = fPkm1 * fBigInv;
81 fQkm2 = fQkm2 * fBigInv;
82 fQkm1 = fQkm1 * fBigInv;
84 }
while (!bFinished && fCount<10000);
88 SetError(FormulaError::NoConvergence);
98 double fDenomfactor = fA;
99 double fSummand = 1.0/fA;
100 double fSum = fSummand;
104 fDenomfactor = fDenomfactor + 1.0;
105 fSummand = fSummand * fX/fDenomfactor;
106 fSum = fSum + fSummand;
113 SetError(FormulaError::NoConvergence);
122 double fFactor = exp(fLnFactor);
134 double fFactor = exp(fLnFactor);
153 SetError(FormulaError::DivisionByZero);
156 else if (fAlpha == 1)
158 return (1.0 / fLambda);
167 double fXr = fX / fLambda;
171 const double fLogDblMax =
log( ::std::numeric_limits<double>::max());
174 return pow( fXr, fAlpha-1.0) * exp(-fXr) / fLambda /
GetGamma(fAlpha);
185 return pow( fXr, fAlpha-1.0) * exp(-fXr) / fLambda /
GetGamma(fAlpha);
189 return pow( fXr, fAlpha-1.0) * exp(-fXr) / fLambda / exp(
GetLogGamma(fAlpha));
208class NumericCellAccumulator
216 void operator() (
const sc::CellStoreType::value_type& rNode,
size_t nOffset,
size_t nDataSize)
225 const double *
p = &sc::numeric_block::at(*rNode.data, nOffset);
232 sc::formula_block::const_iterator it = sc::formula_block::begin(*rNode.data);
233 std::advance(it, nOffset);
234 sc::formula_block::const_iterator itEnd = it;
235 std::advance(itEnd, nDataSize);
236 for (; it != itEnd; ++it)
245 if (nErr != FormulaError::NONE)
262 const KahanSum& getResult()
const {
return maSum; }
265class NumericCellCounter
269 NumericCellCounter() :
mnCount(0) {}
271 void operator() (
const sc::CellStoreType::value_type& rNode,
size_t nOffset,
size_t nDataSize)
280 sc::formula_block::const_iterator it = sc::formula_block::begin(*rNode.data);
281 std::advance(it, nOffset);
282 sc::formula_block::const_iterator itEnd = it;
283 std::advance(itEnd, nDataSize);
284 for (; it != itEnd; ++it)
297 size_t getCount()
const {
return mnCount; }
322 NumericCellCounter aFunc;
328 size_t getCount()
const {
return mnCount; }
329 sal_uInt32 getNumberFormat()
const {
return mnNumFmt; }
355 if (mnError != FormulaError::NONE)
358 NumericCellAccumulator aFunc;
360 mnError = aFunc.getError();
361 if (mnError != FormulaError::NONE)
365 mfSum += aFunc.getResult();
370 const KahanSum& getSum()
const {
return mfSum; }
371 sal_uInt32 getNumberFormat()
const {
return mnNumFmt; }
384 rFuncFmtType = SvNumFormatType::NUMBER;
396 rCount += pMat->Count(bTextAsZero,
false);
400 rCount += pMat->Count(
true,
true);
426 for (
short i=1;
i <= nParamCount; ++
i)
431 if (
p &&
p->IsArrayResult() &&
p->GetRefList()->size() > nSize)
432 nSize =
p->GetRefList()->size();
465 const double ResInitVal = (eFunc ==
ifPRODUCT) ? 1.0 : 0.0;
471 size_t nRefInList = 0;
472 size_t nRefArrayPos = std::numeric_limits<size_t>::max();
476 while (nParamCount-- > 0)
517 while (nParamCount-- > 0)
535 case ifSUM: fRes += fVal;
break;
536 case ifSUMSQ: fRes += fVal * fVal;
break;
573 fVal = pToken->GetDouble();
582 case ifSUM: fRes += fVal;
break;
583 case ifSUMSQ: fRes += fVal * fVal;
break;
652 case ifSUM: fRes += fVal;
break;
653 case ifSUMSQ: fRes += fVal * fVal;
break;
658 else if (bTextAsZero && aCell.
hasString())
670 if (
p &&
p->IsArrayResult())
672 nRefArrayPos = nRefInList;
679 assert(nMatRows > 0);
681 xResMat->FillDouble( fRes.
get(), 0,0, 0,nMatRows-1);
684 xResCount =
GetNewMat( 1, nMatRows,
true);
685 xResCount->FillDouble(
nCount, 0,0, 0,nMatRows-1);
696 xResCount->PutDouble( xResCount->GetDouble(0,
i) +
nCount, 0,
i);
699 if (fRes != ResInitVal)
703 double fVecRes = xResMat->GetDouble(0,
i);
705 fVecRes *= fRes.
get();
707 fVecRes += fRes.
get();
708 xResMat->PutDouble( fVecRes, 0,
i);
738 for (
bool bHas = aIter.
first(); bHas; bHas = aIter.
next())
757 if ( eFunc ==
ifSUM )
762 if ( nErr != FormulaError::NONE )
767 fRes += aAction.getSum();
776 nCount += aAction.getCount();
800 if ( nErr == FormulaError::NONE )
807 while (aValIter.
GetNext(fVal, nErr));
817 while (aValIter.
GetNext(fVal, nErr));
825 if ( nErr == FormulaError::NONE )
832 while (aValIter.
GetNext(fVal, nErr));
842 while (aValIter.
GetNext(fVal, nErr));
855 while (aValIter.
GetNext(fVal, nErr));
860 if ( nErr == FormulaError::NONE )
863 while (aValIter.
GetNext(fVal, nErr));
870 if (nRefArrayPos != std::numeric_limits<size_t>::max())
874 xResCount->PutDouble( xResCount->GetDouble(0,nRefArrayPos) +
nCount, 0,nRefArrayPos);
875 double fVecRes = xResMat->GetDouble(0,nRefArrayPos);
877 fVecRes *= fRes.
get();
879 fVecRes += fRes.
get();
880 xResMat->PutDouble( fVecRes, 0,nRefArrayPos);
884 nRefArrayPos = std::numeric_limits<size_t>::max();
920 while (nParamCount-- > 0)
922 SetError(FormulaError::IllegalParameter);
937 double fVecRes = xResMat->GetDouble(0,
i);
939 fVecRes *= fRes.
get();
941 fVecRes += fRes.
get();
943 xResMat->PutDouble( fVecRes, 0,
i);
999 while (
nGlobalError == FormulaError::NONE && --nParamCount > 0)
1004 while (nParamCount-- > 0)
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 NodeContext & mrContext
This class provides LO with Kahan summation algorithm About this algorithm: https://en....
double get() const
Returns the final sum.
Walk through all cells in an area.
void InitBlockPosition(sc::ColumnBlockPosition &rBlockPos)
sc::CellStoreType & GetCellStore()
sal_uInt32 GetNumberFormat(const ScInterpreterContext &rContext, SCROW nRow) const
SC_DLLPUBLIC bool RowFiltered(SCROW nRow, SCTAB nTab, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
SC_DLLPUBLIC bool RowHidden(SCROW nRow, SCTAB nTab, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
::formula::FormulaTokenRef TokenRef
void SetError(FormulaError nError)
double ConvertStringToValue(const OUString &)
bool IsInArrayContext() const
void PopExternalSingleRef(sal_uInt16 &rFileId, OUString &rTabName, ScSingleRefData &rRef)
bool MustHaveParamCountMin(short nAct, short nMin)
SubtotalFlags mnSubTotalFlags
static const double fMaxGammaArgument
FormulaError nGlobalError
double GetGamma(double x)
You must ensure non integer arguments for fZ<1.
ScInterpreterContext & mrContext
SvNumFormatType nFuncFmtType
size_t GetRefListArrayMaxSize(short nParamCount)
Check for array of references to determine the maximum size of a return column vector if in array con...
const svl::SharedString & PopString()
void PushError(FormulaError nError)
sal_uInt8 GetByte() const
ScMatrixRef GetNewMat(SCSIZE nC, SCSIZE nR, bool bEmpty=false)
void ScAverage(bool bTextAsZero=false)
double GetLowRegIGamma(double fA, double fX)
You must ensure fA>0.0 && fX>0.0)
double GetGammaDistPDF(double fX, double fAlpha, double fLambda)
Gamma distribution, probability density function.
void PushDouble(double nVal)
void IterateParameters(ScIterFunc, bool bTextAsZero=false)
const formula::FormulaToken ** pStack
void PopSingleRef(ScAddress &)
void ReverseStack(sal_uInt8 nParamCount)
void ScRawSubtract()
The purpose of RAWSUBTRACT() is exactly to not apply any error correction, approximation etc.
void PopDoubleRef(ScRange &rRange, short &rParam, size_t &rRefInList)
If formula::StackVar formula::svDoubleRef pop ScDoubleRefToken and return values of ScComplexRefData.
double GetUpRegIGamma(double fA, double fX)
You must ensure fA>0.0 && fX>0.0)
void PushMatrix(const sc::RangeMatrix &rMat)
void PopExternalDoubleRef(sal_uInt16 &rFileId, OUString &rTabName, ScComplexRefData &rRef)
double GetCellValue(const ScAddress &, ScRefCellValue &rCell)
static double GetLogGamma(double x)
You must ensure fZ>0.
double GetGammaDist(double fX, double fAlpha, double fLambda)
Gamma distribution, cumulative distribution function.
formula::StackVar GetStackType()
Stack type with replacement of defaults, e.g. svMissing and formula::svEmptyCell will result in formu...
double GetGammaSeries(double fA, double fX)
You must ensure fA>0.0 && fX>0.0 valid results only if fX <= fA+1.0 uses power series.
double GetGammaContFraction(double fA, double fX)
You must ensure fA>0.0 && fX>0.0 valid results only if fX > fA+1.0 uses continued fraction with odd i...
bool GetFirst(double &rValue, FormulaError &rErr)
Does NOT reset rValue if no value found!
void GetCurNumFmtInfo(SvNumFormatType &nType, sal_uInt32 &nIndex)
bool GetNext(double &rValue, FormulaError &rErr)
Does NOT reset rValue if no value found!
virtual void execute(SCROW nRow1, SCROW nRow2, bool bVal)=0
virtual void startColumn(ScColumn *pCol)=0
Optimized ColumnSpanSet version that operates on a single ScRange.
void executeColumnAction(ScDocument &rDoc, sc::ColumnSpanSet::ColumnAction &ac) const
const OUString & getString() const
double const fHalfMachEps
static double lcl_IterResult(ScIterFunc eFunc, double fRes, sal_uLong nCount)
static void IterateMatrix(const ScMatrixRef &pMat, ScIterFunc eFunc, bool bTextAsZero, SubtotalFlags nSubTotalFlags, sal_uLong &rCount, SvNumFormatType &rFuncFmtType, KahanSum &fRes)
KahanSum sumArray(const double *pArray, size_t nSize)
Performs the sum of an array.
StoreT::const_iterator ParseBlock(const typename StoreT::const_iterator &itPos, const StoreT &rStore, Func &rFunc, typename StoreT::size_type nStart, typename StoreT::size_type nEnd)
Generic algorithm to parse blocks of multi_type_vector either partially or fully.
const mdds::mtv::element_t element_type_formula
double div(const double &fNumerator, const double &fDenominator)
Return fNumerator/fDenominator if fDenominator!=0 else #DIV/0! error coded into double.
const mdds::mtv::element_t element_type_numeric
Mapped standard element types (for convenience).
SvNumFormatType GetNumberFormatType(sal_uInt32 nFIndex) const
Iterator for executing one operation with the matrix data.
This is very similar to ScCellValue, except that it references the original value instead of copying ...
CellStoreType::const_iterator miCellPos
::boost::intrusive_ptr< ScMatrix > ScMatrixRef