25#include <document.hxx>
38#include <osl/diagnose.h>
51const double fMachEps = ::std::numeric_limits<double>::epsilon();
58 virtual double GetValue(
double x)
const = 0;
73 return (u < 0.0 && w > 0.0) || (
u > 0.0 &&
w < 0.0);
76static double lcl_IterateInverse(
const ScDistFunc& rFunction,
double fAx,
double fBx,
bool& rConvError )
79 const double fYEps = 1.0E-307;
80 const double fXEps = ::std::numeric_limits<double>::epsilon();
82 OSL_ENSURE(fAx<fBx,
"IterateInverse: wrong interval");
88 double fAy = rFunction.GetValue(fAx);
89 double fBy = rFunction.GetValue(fBx);
94 if (std::abs(fAy) <= std::abs(fBy))
97 fkAx += (fkAx - fkBx) * 2.0;
102 fAy = rFunction.GetValue(fkAx.
get());
107 fkBx += (fkBx - fkAx) * 2.0;
110 fBy = rFunction.GetValue(fkBx.
get());
133 double fSx = 0.5 * (fAx + fBx);
134 bool bHasToInterpolate =
true;
136 while (
nCount < 500 && std::abs(fRy) > fYEps &&
137 (fBx-fAx) > ::std::max( std::abs(fAx), std::abs(fBx)) * fXEps )
139 if (bHasToInterpolate)
141 if (fPy!=fQy && fQy!=fRy && fRy!=fPy)
143 fSx = fPx * fRy * fQy / (fRy-fPy) / (fQy-fPy)
144 + fRx * fQy * fPy / (fQy-fRy) / (fPy-fRy)
145 + fQx * fPy * fRy / (fPy-fQy) / (fRy-fQy);
146 bHasToInterpolate = (fAx < fSx) && (fSx < fBx);
149 bHasToInterpolate =
false;
151 if(!bHasToInterpolate)
153 fSx = 0.5 * (fAx + fBx);
155 fQx = fBx; fQy = fBy;
156 bHasToInterpolate =
true;
159 fPx = fQx; fQx = fRx; fRx = fSx;
160 fPy = fQy; fQy = fRy; fRy = rFunction.GetValue(fSx);
164 fBx = fRx; fBy = fRy;
168 fAx = fRx; fAy = fRy;
172 bHasToInterpolate = bHasToInterpolate && (std::abs(fRy) * 2.0 <= std::abs(fQy));
188 while (nParamCount-- > 0)
197 return 0.39894228040143268 * exp(-(
x *
x) / 2.0);
202 return 0.5 * std::erfc(-
x * M_SQRT1_2);
208 for (
short i = nMax-1;
i >= 0;
i--)
210 nVal = (nVal *
x) + pPolynom[
i];
218 double xAbs = std::abs(
x);
219 sal_uInt16 xShort =
static_cast<sal_uInt16
>(::rtl::math::approxFloor(xAbs));
223 static const double t0[] =
224 { 0.39894228040143268, -0.06649038006690545, 0.00997355701003582,
225 -0.00118732821548045, 0.00011543468761616, -0.00000944465625950,
226 0.00000066596935163, -0.00000004122667415, 0.00000000227352982,
227 0.00000000011301172, 0.00000000000511243, -0.00000000000021218 };
228 nVal =
taylor(t0, 11, (xAbs * xAbs)) * xAbs;
230 else if (xShort <= 2)
232 static const double t2[] =
233 { 0.47724986805182079, 0.05399096651318805, -0.05399096651318805,
234 0.02699548325659403, -0.00449924720943234, -0.00224962360471617,
235 0.00134977416282970, -0.00011783742691370, -0.00011515930357476,
236 0.00003704737285544, 0.00000282690796889, -0.00000354513195524,
237 0.00000037669563126, 0.00000019202407921, -0.00000005226908590,
238 -0.00000000491799345, 0.00000000366377919, -0.00000000015981997,
239 -0.00000000017381238, 0.00000000002624031, 0.00000000000560919,
240 -0.00000000000172127, -0.00000000000008634, 0.00000000000007894 };
241 nVal =
taylor(t2, 23, (xAbs - 2.0));
243 else if (xShort <= 4)
245 static const double t4[] =
246 { 0.49996832875816688, 0.00013383022576489, -0.00026766045152977,
247 0.00033457556441221, -0.00028996548915725, 0.00018178605666397,
248 -0.00008252863922168, 0.00002551802519049, -0.00000391665839292,
249 -0.00000074018205222, 0.00000064422023359, -0.00000017370155340,
250 0.00000000909595465, 0.00000000944943118, -0.00000000329957075,
251 0.00000000029492075, 0.00000000011874477, -0.00000000004420396,
252 0.00000000000361422, 0.00000000000143638, -0.00000000000045848 };
253 nVal =
taylor(t4, 20, (xAbs - 4.0));
257 static const double asympt[] = { -1.0, 1.0, -3.0, 15.0, -105.0 };
258 nVal = 0.5 +
phi(xAbs) *
taylor(asympt, 4, 1.0 / (xAbs * xAbs)) / xAbs;
274 if(std::abs(q)<=.425)
287 t*2509.0809287301226727+33430.575583588128105
289 *
t+67265.770927008700853
291 *
t+45921.953931549871457
293 *
t+13731.693765509461125
295 *
t+1971.5909503065514427
297 *
t+133.14166789178437745
299 *
t+3.387132872796366608
309 t*5226.495278852854561+28729.085735721942674
311 *
t+39307.89580009271061
313 *
t+21213.794301586595867
315 *
t+5394.1960214247511077
317 *
t+687.1870074920579083
319 *
t+42.313330701600911252
344 t*7.7454501427834140764e-4+0.0227238449892691845833
346 *
t+0.24178072517745061177
348 *
t+1.27045825245236838258
350 *
t+3.64784832476320460504
352 *
t+5.7694972214606914055
354 *
t+4.6303378461565452959
356 *
t+1.42343711074968357734
366 t*1.05075007164441684324e-9+5.475938084995344946e-4
368 *
t+0.0151986665636164571966
370 *
t+0.14810397642748007459
372 *
t+0.68976733498510000455
374 *
t+1.6763848301838038494
376 *
t+2.05319162663775882187
394 t*2.01033439929228813265e-7+2.71155556874348757815e-5
396 *
t+0.0012426609473880784386
398 *
t+0.026532189526576123093
400 *
t+0.29656057182850489123
402 *
t+1.7848265399172913358
404 *
t+5.4637849111641143699
406 *
t+6.6579046435011037772
416 t*2.04426310338993978564e-15+1.4215117583164458887e-7
418 *
t+1.8463183175100546818e-5
420 *
t+7.868691311456132591e-4
422 *
t+0.0148753612908506148525
424 *
t+0.13692988092273580531
426 *
t+0.59983220655588793769
441 x = ::rtl::math::approxFloor(
x);
466 k = ::rtl::math::approxFloor(k);
493 static const double fNum[13] ={
494 23531376880.41075968857200767445163675473,
495 42919803642.64909876895789904700198885093,
496 35711959237.35566804944018545154716670596,
497 17921034426.03720969991975575445893111267,
498 6039542586.35202800506429164430729792107,
499 1439720407.311721673663223072794912393972,
500 248874557.8620541565114603864132294232163,
501 31426415.58540019438061423162831820536287,
502 2876370.628935372441225409051620849613599,
503 186056.2653952234950402949897160456992822,
504 8071.672002365816210638002902272250613822,
505 210.8242777515793458725097339207133627117,
506 2.506628274631000270164908177133837338626
508 static const double fDenom[13] = {
530 fSumDenom = fDenom[12];
531 for (nI = 11; nI >= 0; --nI)
536 fSumDenom += fDenom[nI];
544 fSumDenom = fDenom[0];
545 for (nI = 1; nI <=12; ++nI)
550 fSumDenom += fDenom[nI];
553 return fSumNum/fSumDenom;
562 const double fg = 6.024680040776729583740234375;
563 double fZgHelp = fZ + fg - 0.5;
565 double fHalfpower = pow( fZgHelp, fZ / 2 - 0.25);
566 fGamma *= fHalfpower;
567 fGamma /= exp(fZgHelp);
568 fGamma *= fHalfpower;
569 if (fZ <= 20.0 && fZ == ::rtl::math::approxFloor(fZ))
570 fGamma = ::rtl::math::round(fGamma);
579 const double fg = 6.024680040776729583740234375;
580 double fZgHelp = fZ + fg - 0.5;
587 const double fLogPi =
log(M_PI);
588 const double fLogDblMax =
log( ::std::numeric_limits<double>::max());
592 SetError(FormulaError::IllegalFPOperation);
605 if (fLogTest >= fLogDblMax)
607 SetError( FormulaError::IllegalFPOperation);
615 if (fLogDivisor - fLogPi >= fLogDblMax)
619 if (fLogPi - fLogDivisor > fLogDblMax)
621 SetError(FormulaError::IllegalFPOperation);
625 return exp( fLogPi - fLogDivisor) * ((::rtl::math::sin( M_PI*fZ) < 0.0) ? -1.0 : 1.0);
642 double arg = fF2/(fF2+fF1*
x);
643 double alpha = fF2/2.0;
644 double beta = fF1/2.0;
653 return 0.5 *
GetBetaDist( fDF / ( fDF + T * T ), fDF / 2.0, 0.5 );
655 return GetBetaDist( fDF / ( fDF + T * T ), fDF / 2.0, 0.5);
657 return pow( 1 + ( T * T / fDF ), -( fDF + 1 ) / 2 ) / ( sqrt( fDF ) *
GetBeta( 0.5, fDF / 2.0 ) );
659 double X = fDF / ( T * T + fDF );
661 return ( T < 0 ?
R : 1 -
R );
663 SetError( FormulaError::IllegalArgument );
695 if (fDF*fX > 1391000.0)
698 fValue = exp((0.5*fDF - 1) *
log(fX*0.5) - 0.5 * fX -
log(2.0) -
GetLogGamma(0.5*fDF));
703 if (fmod(fDF,2.0)<0.5)
711 fValue = 1/sqrt(fX*2*M_PI);
714 while ( fCount < fDF)
716 fValue *= (fX / fCount);
720 fValue = exp(
log(fValue)-fX/2);
722 fValue *= exp(-fX/2);
733 if (nParamCount == 3)
737 double fDF = ::rtl::math::approxFloor(
GetDouble());
756 double fDF = ::rtl::math::approxFloor(
GetDouble() );
757 if ( fDF < 1.0 || fDF > 1E10 )
777 if (
x <= 0.0 &&
x == ::rtl::math::approxFloor(
x))
806 fA = fAlpha; fB = fBeta;
810 fA = fBeta; fB = fAlpha;
817 const double fg = 6.024680040776729583740234375;
818 double fgm = fg - 0.5;
822 double fABgm = fA+fB+fgm;
823 fLanczos *= sqrt((fABgm/(fA+fgm))/(fB+fgm));
824 double fTempA = fB/(fA+fgm);
825 double fTempB = fA/(fB+fgm);
826 double fResult = exp(-fA * std::log1p(fTempA)
827 -fB * std::log1p(fTempB)-fgm);
839 fA = fAlpha; fB = fBeta;
843 fA = fBeta; fB = fAlpha;
845 const double fg = 6.024680040776729583740234375;
846 double fgm = fg - 0.5;
850 double fLogLanczos =
log(fLanczos);
851 double fABgm = fA+fB+fgm;
852 fLogLanczos += 0.5*(
log(fABgm)-
log(fA+fgm)-
log(fB+fgm));
853 double fTempA = fB/(fA+fgm);
854 double fTempB = fA/(fB+fgm);
855 double fResult = -fA * std::log1p(fTempA)
856 -fB * std::log1p(fTempB)-fgm;
857 fResult += fLogLanczos;
870 return -2.0*fX + 2.0;
871 if (fX == 1.0 && fB < 1.0)
873 SetError(FormulaError::IllegalArgument);
877 return fB + fB * std::expm1((fB-1.0) * std::log1p(-fX));
879 return fB * pow(0.5-fX+0.5,fB-1.0);
885 if (fX == 0.0 && fA < 1.0)
887 SetError(FormulaError::IllegalArgument);
890 return fA * pow(fX,fA-1);
894 if (fA < 1.0 && fX == 0.0)
896 SetError(FormulaError::IllegalArgument);
904 if (fB < 1.0 && fX == 1.0)
906 SetError(FormulaError::IllegalArgument);
914 const double fLogDblMax =
log( ::std::numeric_limits<double>::max());
915 const double fLogDblMin =
log( ::std::numeric_limits<double>::min());
916 double fLogY = (fX < 0.1) ? std::log1p(-fX) :
log(0.5-fX+0.5);
917 double fLogX =
log(fX);
918 double fAm1LogX = (fA-1.0) * fLogX;
919 double fBm1LogY = (fB-1.0) * fLogY;
922 if ( fAm1LogX < fLogDblMax && fAm1LogX > fLogDblMin
923 && fBm1LogY < fLogDblMax && fBm1LogY > fLogDblMin
924 && fLogBeta < fLogDblMax && fLogBeta > fLogDblMin
925 && fAm1LogX + fBm1LogY < fLogDblMax && fAm1LogX + fBm1LogY > fLogDblMin)
926 return pow(fX,fA-1.0) * pow(0.5-fX+0.5,fB-1.0) /
GetBeta(fA,fB);
929 return exp( fAm1LogX + fBm1LogY - fLogBeta);
939 double a1, b1, a2, b2, fnorm, cfnew, cf;
941 b2 = 1.0 - (fA+fB)/(fA+1.0)*fX;
957 const double fMaxIter = 50000.0;
961 bool bfinished =
false;
964 const double apl2m = fA + 2.0*rm;
965 const double d2m = rm*(fB-rm)*fX/((apl2m-1.0)*apl2m);
966 const double d2m1 = -(fA+rm)*(fA+fB+rm)*fX/(apl2m*(apl2m+1.0));
967 a1 = (a2+d2m*a1)*fnorm;
968 b1 = (b2+d2m*b1)*fnorm;
969 a2 = a1 + d2m1*a2*fnorm;
970 b2 = b1 + d2m1*b2*fnorm;
975 bfinished = (std::abs(cf-cfnew) < std::abs(cf)*
fMachEps);
980 while (rm < fMaxIter && !bfinished);
993 return pow(fXin, fAlpha);
996 return -std::expm1(fBeta * std::log1p(-fXin));
1001 double fY = (0.5-fXin)+0.5;
1002 double flnY = std::log1p(-fXin);
1004 double flnX =
log(fXin);
1007 bool bReflect = fXin > fAlpha/(fAlpha+fBeta);
1018 fResult = fResult/fA;
1019 double fP = fA/(fA+fB);
1020 double fQ = fB/(fA+fB);
1022 if (fA > 1.0 && fB > 1.0 && fP < 0.97 && fQ < 0.97)
1025 fTemp = exp(fA*flnX + fB*flnY -
GetLogBeta(fA,fB));
1028 fResult = 0.5 - fResult + 0.5;
1041 double fLowerBound, fUpperBound;
1044 if (nParamCount == 6)
1047 bIsCumulative =
true;
1048 if (nParamCount >= 5)
1052 if (nParamCount >= 4)
1059 double fScale = fUpperBound - fLowerBound;
1060 if (fScale <= 0.0 ||
alpha <= 0.0 || beta <= 0.0)
1068 if (
x < fLowerBound)
1072 if (
x > fUpperBound)
1077 x = (
x-fLowerBound)/fScale;
1083 if (x < fLowerBound || x > fUpperBound)
1088 x = (
x-fLowerBound)/fScale;
1105 double fLowerBound, fUpperBound;
1108 if (nParamCount == 6)
1112 if (nParamCount >= 5)
1120 if (
alpha <= 0.0 || beta <= 0.0 || x < fLowerBound || x > fUpperBound)
1125 double fScale = fUpperBound - fLowerBound;
1128 x = (
x-fLowerBound)/fScale;
1134 x = (
x-fLowerBound)/fScale;
1153 if (std::abs(fVal) >= 1.0)
1177 double k = ::rtl::math::approxFloor(
GetDouble());
1178 double n = ::rtl::math::approxFloor(
GetDouble());
1179 if (k < 0.0 || n < 0.0 || k >
n)
1190 double k = ::rtl::math::approxFloor(
GetDouble());
1191 double n = ::rtl::math::approxFloor(
GetDouble());
1192 if (k < 0.0 || n < 0.0 || k >
n)
1204 double k = ::rtl::math::approxFloor(
GetDouble());
1205 double n = ::rtl::math::approxFloor(
GetDouble());
1206 if (
n < 0.0 || k < 0.0 || k >
n)
1214 nVal *=
n-
static_cast<double>(
i);
1223 double k = ::rtl::math::approxFloor(
GetDouble());
1224 double n = ::rtl::math::approxFloor(
GetDouble());
1225 if (
n < 0.0 || k < 0.0)
1236 double q = (0.5 -
p) + 0.5;
1237 double fFactor = pow(q,
n);
1238 if (fFactor <=::std::numeric_limits<double>::min())
1240 fFactor = pow(
p,
n);
1241 if (fFactor <= ::std::numeric_limits<double>::min())
1245 sal_uInt32
max =
static_cast<sal_uInt32
>(
n -
x);
1246 for (sal_uInt32
i = 0; i < max && fFactor > 0.0;
i++)
1247 fFactor *= (
n-
i)/(
i+1)*q/
p;
1253 sal_uInt32
max =
static_cast<sal_uInt32
>(
x);
1254 for (sal_uInt32
i = 0; i < max && fFactor > 0.0;
i++)
1255 fFactor *= (
n-
i)/(
i+1)*
p/q;
1261 double fFactor ,
double p,
double q)
1266 sal_uInt32 nXs =
static_cast<sal_uInt32
>( xs );
1267 for (
i = 1; i <= nXs && fFactor > 0.0;
i++)
1268 fFactor *= (
n-
i+1)/
i *
p/q;
1270 sal_uInt32 nXe =
static_cast<sal_uInt32
>(xe);
1271 for (
i = nXs+1; i <= nXe && fFactor > 0.0;
i++)
1273 fFactor *= (
n-
i+1)/
i *
p/q;
1276 return std::min(fSum.
get(), 1.0);
1284 if (nParamCount == 3)
1286 double x = ::rtl::math::approxFloor(
GetDouble());
1288 double n = ::rtl::math::approxFloor(
GetDouble());
1289 if (
n < 0.0 || x < 0.0 || x >
n || p < 0.0 || p > 1.0)
1300 double xe = ::rtl::math::approxFloor(
GetDouble());
1301 double xs = ::rtl::math::approxFloor(
GetDouble());
1303 double n = ::rtl::math::approxFloor(
GetDouble());
1304 double q = (0.5 -
p) + 0.5;
1305 bool bIsValidX = ( 0.0 <= xs && xs <= xe && xe <=
n);
1306 if ( bIsValidX && 0.0 <
p &&
p < 1.0)
1312 double fFactor = pow(q,
n);
1313 if (fFactor > ::std::numeric_limits<double>::min())
1317 fFactor = pow(
p,
n);
1318 if (fFactor > ::std::numeric_limits<double>::min())
1335 else if (
p == 1.0 )
1353 double n = ::rtl::math::approxFloor(
GetDouble());
1354 double x = ::rtl::math::approxFloor(
GetDouble());
1355 double q = (0.5 -
p) + 0.5;
1356 if (
n < 0.0 || x < 0.0 || x >
n || p < 0.0 || p > 1.0)
1379 double fFactor = pow(q,
n);
1382 else if (fFactor <= ::std::numeric_limits<double>::min())
1384 fFactor = pow(
p,
n);
1385 if (fFactor <= ::std::numeric_limits<double>::min())
1391 double fSum = 1.0 - fFactor;
1392 sal_uInt32
max =
static_cast<sal_uInt32
> (
n -
x) - 1;
1393 for (sal_uInt32
i = 0; i < max && fFactor > 0.0;
i++)
1395 fFactor *= (
n-
i)/(
i+1)*q/
p;
1417 double n = ::rtl::math::approxFloor(
GetDouble());
1418 if (
n < 0.0 || alpha < 0.0 || alpha > 1.0 || p < 0.0 || p > 1.0)
1420 else if (
alpha == 0.0 )
1422 else if (
alpha == 1.0 )
1427 double q = (0.5 -
p) + 0.5;
1432 if (fFactor > ::std::numeric_limits<double>::min())
1435 sal_uInt32
max =
static_cast<sal_uInt32
> (
n),
i;
1438 fFactor *= (
n-
i)/(
i+1)*
p/q;
1447 sal_uInt32
max =
static_cast<sal_uInt32
> (
n),
i;
1465 fFactor = pow(
p,
n);
1466 if (fFactor > ::std::numeric_limits<double>::min())
1469 sal_uInt32
max =
static_cast<sal_uInt32
> (
n),
i;
1470 for (
i = 0; i < max && fSum >=
alpha;
i++)
1472 fFactor *= (
n-
i)/(
i+1)*q/
p;
1481 sal_uInt32
max =
static_cast<sal_uInt32
> (
n),
i;
1506 double s = ::rtl::math::approxFloor(
GetDouble());
1507 double f = ::rtl::math::approxFloor(
GetDouble());
1508 if ((f + s) <= 1.0 || p < 0.0 || p > 1.0)
1513 double fFactor = pow(
p,s);
1514 for (
double i = 0.0;
i < f;
i++)
1515 fFactor *= (
i+s)/(
i+1.0)*q;
1527 double s = ::rtl::math::approxFloor(
GetDouble());
1528 double f = ::rtl::math::approxFloor(
GetDouble());
1529 if ( s < 1.0 || f < 0.0 || p < 0.0 || p > 1.0 )
1538 double fFactor = pow(
p, s );
1539 for (
double i = 0.0;
i < f;
i++ )
1540 fFactor *= (
i + s ) / (
i + 1.0 ) * q;
1551 bool bCumulative = nParamCount != 4 ||
GetBool();
1571 bool bCumulative = nParamCount != 4 ||
GetBool();
1572 double sigma = nParamCount >= 3 ?
GetDouble() : 1.0;
1573 double mue = nParamCount >= 2 ?
GetDouble() : 0.0;
1612 PushDouble( exp( - pow(
x, 2 ) / 2 ) / sqrt( 2 * M_PI ) );
1625 else if (kum == 0.0)
1645 double fFlag = ::rtl::math::approxFloor(
GetDouble());
1646 double fDF = ::rtl::math::approxFloor(
GetDouble());
1648 if (fDF < 1.0 || T < 0.0 || (fFlag != 1.0 && fFlag != 2.0) )
1660 double fDF = ::rtl::math::approxFloor(
GetDouble() );
1662 if ( fDF < 1.0 || ( nTails == 2 && fT < 0.0 ) )
1667 double fRes =
GetTDist( fT, fDF, nTails );
1668 if ( nTails == 1 && fT < 0.0 )
1679 double fDF = ::rtl::math::approxFloor(
GetDouble() );
1693 double fF2 = ::rtl::math::approxFloor(
GetDouble());
1694 double fF1 = ::rtl::math::approxFloor(
GetDouble());
1696 if (fF < 0.0 || fF1 < 1.0 || fF2 < 1.0 || fF1 >= 1.0E10 || fF2 >= 1.0E10)
1710 if ( nParamCount == 3 )
1719 double fF2 = ::rtl::math::approxFloor(
GetDouble() );
1720 double fF1 = ::rtl::math::approxFloor(
GetDouble() );
1722 if ( fF < 0.0 || fF1 < 1.0 || fF2 < 1.0 || fF1 >= 1.0E10 || fF2 >= 1.0E10 )
1735 PushDouble( pow( fF1 / fF2, fF1 / 2 ) * pow( fF, ( fF1 / 2 ) - 1 ) /
1736 ( pow( ( 1 + ( fF * fF1 / fF2 ) ), ( fF1 + fF2 ) / 2 ) *
1737 GetBeta( fF1 / 2, fF2 / 2 ) ) );
1746 double fDF = ::rtl::math::approxFloor(
GetDouble());
1749 || ( !bODFF && fChi < 0 ) )
1772 if (
alpha <= 0.0 || beta <= 0.0 ||
x < 0.0)
1774 else if (kum == 0.0)
1776 exp(-pow(
x/beta,
alpha)));
1787 bool bCumulative = nParamCount != 3 ||
GetBool();
1789 double x = ::rtl::math::approxFloor(
GetDouble());
1790 if (lambda <= 0.0 ||
x < 0.0)
1792 else if (!bCumulative)
1800 double fPoissonVar = 1.0;
1801 for (
double f = 0.0; f <
x; ++f )
1802 fPoissonVar *= lambda / ( f + 1.0 );
1818 double fSummand = std::exp(-lambda);
1820 int nEnd = sal::static_int_cast<int>(
x );
1821 for (
int i = 1;
i <= nEnd;
i++)
1823 fSummand = (fSummand * lambda)/
static_cast<double>(
i);
1836 for (
double i = fLower;
i <= fUpper; ++
i )
1838 double fVal = fBase -
i;
1840 cn.push_back( fVal );
1862 bool bCumulative = ( nParamCount == 5 &&
GetBool() );
1863 double N = ::rtl::math::approxFloor(
GetDouble());
1864 double M = ::rtl::math::approxFloor(
GetDouble());
1865 double n = ::rtl::math::approxFloor(
GetDouble());
1866 double x = ::rtl::math::approxFloor(
GetDouble());
1868 if ( (
x < 0.0) || (
n <
x) || (
N <
n) || (
N <
M) || (
M < 0.0) )
1876 for (
int i = ( bCumulative ? 0 :
x );
i <=
x &&
nGlobalError == FormulaError::NONE;
i++ )
1878 if ( (
n -
i <=
N -
M) && (
i <=
M) )
1897 const size_t nMaxArraySize = 500000;
1899 std::vector<double> cnNumer, cnDenom;
1901 size_t nEstContainerSize =
static_cast<size_t>(
x + ::std::min(
n,
M ) );
1902 size_t nMaxSize = ::std::min( cnNumer.max_size(), nMaxArraySize );
1903 if ( nEstContainerSize > nMaxSize )
1908 cnNumer.reserve( nEstContainerSize + 10 );
1909 cnDenom.reserve( nEstContainerSize + 10 );
1912 double fCNumVarUpper =
N -
n -
M +
x - 1.0;
1913 double fCDenomVarLower = 1.0;
1914 if (
N -
n -
M +
x >=
M -
x + 1.0 )
1916 fCNumVarUpper =
M -
x - 1.0;
1917 fCDenomVarLower =
N -
n - 2.0*(
M -
x) + 1.0;
1920 double fCNumLower =
N -
n - fCNumVarUpper;
1921 double fCDenomUpper =
N -
n -
M +
x + 1.0 - fCDenomVarLower;
1923 double fDNumVarLower =
n -
M;
1927 if (
N -
M <
n + 1.0 )
1931 if (
N -
n <
n + 1.0 )
1940 OSL_ENSURE( fCNumLower <
n + 1.0,
"ScHypGeomDist: wrong assertion" );
1945 OSL_ENSURE( fCDenomUpper <=
N -
M,
"ScHypGeomDist: wrong assertion" );
1947 if ( fCDenomUpper <
n -
x + 1.0 )
1955 fCDenomUpper =
n -
x;
1956 fCDenomVarLower =
N -
M - 2.0*(
n -
x) + 1.0;
1975 OSL_ENSURE( fCDenomUpper <=
n,
"ScHypGeomDist: wrong assertion" );
1977 if ( fCDenomUpper <
n -
x + 1.0 )
1983 fCDenomUpper =
n -
x;
1984 fCDenomVarLower =
N -
M - 2.0*(
n -
x) + 1.0;
1988 OSL_ENSURE( fCDenomUpper <=
M,
"ScHypGeomDist: wrong assertion" );
1992 if (
N -
M <
M + 1.0 )
1996 if (
N -
n <
M + 1.0 )
2008 if (
n -
x + 1.0 > fCDenomUpper )
2016 fCDenomVarLower =
N -
M - 2.0*(
n -
x) + 1.0;
2017 fCDenomUpper =
n -
x;
2024 OSL_ENSURE(
M >=
n -
x,
"ScHypGeomDist: wrong assertion" );
2025 OSL_ENSURE(
M -
x <=
N -
M + 1.0,
"ScHypGeomDist: wrong assertion" );
2027 if (
N -
n <
N -
M + 1.0 )
2036 OSL_ENSURE( fCNumLower <=
N -
M + 1.0,
"ScHypGeomDist: wrong assertion" );
2041 if (
n -
x + 1.0 > fCDenomUpper )
2044 else if (
M >= fCDenomUpper )
2048 fCDenomUpper =
n -
x;
2049 fCDenomVarLower =
N -
M - 2.0*(
n -
x) + 1.0;
2053 OSL_ENSURE(
M <= fCDenomUpper,
"ScHypGeomDist: wrong assertion" );
2055 N -
n -
M +
x + 1.0 );
2057 fCDenomUpper =
n -
x;
2058 fCDenomVarLower =
N -
M - 2.0*(
n -
x) + 1.0;
2062 OSL_ENSURE( fCDenomUpper <=
n,
"ScHypGeomDist: wrong assertion" );
2064 fDNumVarLower = 0.0;
2067 double nDNumVarUpper = fCDenomUpper <
x + 1.0 ?
n -
x - 1.0 :
n - fCDenomUpper - 1.0;
2068 double nDDenomVarLower = fCDenomUpper <
x + 1.0 ? fCDenomVarLower :
N -
n -
M + 1.0;
2072 ::std::sort( cnNumer.begin(), cnNumer.end() );
2073 ::std::sort( cnDenom.begin(), cnDenom.end() );
2074 auto it1 = cnNumer.rbegin(), it1End = cnNumer.rend();
2075 auto it2 = cnDenom.rbegin(), it2End = cnDenom.rend();
2077 double fFactor = 1.0;
2078 for ( ; it1 != it1End || it2 != it2End; )
2080 double fEnum = 1.0, fDenom = 1.0;
2081 if ( it1 != it1End )
2083 if ( it2 != it2End )
2085 fFactor *= fEnum / fDenom;
2093 sal_uInt8 nMinParamCount = ( bODFF ? 3 : 4 );
2098 if (nParamCount == 4)
2105 if ((!bODFF && fX < 0) || fAlpha <= 0.0 || fBeta <= 0.0)
2123 if (sigma <= 0.0 || x < 0.0 || x > 1.0)
2125 else if (
x == 0.0 ||
x == 1.0)
2135 if (x < 0.0 || x > 1.0)
2137 else if (
x == 0.0 ||
x == 1.0)
2148 double fSigma = ( nParamCount == 3 ?
GetDouble() : 1.0 );
2149 double fMue = ( nParamCount >= 2 ?
GetDouble() : 0.0 );
2151 if ( fSigma <= 0.0 || fP <= 0.0 || fP >= 1.0 )
2179 if (fAlpha <= 0.0 || fBeta <= 0.0 || fP < 0.0 || fP >= 1.0 )
2190 double fStart = fAlpha * fBeta;
2193 SetError(FormulaError::NoConvergence);
2217 double fP, fA, fB, fAlpha, fBeta;
2218 if (nParamCount == 5)
2222 if (nParamCount >= 4)
2229 if (fP < 0.0 || fP > 1.0 || fA >= fB || fAlpha <= 0.0 || fBeta <= 0.0)
2240 PushError( FormulaError::NoConvergence);
2268 double fDF = ::rtl::math::approxFloor(
GetDouble());
2270 if (fDF < 1.0 || fP <= 0.0 || fP > 1.0 )
2279 else if ( fP < 0.5 )
2294 SetError(FormulaError::NoConvergence);
2316 double fF2 = ::rtl::math::approxFloor(
GetDouble());
2317 double fF1 = ::rtl::math::approxFloor(
GetDouble());
2319 if (fP <= 0.0 || fF1 < 1.0 || fF2 < 1.0 || fF1 >= 1.0E10 || fF2 >= 1.0E10 || fP > 1.0)
2329 SetError(FormulaError::NoConvergence);
2337 double fF2 = ::rtl::math::approxFloor(
GetDouble());
2338 double fF1 = ::rtl::math::approxFloor(
GetDouble());
2340 if (fP <= 0.0 || fF1 < 1.0 || fF2 < 1.0 || fF1 >= 1.0E10 || fF2 >= 1.0E10 || fP > 1.0)
2350 SetError(FormulaError::NoConvergence);
2372 double fDF = ::rtl::math::approxFloor(
GetDouble());
2374 if (fDF < 1.0 || fP <= 0.0 || fP > 1.0 )
2384 SetError(FormulaError::NoConvergence);
2407 double fDF = ::rtl::math::approxFloor(
GetDouble());
2409 if (fDF < 1.0 || fP < 0.0 || fP >= 1.0 )
2419 SetError(FormulaError::NoConvergence);
2427 double n = ::rtl::math::approxFloor(
GetDouble());
2430 if (sigma <= 0.0 || alpha <= 0.0 || alpha >= 1.0 ||
n < 1.0)
2441 double n = ::rtl::math::approxFloor(
GetDouble());
2444 if (sigma <= 0.0 || alpha <= 0.0 || alpha >= 1.0 ||
n < 1.0)
2447 PushError(FormulaError::DivisionByZero);
2458 double sigma = 0.0,
x;
2459 if (nParamCount == 3)
2473 double rValCount = 0.0;
2480 fSumSqr += fVal*fVal;
2493 fSumSqr += fVal*fVal;
2502 size_t nRefInList = 0;
2503 while (nParam-- > 0)
2512 fSumSqr += fVal*fVal;
2514 while ((nErr == FormulaError::NONE) && aValIter.
GetNext(fVal, nErr))
2517 fSumSqr += fVal*fVal;
2533 if (pMat->IsNumeric())
2537 fVal= pMat->GetDouble(
i);
2539 fSumSqr += fVal * fVal;
2546 if (!pMat->IsStringOrEmpty(
i))
2548 fVal= pMat->GetDouble(
i);
2550 fSumSqr += fVal * fVal;
2557 default :
SetError(FormulaError::IllegalParameter);
break;
2559 if (rValCount <= 1.0)
2560 PushError( FormulaError::DivisionByZero);
2563 double mue = fSum.
get()/rValCount;
2565 if (nParamCount != 3)
2567 sigma = (fSumSqr - fSum*fSum/rValCount).
get()/(rValCount-1.0);
2570 PushError(FormulaError::DivisionByZero);
2583 ,
double& fT,
double& fF)
2585 double fCount1 = 0.0;
2586 double fCount2 = 0.0;
2593 for (
i = 0;
i < nC1;
i++)
2594 for (j = 0; j < nR1; j++)
2596 if (!pMat1->IsStringOrEmpty(
i,j))
2598 fVal = pMat1->GetDouble(
i,j);
2600 fSumSqr1 += fVal * fVal;
2604 for (
i = 0;
i < nC2;
i++)
2605 for (j = 0; j < nR2; j++)
2607 if (!pMat2->IsStringOrEmpty(
i,j))
2609 fVal = pMat2->GetDouble(
i,j);
2611 fSumSqr2 += fVal * fVal;
2615 if (fCount1 < 2.0 || fCount2 < 2.0)
2622 double fS1 = (fSumSqr1-fSum1*fSum1/fCount1).
get() / (fCount1-1.0) / fCount1;
2623 double fS2 = (fSumSqr2-fSum2*fSum2/fCount2).
get() / (fCount2-1.0) / fCount2;
2624 if (fS1 + fS2 == 0.0)
2629 fT = std::abs(( fSum1/fCount1 - fSum2/fCount2 ).
get())/sqrt(fS1+fS2);
2630 double c = fS1/(fS1+fS2);
2633 fF = 1.0/(c*c/(fCount1-1.0)+(1.0-c)*(1.0-c)/(fCount2-1.0));
2638 double fS1 = (fSumSqr1 - fSum1*fSum1/fCount1).
get() / (fCount1 - 1.0);
2639 double fS2 = (fSumSqr2 - fSum2*fSum2/fCount2).
get() / (fCount2 - 1.0);
2640 fT = std::abs( fSum1.
get()/fCount1 - fSum2.
get()/fCount2 ) /
2641 sqrt( (fCount1-1.0)*fS1 + (fCount2-1.0)*fS2 ) *
2642 sqrt( fCount1*fCount2*(fCount1+fCount2-2)/(fCount1+fCount2) );
2643 fF = fCount1 + fCount2 - 2;
2651 double fTyp = ::rtl::math::approxFloor(
GetDouble());
2652 double fTails = ::rtl::math::approxFloor(
GetDouble());
2653 if (fTails != 1.0 && fTails != 2.0)
2661 if (!pMat1 || !pMat2)
2670 pMat1->GetDimensions(nC1, nR1);
2671 pMat2->GetDimensions(nC2, nR2);
2674 if (nC1 != nC2 || nR1 != nR2)
2679 double fCount = 0.0;
2683 double fVal1, fVal2;
2684 for (
i = 0;
i < nC1;
i++)
2685 for (j = 0; j < nR1; j++)
2687 if (!pMat1->IsStringOrEmpty(
i,j) && !pMat2->IsStringOrEmpty(
i,j))
2689 fVal1 = pMat1->GetDouble(
i,j);
2690 fVal2 = pMat2->GetDouble(
i,j);
2693 fSumSqrD += (fVal1 - fVal2)*(fVal1 - fVal2);
2703 double fDivider = ( fSumSqrD*fCount - fSumD*fSumD ).
get();
2704 if ( fDivider == 0.0 )
2706 PushError(FormulaError::DivisionByZero);
2709 fT = std::abs(fSumD.
get()) * sqrt((fCount-1.0) / fDivider);
2712 else if (fTyp == 2.0)
2714 if (!
CalculateTest(
false,nC1, nC2,nR1, nR2,pMat1,pMat2,fT,fF))
2717 else if (fTyp == 3.0)
2719 if (!
CalculateTest(
true,nC1, nC2,nR1, nR2,pMat1,pMat2,fT,fF))
2736 if (!pMat1 || !pMat2)
2744 double fCount1 = aVal1.mnCount;
2745 double fCount2 = aVal2.mnCount;
2746 KahanSum fSum1 = aVal1.maAccumulator[0];
2747 KahanSum fSumSqr1 = aVal1.maAccumulator[1];
2748 KahanSum fSum2 = aVal2.maAccumulator[0];
2749 KahanSum fSumSqr2 = aVal2.maAccumulator[1];
2751 if (fCount1 < 2.0 || fCount2 < 2.0)
2756 double fS1 = (fSumSqr1-fSum1*fSum1/fCount1).
get() / (fCount1-1.0);
2757 double fS2 = (fSumSqr2-fSum2*fSum2/fCount2).
get() / (fCount2-1.0);
2758 if (fS1 == 0.0 || fS2 == 0.0)
2763 double fF, fF1, fF2;
2776 double fFcdf =
GetFDist(fF, fF1, fF2);
2777 PushDouble(2.0*std::min(fFcdf, 1.0 - fFcdf));
2786 if (!pMat1 || !pMat2)
2793 pMat1->GetDimensions(nC1, nR1);
2794 pMat2->GetDimensions(nC2, nR2);
2795 if (nR1 != nR2 || nC1 != nC2)
2804 for (
SCSIZE j = 0; j < nR1; j++)
2806 if (!(pMat1->IsEmpty(
i,j) || pMat2->IsEmpty(
i,j)))
2809 if (!pMat1->IsStringOrEmpty(
i,j) && !pMat2->IsStringOrEmpty(
i,j))
2811 double fValX = pMat1->GetDouble(
i,j);
2812 double fValE = pMat2->GetDouble(
i,j);
2815 PushError(FormulaError::DivisionByZero);
2823 volatile double fTemp1 = (fValX - fValE) * (fValX - fValE);
2824 double fTemp2 = fTemp1;
2825 if (std::isinf(fTemp2))
2847 if (nC1 == 1 || nR1 == 1)
2849 fDF =
static_cast<double>(nC1*nR1 - 1);
2857 fDF =
static_cast<double>(nC1-1)*
static_cast<double>(nR1-1);
2865 std::vector<double>
values;
2873 PushError( FormulaError::DivisionByZero);
2878 double fMean = fSum.
get() / fCount;
2880 vSum += (
v - fMean) * (
v - fMean);
2882 double fStdDev = sqrt(vSum.
get() / (fCount - 1.0));
2885 PushError( FormulaError::DivisionByZero);
2892 double dx = (
v - fMean) / fStdDev;
2893 xpower4 += (dx * dx) * (dx * dx);
2896 double k_d = (fCount - 2.0) * (fCount - 3.0);
2897 double k_l = fCount * (fCount + 1.0) / ((fCount - 1.0) * k_d);
2898 double k_t = 3.0 * (fCount - 1.0) * (fCount - 1.0) / k_d;
2905 short nParamCount =
GetByte();
2907 double nValCount = 0.0;
2910 size_t nRefInList = 0;
2911 while ((
nGlobalError == FormulaError::NONE) && (nParamCount-- > 0))
2924 SetError( FormulaError::IllegalArgument);
2940 SetError( FormulaError::IllegalArgument);
2951 if (aValIter.
GetFirst(nCellVal, nErr))
2955 nVal += 1.0/nCellVal;
2959 SetError( FormulaError::IllegalArgument);
2961 while ((nErr == FormulaError::NONE) && aValIter.
GetNext(nCellVal, nErr))
2965 nVal += 1.0/nCellVal;
2969 SetError( FormulaError::IllegalArgument);
2983 if (pMat->IsNumeric())
2987 double x = pMat->GetDouble(nElem);
2994 SetError( FormulaError::IllegalArgument);
3000 if (!pMat->IsStringOrEmpty(nElem))
3002 double x = pMat->GetDouble(nElem);
3009 SetError( FormulaError::IllegalArgument);
3015 default :
SetError(FormulaError::IllegalParameter);
break;
3026 short nParamCount =
GetByte();
3028 double nValCount = 0.0;
3032 size_t nRefInList = 0;
3033 while ((
nGlobalError == FormulaError::NONE) && (nParamCount-- > 0))
3045 else if (
x == 0.0 )
3048 while ( nParamCount-- > 0 )
3054 SetError( FormulaError::IllegalArgument);
3069 else if (
x == 0.0 )
3072 while ( nParamCount-- > 0 )
3078 SetError( FormulaError::IllegalArgument);
3089 if (aValIter.
GetFirst(nCellVal, nErr))
3093 nVal +=
log(nCellVal);
3096 else if ( nCellVal == 0.0 )
3099 while ( nParamCount-- > 0 )
3105 SetError( FormulaError::IllegalArgument);
3107 while ((nErr == FormulaError::NONE) && aValIter.
GetNext(nCellVal, nErr))
3111 nVal +=
log(nCellVal);
3114 else if ( nCellVal == 0.0 )
3117 while ( nParamCount-- > 0 )
3123 SetError( FormulaError::IllegalArgument);
3137 if (pMat->IsNumeric())
3141 double x = pMat->GetDouble(ui);
3147 else if (
x == 0.0 )
3150 while ( nParamCount-- > 0 )
3156 SetError( FormulaError::IllegalArgument);
3163 if (!pMat->IsStringOrEmpty(ui))
3165 double x = pMat->GetDouble(ui);
3171 else if (
x == 0.0 )
3174 while ( nParamCount-- > 0 )
3180 SetError( FormulaError::IllegalArgument);
3187 default :
SetError(FormulaError::IllegalParameter);
break;
3204 PushError( FormulaError::IllegalArgument);
3205 else if (sigma == 0.0)
3206 PushError( FormulaError::DivisionByZero);
3213 short nParamCount =
GetByte();
3222 size_t nRefInList = 0;
3223 while (nParamCount-- > 0)
3260 while ((nErr == FormulaError::NONE) && aValIter.
GetNext(fVal, nErr))
3278 if (pMat->IsNumeric())
3282 fVal = pMat->GetDouble(nElem);
3291 if (!pMat->IsStringOrEmpty(nElem))
3293 fVal = pMat->GetDouble(nElem);
3303 SetError(FormulaError::IllegalParameter);
3320 std::vector<double>
values;
3327 PushError(FormulaError::DivisionByZero);
3332 double fMean = fSum.
get() / fCount;
3334 vSum += (
v - fMean) * (
v - fMean);
3336 double fStdDev = sqrt( vSum.
get() / (bSkewp ? fCount : (fCount - 1.0)));
3346 double dx = (
v - fMean) / fStdDev;
3347 xcube += dx * dx * dx;
3353 PushDouble( ((xcube.
get() * fCount) / (fCount - 1.0)) / (fCount - 2.0) );
3368 size_t nSize = rArray.size();
3376 size_t nMid = nSize / 2;
3377 vector<double>::iterator iMid = rArray.begin() + nMid;
3378 ::std::nth_element( rArray.begin(), iMid, rArray.end());
3385 iMid = ::std::max_element( rArray.begin(), rArray.begin() + nMid);
3386 return (fUp + *iMid) / 2;
3395 vector<double> aArray;
3402 size_t nSize = rArray.size();
3407 size_t nIndex =
static_cast<size_t>(::rtl::math::approxFloor( fPercentile * (nSize-1)));
3408 double fDiff = fPercentile * (nSize-1) - ::rtl::math::approxFloor( fPercentile * (nSize-1));
3409 OSL_ENSURE(
nIndex < nSize,
"GetPercentile: wrong index(1)");
3410 vector<double>::iterator iter = rArray.begin() +
nIndex;
3411 ::std::nth_element( rArray.begin(), iter, rArray.end());
3421 OSL_ENSURE(
nIndex < nSize-1,
"GetPercentile: wrong index(2)");
3422 double fVal = *iter;
3423 iter = ::std::min_element( rArray.begin() +
nIndex + 1, rArray.end());
3424 return fVal + fDiff * (*iter - fVal);
3431 size_t nSize1 = rArray.size() + 1;
3432 if ( rArray.empty() || nSize1 == 1 ||
nGlobalError != FormulaError::NONE)
3437 if ( fPercentile * nSize1 < 1.0 || fPercentile * nSize1 >
static_cast<double>( nSize1 - 1 ) )
3439 SetError( FormulaError::IllegalParameter );
3443 size_t nIndex =
static_cast<size_t>(::rtl::math::approxFloor( fPercentile * nSize1 - 1 ));
3444 double fDiff = fPercentile * nSize1 - 1 - ::rtl::math::approxFloor( fPercentile * nSize1 - 1 );
3445 OSL_ENSURE(
nIndex < ( nSize1 - 1 ),
"GetPercentile: wrong index(1)");
3446 vector<double>::iterator iter = rArray.begin() +
nIndex;
3447 ::std::nth_element( rArray.begin(), iter, rArray.end());
3452 OSL_ENSURE(
nIndex < nSize1,
"GetPercentile: wrong index(2)");
3453 double fVal = *iter;
3454 iter = ::std::min_element( rArray.begin() +
nIndex + 1, rArray.end());
3455 return fVal + fDiff * (*iter - fVal);
3464 if ( bInclusive ? ( alpha < 0.0 || alpha > 1.0 ) : ( alpha <= 0.0 || alpha >= 1.0 ) )
3469 vector<double> aArray;
3471 if ( aArray.empty() ||
nGlobalError != FormulaError::NONE )
3486 double fFlag = ::rtl::math::approxFloor(
GetDouble());
3487 if ( bInclusive ? ( fFlag < 0.0 || fFlag > 4.0 ) : ( fFlag <= 0.0 || fFlag >= 4.0 ) )
3492 vector<double> aArray;
3494 if ( aArray.empty() ||
nGlobalError != FormulaError::NONE )
3510 vector<double> aSortArray;
3511 GetSortArray( nParamCount, aSortArray,
nullptr,
false,
false );
3512 SCSIZE nSize = aSortArray.size();
3518 double nOldVal = aSortArray[0];
3520 for (
i = 1;
i < nSize;
i++)
3522 if (aSortArray[
i] == nOldVal)
3526 nOldVal = aSortArray[
i];
3540 if (nMax == 1 &&
nCount == 1)
3554 vector<double> aArray;
3556 vector< double > aSortArray( aArray );
3558 SCSIZE nSize = aSortArray.size();
3559 if ( nSize == 0 ||
nGlobalError != FormulaError::NONE )
3564 double nOldVal = aSortArray[ 0 ];
3565 vector< double > aResultArray( 1 );
3567 for (
i = 1;
i < nSize;
i++ )
3569 if ( aSortArray[
i ] == nOldVal )
3578 if ( aResultArray.size() != 1 )
3579 vector< double >( 1 ).swap( aResultArray );
3580 aResultArray[ 0 ] = nOldVal;
3583 aResultArray.emplace_back( nOldVal );
3585 nOldVal = aSortArray[
i ];
3592 vector< double >().swap( aResultArray );
3593 aResultArray.emplace_back( nOldVal );
3595 if ( nMax == 1 &&
nCount == 1 )
3597 else if ( nMax == 1 )
3602 vector< vector< double > > aOrder;
3603 aOrder.resize( aResultArray.size(), vector< double >( 2 ) );
3604 for (
i = 0;
i < aResultArray.size();
i++ )
3606 for (
SCSIZE j = 0; j < nSize; j++ )
3608 if ( aArray[ j ] == aResultArray[
i ] )
3610 aOrder[
i ][ 0 ] = aResultArray[
i ];
3611 aOrder[
i ][ 1 ] = j;
3616 sort( aOrder.begin(), aOrder.end(), [](
const std::vector< double >& lhs,
3617 const std::vector< double >& rhs )
3618 { return lhs[ 1 ] < rhs[ 1 ]; } );
3625 for (
i = 0;
i < aResultArray.size();
i++ )
3626 aResultArray[
i ] = aOrder[
i ][ 0 ];
3628 pResMatrix->PutDoubleVector( aResultArray, 0, 0 );
3640 SCSIZE nCol = 0, nRow = 0;
3642 const size_t nRankArraySize = aArray.size();
3643 if (nRankArraySize == 0 ||
nGlobalError != FormulaError::NONE)
3648 assert(nRankArraySize == nCol * nRow);
3650 std::vector<SCSIZE> aRankArray;
3651 aRankArray.reserve(nRankArraySize);
3652 std::transform(aArray.begin(), aArray.end(), std::back_inserter(aRankArray),
3653 [bSmall](
double f) {
3654 f = (bSmall ? rtl::math::approxFloor(f) : rtl::math::approxCeil(f));
3656 if (f < 1.0 || !o3tl::convertsToAtMost(f, std::numeric_limits<SCSIZE>::max()))
3657 return static_cast<SCSIZE>(0);
3658 return static_cast<SCSIZE>(f);
3661 vector<double> aSortArray;
3663 const SCSIZE nSize = aSortArray.size();
3666 else if (nRankArraySize == 1)
3668 const SCSIZE k = aRankArray[0];
3669 if (k < 1 || nSize < k)
3671 if (!std::isfinite(aArray[0]))
3678 vector<double>::iterator iPos = aSortArray.begin() + (bSmall ? k-1 : nSize-k);
3679 ::std::nth_element( aSortArray.begin(), iPos, aSortArray.end());
3685 std::set<SCSIZE> aIndices;
3688 if (1 <=
n &&
n <= nSize)
3689 aIndices.insert(bSmall ?
n-1 : nSize-
n);
3694 if (aIndices.size() < nSize/3)
3696 auto itBegin = aSortArray.begin();
3699 auto it = aSortArray.begin() +
i;
3700 std::nth_element(itBegin, it, aSortArray.end());
3705 std::sort(aSortArray.begin(), aSortArray.end());
3707 std::vector<double> aResultArray;
3708 aResultArray.reserve(nRankArraySize);
3709 for (
size_t i = 0;
i < nRankArraySize; ++
i)
3712 if (1 <=
n &&
n <= nSize)
3713 aResultArray.push_back( aSortArray[bSmall ?
n-1 : nSize-
n]);
3714 else if (!std::isfinite( aArray[
i]))
3715 aResultArray.push_back( aArray[
i]);
3739 double fSignificance = ( nParamCount == 3 ? ::rtl::math::approxFloor(
GetDouble() ) : 3.0 );
3740 if ( fSignificance < 1.0 )
3746 vector<double> aSortArray;
3748 SCSIZE nSize = aSortArray.size();
3749 if ( nSize == 0 ||
nGlobalError != FormulaError::NONE )
3753 if ( fNum < aSortArray[ 0 ] || fNum > aSortArray[ nSize - 1 ] )
3764 double fExp = ::rtl::math::approxFloor( log10( fRes ) ) + 1.0 - fSignificance;
3765 fRes = ::rtl::math::round( fRes * pow( 10, -fExp ) ) / pow( 10, -fExp );
3774 SCSIZE nSize = rArray.size();
3776 if ( fVal == rArray[ 0 ] )
3781 fRes = 1.0 /
static_cast<double>( nSize + 1 );
3786 double fOldVal = rArray[ 0 ];
3788 for (
i = 1;
i < nSize && rArray[
i ] < fVal;
i++ )
3790 if ( rArray[
i ] != fOldVal )
3793 fOldVal = rArray[
i ];
3796 if ( rArray[
i ] != fOldVal )
3798 if ( fVal == rArray[
i ] )
3801 fRes =
div( nOldCount, nSize - 1 );
3803 fRes =
static_cast<double>(
i + 1 ) /
static_cast<double>( nSize + 1 );
3810 if ( nOldCount == 0 )
3812 OSL_FAIL(
"should not happen" );
3817 double fFract = ( fVal - rArray[ nOldCount - 1 ] ) /
3818 ( rArray[ nOldCount ] - rArray[ nOldCount - 1 ] );
3820 fRes =
div(
static_cast<double>( nOldCount - 1 ) + fFract, nSize - 1 );
3822 fRes = (
static_cast<double>(nOldCount) + fFract ) /
static_cast<double>( nSize + 1 );
3834 if (alpha < 0.0 || alpha >= 1.0)
3839 vector<double> aSortArray;
3841 SCSIZE nSize = aSortArray.size();
3850 OSL_ENSURE(
nIndex < nSize,
"ScTrimMean: wrong index");
3853 fSum += aSortArray[
i];
3860 std::vector<double> aArray;
3889 SetError(FormulaError::IllegalParameter);
3898 aArray.reserve(rCol * rRow);
3903 if (aValIter.
GetFirst(fCellVal, nErr))
3906 aArray.push_back(fCellVal);
3907 while (aValIter.
GetNext(fCellVal, nErr) && nErr == FormulaError::NONE);
3915 if (aArray.size() != rCol * rRow)
3933 pMat->SetErrorInterpreter(
nullptr);
3934 if (pMat->IsNumeric())
3937 aArray.push_back(pMat->GetDouble(
i));
3943 if (pMat->IsValue(
i))
3944 aArray.push_back( pMat->GetDouble(
i));
3949 pMat->GetDimensions(rCol, rRow);
3954 SetError(FormulaError::IllegalParameter);
3965 short nParam = nParamCount;
3966 size_t nRefInList = 0;
3968 while (nParam-- > 0)
3980 if (bIgnoreErrVal && aCell.
hasError())
3996 rArray.reserve( rArray.size() + nCellCount);
4001 if (aValIter.
GetFirst( fCellVal, nErr))
4005 if (nErr == FormulaError::NONE)
4006 rArray.push_back( fCellVal);
4007 while (aValIter.
GetNext( fCellVal, nErr))
4009 if (nErr == FormulaError::NONE)
4010 rArray.push_back( fCellVal);
4015 rArray.push_back( fCellVal);
4017 while ((nErr == FormulaError::NONE) && aValIter.
GetNext( fCellVal, nErr))
4018 rArray.push_back( fCellVal);
4033 rArray.reserve( rArray.size() +
nCount);
4034 if (pMat->IsNumeric())
4040 const double fVal = pMat->GetDouble(
i);
4042 rArray.push_back( fVal);
4050 rArray.push_back( pMat->GetDouble(
i));
4053 else if (bConvertTextInArray && eStackType ==
svMatrix)
4057 if ( pMat->IsValue(
i ) )
4061 const double fVal = pMat->GetDouble(
i);
4063 rArray.push_back( fVal);
4068 rArray.push_back( pMat->GetDouble(
i));
4073 OUString
aStr = pMat->GetString(
i ).getString();
4074 if (
aStr.getLength() > 0 )
4081 rArray.push_back( fVal );
4091 if (nErr != FormulaError::NONE)
4093 else if (!bIgnoreErrVal)
4108 if (pMat->IsValue(
i))
4110 const double fVal = pMat->GetDouble(
i);
4112 rArray.push_back( fVal);
4122 if (pMat->IsValue(
i))
4123 rArray.push_back( pMat->GetDouble(
i));
4131 SetError( FormulaError::IllegalParameter);
4139 while (nParam-- > 0)
4147 SetError( FormulaError::MatrixSize);
4148 else if ( rSortArray.empty() )
4150 if ( bAllowEmptyArray )
4167 if (rSortArray[nLo] > rSortArray[nHi])
4169 swap(rSortArray[nLo], rSortArray[nHi]);
4171 swap(pIndexOrder->at(nLo), pIndexOrder->at(nHi));
4180 double fLo = rSortArray[nLo];
4181 while (ni <= nHi && rSortArray[ni] < fLo) ni++;
4182 while (nj >= nLo && fLo < rSortArray[nj]) nj--;
4187 swap(rSortArray[ni], rSortArray[nj]);
4189 swap(pIndexOrder->at(ni), pIndexOrder->at(nj));
4198 if ((nj - nLo) < (nHi - ni))
4200 if (nLo < nj)
lcl_QuickSort(nLo, nj, rSortArray, pIndexOrder);
4201 if (ni < nHi)
lcl_QuickSort(ni, nHi, rSortArray, pIndexOrder);
4205 if (ni < nHi)
lcl_QuickSort(ni, nHi, rSortArray, pIndexOrder);
4206 if (nLo < nj)
lcl_QuickSort(nLo, nj, rSortArray, pIndexOrder);
4216 pIndexOrder->clear();
4217 pIndexOrder->reserve(
n);
4219 pIndexOrder->push_back(
i);
4225 size_t nValCount = rSortArray.size();
4226 for (
size_t i = 0; (
i + 4) <= nValCount-1;
i += 4)
4229 ::std::swap( rSortArray[
i], rSortArray[nInd]);
4231 ::std::swap( pIndexOrder->at(
i), pIndexOrder->at(nInd));
4243 if ( nParamCount == 3 )
4248 vector<double> aSortArray;
4251 SCSIZE nSize = aSortArray.size();
4252 if ( nSize == 0 ||
nGlobalError != FormulaError::NONE )
4256 if ( fVal < aSortArray[ 0 ] || fVal > aSortArray[ nSize - 1 ] )
4260 double fLastPos = 0;
4261 double fFirstPos = -1.0;
4262 bool bFinished =
false;
4264 for (
i = 0;
i < nSize && !bFinished;
i++)
4266 if ( aSortArray[
i ] == fVal )
4268 if ( fFirstPos < 0 )
4269 fFirstPos =
i + 1.0;
4273 if ( aSortArray[
i ] > fVal )
4286 else if ( !bAverage )
4296 PushDouble( ( fFirstPos + fLastPos ) / 2.0 );
4298 PushDouble( nSize + 1.0 - ( fFirstPos + fLastPos ) / 2.0 );
4309 sal_uInt16 SaveSP =
sp;
4310 double nMiddle = 0.0;
4312 double rValCount = 0.0;
4315 short nParam = nParamCount;
4316 size_t nRefInList = 0;
4317 while (nParam-- > 0)
4343 if (aValIter.
GetFirst(nCellVal, nErr))
4348 while ((nErr == FormulaError::NONE) && aValIter.
GetNext(nCellVal, nErr))
4365 if (pMat->IsNumeric())
4369 rVal += pMat->GetDouble(nElem);
4376 if (!pMat->IsStringOrEmpty(nElem))
4378 rVal += pMat->GetDouble(nElem);
4386 SetError(FormulaError::IllegalParameter);
4395 nMiddle = rVal.
get() / rValCount;
4398 nParam = nParamCount;
4400 while (nParam-- > 0)
4405 rVal += std::abs(
GetDouble() - nMiddle);
4422 if (aValIter.
GetFirst(nCellVal, nErr))
4424 rVal += std::abs(nCellVal - nMiddle);
4425 while (aValIter.
GetNext(nCellVal, nErr))
4426 rVal += std::abs(nCellVal - nMiddle);
4438 if (pMat->IsNumeric())
4442 rVal += std::abs(pMat->GetDouble(nElem) - nMiddle);
4449 if (!pMat->IsStringOrEmpty(nElem))
4450 rVal += std::abs(pMat->GetDouble(nElem) - nMiddle);
4456 default :
SetError(FormulaError::IllegalParameter);
break;
4464 auto VarResult = [](
double fVal,
size_t )
4478 if (nParamCount == 4)
4483 std::swap( fLo, fUp );
4486 if (!pMatP || !pMatW)
4492 pMatP->GetDimensions(nC1, nR1);
4493 pMatW->GetDimensions(nC2, nR2);
4494 if (nC1 != nC2 || nR1 != nR2 || nC1 == 0 || nR1 == 0 ||
4495 nC2 == 0 || nR2 == 0)
4503 for (
SCSIZE i = 0;
i < nC1 && !bStop;
i++ )
4505 for (
SCSIZE j = 0; j < nR1 && !bStop; ++j )
4507 if (pMatP->IsValue(
i,j) && pMatW->IsValue(
i,j))
4509 fP = pMatP->GetDouble(
i,j);
4510 fW = pMatW->GetDouble(
i,j);
4511 if (fP < 0.0 || fP > 1.0)
4516 if (fW >= fLo && fW <= fUp)
4521 SetError( FormulaError::IllegalArgument);
4524 if (bStop || std::abs((fSum -1.0).
get()) > 1.0E-7)
4559 if (!pMat1 || !pMat2)
4566 pMat1->GetDimensions(nC1, nR1);
4567 pMat2->GetDimensions(nC2, nR2);
4568 if (nR1 != nR2 || nC1 != nC2)
4578 double fCount = 0.0;
4584 for (
SCSIZE j = 0; j < nR1; j++)
4586 if (!pMat1->IsStringOrEmpty(
i,j) && !pMat2->IsStringOrEmpty(
i,j))
4588 fSumX += pMat1->GetDouble(
i,j);
4589 fSumY += pMat2->GetDouble(
i,j);
4594 if (fCount < (_bStexy ? 3.0 : (_bSample ? 2.0 : 1.0)))
4601 const double fMeanX = fSumX.
get() / fCount;
4602 const double fMeanY = fSumY.
get() / fCount;
4605 for (
SCSIZE j = 0; j < nR1; j++)
4607 if (!pMat1->IsStringOrEmpty(
i,j) && !pMat2->IsStringOrEmpty(
i,j))
4609 const double fValX = pMat1->GetDouble(
i,j);
4610 const double fValY = pMat2->GetDouble(
i,j);
4611 fSumDeltaXDeltaY += (fValX - fMeanX) * (fValY - fMeanY);
4614 fSumSqrDeltaX += (fValX - fMeanX) * (fValX - fMeanX);
4615 fSumSqrDeltaY += (fValY - fMeanY) * (fValY - fMeanY);
4623 if (fSumSqrDeltaX < ::std::numeric_limits<double>::min()
4624 || (!_bStexy && fSumSqrDeltaY < ::std::numeric_limits<double>::min()))
4625 PushError( FormulaError::DivisionByZero);
4627 PushDouble( sqrt( ( fSumSqrDeltaY - fSumDeltaXDeltaY *
4628 fSumDeltaXDeltaY / fSumSqrDeltaX ).
get() / (fCount-2)));
4673 if (!pMat1 || !pMat2)
4680 pMat1->GetDimensions(nC1, nR1);
4681 pMat2->GetDimensions(nC2, nR2);
4682 if (nR1 != nR2 || nC1 != nC2)
4688 double fCount = 0.0;
4694 for (
SCSIZE j = 0; j < nR1; j++)
4696 if (!pMat1->IsStringOrEmpty(
i,j) && !pMat2->IsStringOrEmpty(
i,j))
4698 fSumX += pMat1->GetDouble(
i,j);
4699 fSumY += pMat2->GetDouble(
i,j);
4710 double fMeanX = fSumX.
get() / fCount;
4711 double fMeanY = fSumY.
get() / fCount;
4714 for (
SCSIZE j = 0; j < nR1; j++)
4716 if (!pMat1->IsStringOrEmpty(
i,j) && !pMat2->IsStringOrEmpty(
i,j))
4718 double fValX = pMat1->GetDouble(
i,j);
4719 double fValY = pMat2->GetDouble(
i,j);
4720 fSumDeltaXDeltaY += (fValX - fMeanX) * (fValY - fMeanY);
4721 fSumSqrDeltaX += (fValX - fMeanX) * (fValX - fMeanX);
4725 if (fSumSqrDeltaX == 0.0)
4726 PushError( FormulaError::DivisionByZero);
4732 PushDouble( fMeanY - fSumDeltaXDeltaY.
get() / fSumSqrDeltaX.
get() * fMeanX);
4753 if (!pMat1 || !pMat2)
4760 pMat1->GetDimensions(nC1, nR1);
4761 pMat2->GetDimensions(nC2, nR2);
4762 if (nR1 != nR2 || nC1 != nC2)
4769 double fCount = 0.0;
4775 for (
SCSIZE j = 0; j < nR1; j++)
4777 if (!pMat1->IsStringOrEmpty(
i,j) && !pMat2->IsStringOrEmpty(
i,j))
4779 fSumX += pMat1->GetDouble(
i,j);
4780 fSumY += pMat2->GetDouble(
i,j);
4791 double fMeanX = fSumX.
get() / fCount;
4792 double fMeanY = fSumY.
get() / fCount;
4795 for (
SCSIZE j = 0; j < nR1; j++)
4797 if (!pMat1->IsStringOrEmpty(
i,j) && !pMat2->IsStringOrEmpty(
i,j))
4799 double fValX = pMat1->GetDouble(
i,j);
4800 double fValY = pMat2->GetDouble(
i,j);
4801 fSumDeltaXDeltaY += (fValX - fMeanX) * (fValY - fMeanY);
4802 fSumSqrDeltaX += (fValX - fMeanX) * (fValX - fMeanX);
4806 if (fSumSqrDeltaX == 0.0)
4807 PushError( FormulaError::DivisionByZero);
4809 PushDouble( fMeanY + fSumDeltaXDeltaY.
get() / fSumSqrDeltaX.
get() * (fVal - fMeanX));
4817 nNumBits = std::numeric_limits<SCSIZE>::digits;
4818 nPow2 <<= (nNumBits - 1);
4829 nNum = nPow2 ? (nPow2 << 1) : 1;
4837 for (
SCSIZE nMask = 1; nMask < nBound; nMask <<= 1)
4851struct ScTwiddleFactors
4853 ScTwiddleFactors(
SCSIZE nN,
bool bInverse) :
4864 mbInverse = !mbInverse;
4865 for (
SCSIZE nIdx = 0; nIdx < mnN; ++nIdx)
4866 mfWImag[nIdx] = -mfWImag[nIdx];
4869 std::vector<double> mfWReal;
4870 std::vector<double> mfWImag;
4877void ScTwiddleFactors::Compute()
4879 mfWReal.resize(mnN);
4880 mfWImag.resize(mnN);
4882 double nW = (mbInverse ? 2 : -2)*M_PI/
static_cast<double>(mnN);
4903 mfWImag[1] = (mbInverse ? 1.0 : -1.0);
4909 mfWImag[3] = (mbInverse ? -1.0 : 1.0);
4911 else if ((mnN % 4) == 0)
4913 const SCSIZE nQSize = mnN >> 2;
4916 for (
SCSIZE nIdx = 0; nIdx <= nQSize; ++nIdx)
4917 mfWReal[nIdx] = cos(nW*
static_cast<double>(nIdx));
4921 const SCSIZE nQ1End = nQSize;
4923 for (
SCSIZE nIdx = 0; nIdx <= nQ1End; ++nIdx)
4924 mfWImag[nIdx] = mfWReal[nQ1End-nIdx];
4927 const SCSIZE nQ2End = nQ1End << 1;
4928 for (
SCSIZE nIdx = nQ1End+1; nIdx <= nQ2End; ++nIdx)
4930 mfWReal[nIdx] = -mfWReal[nQ2End - nIdx];
4931 mfWImag[nIdx] = mfWImag[nQ2End - nIdx];
4935 const SCSIZE nQ3End = nQ2End + nQ1End;
4936 for (
SCSIZE nIdx = nQ2End+1; nIdx <= nQ3End; ++nIdx)
4938 mfWReal[nIdx] = -mfWReal[nIdx - nQ2End];
4939 mfWImag[nIdx] = -mfWImag[nIdx - nQ2End];
4943 for (
SCSIZE nIdx = nQ3End+1; nIdx < mnN; ++nIdx)
4945 mfWReal[nIdx] = mfWReal[mnN - nIdx];
4946 mfWImag[nIdx] = -mfWImag[mnN - nIdx];
4951 const SCSIZE nQ4End = nQSize;
4952 const SCSIZE nQ3End = nQSize << 1;
4953 const SCSIZE nQ2End = nQ3End + nQSize;
4956 for (
SCSIZE nIdx = 0; nIdx <= nQ4End; ++nIdx)
4957 mfWImag[nIdx] = -mfWReal[nQ4End - nIdx];
4960 for (
SCSIZE nIdx = nQ4End+1; nIdx <= nQ3End; ++nIdx)
4962 mfWReal[nIdx] = -mfWReal[nQ3End - nIdx];
4963 mfWImag[nIdx] = mfWImag[nQ3End - nIdx];
4967 for (
SCSIZE nIdx = nQ3End+1; nIdx <= nQ2End; ++nIdx)
4969 mfWReal[nIdx] = -mfWReal[nIdx - nQ3End];
4970 mfWImag[nIdx] = -mfWImag[nIdx - nQ3End];
4974 for (
SCSIZE nIdx = nQ2End+1; nIdx < mnN; ++nIdx)
4976 mfWReal[nIdx] = mfWReal[mnN - nIdx];
4977 mfWImag[nIdx] = -mfWImag[mnN - nIdx];
4983 for (
SCSIZE nIdx = 0; nIdx < mnN; ++nIdx)
4985 double fAngle = nW*
static_cast<double>(nIdx);
4986 mfWReal[nIdx] = cos(fAngle);
4987 mfWImag[nIdx] = sin(fAngle);
5000 ScComplexFFT2(std::vector<double>& raArray,
bool bInverse,
bool bPolar,
double fMinMag,
5001 ScTwiddleFactors& rTF,
bool bSubSampleTFs =
false,
bool bDisableNormalize =
false) :
5003 mfWReal(rTF.mfWReal),
5004 mfWImag(rTF.mfWImag),
5005 mnPoints(raArray.
size()/2),
5008 mbInverse(bInverse),
5010 mbDisableNormalize(bDisableNormalize),
5011 mbSubSampleTFs(bSubSampleTFs)
5020 double getReal(
SCSIZE nIdx)
5022 return mrArray[nIdx];
5025 void setReal(
double fVal,
SCSIZE nIdx)
5027 mrArray[nIdx] = fVal;
5030 double getImag(
SCSIZE nIdx)
5032 return mrArray[mnPoints + nIdx];
5035 void setImag(
double fVal,
SCSIZE nIdx)
5037 mrArray[mnPoints + nIdx] = fVal;
5042 return ( ( nPtIndex << nTfIdxScaleBits ) & ( mnPoints - 1 ) );
5053 const double x1r = getReal(nTopIdx);
5054 const double x2r = getReal(nBottomIdx);
5056 const double& w1r = mfWReal[nWIdx1];
5057 const double& w1i = mfWImag[nWIdx1];
5059 const double& w2r = mfWReal[nWIdx2];
5060 const double& w2i = mfWImag[nWIdx2];
5062 const double x1i = getImag(nTopIdx);
5063 const double x2i = getImag(nBottomIdx);
5065 setReal(x1r + x2r*w1r - x2i*w1i, nTopIdx);
5066 setImag(x1i + x2i*w1r + x2r*w1i, nTopIdx);
5068 setReal(x1r + x2r*w2r - x2i*w2i, nBottomIdx);
5069 setImag(x1i + x2i*w2r + x2r*w2i, nBottomIdx);
5072 std::vector<double>& mrArray;
5073 std::vector<double>& mfWReal;
5074 std::vector<double>& mfWImag;
5080 bool mbDisableNormalize:1;
5081 bool mbSubSampleTFs:1;
5086void ScComplexFFT2::prepare()
5088 SCSIZE nPoints = mnPoints;
5090 assert(nPoints == mnPoints);
5093 for (
SCSIZE nIdx = 0; nIdx < mnPoints; ++nIdx)
5098 double fTmp = getReal(nIdx);
5099 setReal(getReal(nRevIdx), nIdx);
5100 setReal(fTmp, nRevIdx);
5102 fTmp = getImag(nIdx);
5103 setImag(getImag(nRevIdx), nIdx);
5104 setImag(fTmp, nRevIdx);
5111 const SCSIZE nPoints = rCmplxArray.size()/2;
5112 const double fScale = 1.0/
static_cast<double>(nPoints);
5115 for (
SCSIZE nIdx = 0; nIdx < nPoints; ++nIdx)
5116 rCmplxArray[nIdx] *= fScale;
5118 if (!bScaleOnlyReal)
5120 const SCSIZE nLen = nPoints*2;
5121 for (
SCSIZE nIdx = nPoints; nIdx < nLen; ++nIdx)
5122 rCmplxArray[nIdx] *= fScale;
5128 const SCSIZE nPoints = rCmplxArray.size()/2;
5129 double fMag, fPhase, fR, fI;
5130 for (
SCSIZE nIdx = 0; nIdx < nPoints; ++nIdx)
5132 fR = rCmplxArray[nIdx];
5133 fI = rCmplxArray[nPoints+nIdx];
5134 fMag = std::hypot(fR, fI);
5142 fPhase = atan2(fI, fR);
5145 rCmplxArray[nIdx] = fMag;
5146 rCmplxArray[nPoints+nIdx] = fPhase;
5150void ScComplexFFT2::Compute()
5154 const SCSIZE nFliesInStage = mnPoints/2;
5155 for (
SCSIZE nStage = 0; nStage < mnStages; ++nStage)
5157 const SCSIZE nTFIdxScaleBits = mnStages - nStage - 1;
5159 const SCSIZE nGroups = nFliesInStage/nFliesInGroup;
5160 const SCSIZE nFlyWidth = nFliesInGroup;
5161 for (
SCSIZE nGroup = 0, nFlyTopIdx = 0; nGroup < nGroups; ++nGroup)
5163 for (
SCSIZE nFly = 0; nFly < nFliesInGroup; ++nFly, ++nFlyTopIdx)
5165 SCSIZE nFlyBottomIdx = nFlyTopIdx + nFlyWidth;
5166 SCSIZE nWIdx1 = getTFactorIndex(nFlyTopIdx, nTFIdxScaleBits);
5167 SCSIZE nWIdx2 = getTFactorIndex(nFlyBottomIdx, nTFIdxScaleBits);
5169 computeFly(nFlyTopIdx, nFlyBottomIdx, nWIdx1, nWIdx2);
5172 nFlyTopIdx += nFlyWidth;
5181 if (mbInverse && !mbDisableNormalize)
5189class ScComplexBluesteinFFT
5193 ScComplexBluesteinFFT(std::vector<double>& rArray,
bool bReal,
bool bInverse,
5194 bool bPolar,
double fMinMag,
bool bDisableNormalize =
false) :
5196 mnPoints(rArray.
size()/2),
5199 mbInverse(bInverse),
5201 mbDisableNormalize(bDisableNormalize)
5207 std::vector<double>& mrArray;
5213 bool mbDisableNormalize:1;
5218void ScComplexBluesteinFFT::Compute()
5220 std::vector<double> aRealScalars(mnPoints);
5221 std::vector<double> aImagScalars(mnPoints);
5222 double fW = (mbInverse ? 2 : -2)*M_PI/
static_cast<double>(mnPoints);
5223 for (
SCSIZE nIdx = 0; nIdx < mnPoints; ++nIdx)
5225 double fAngle = 0.5*fW*
static_cast<double>(nIdx*nIdx);
5226 aRealScalars[nIdx] = cos(fAngle);
5227 aImagScalars[nIdx] = sin(fAngle);
5230 SCSIZE nMinSize = mnPoints*2 - 1;
5231 SCSIZE nExtendedLength = nMinSize, nTmp = 0;
5233 std::vector<double> aASignal(nExtendedLength*2);
5234 std::vector<double> aBSignal(nExtendedLength*2);
5236 double fReal, fImag;
5237 for (
SCSIZE nIdx = 0; nIdx < mnPoints; ++nIdx)
5240 aASignal[nIdx] = mrArray[nIdx]*aRealScalars[nIdx] + (mbReal ? 0.0 : -mrArray[mnPoints+nIdx]*aImagScalars[nIdx]);
5242 aASignal[nExtendedLength + nIdx] = mrArray[nIdx]*aImagScalars[nIdx] + (mbReal ? 0.0 : mrArray[mnPoints+nIdx]*aRealScalars[nIdx]);
5245 aBSignal[nIdx] = fReal = aRealScalars[nIdx];
5247 aBSignal[nExtendedLength + nIdx] = fImag = -aImagScalars[nIdx];
5252 aBSignal[nExtendedLength - nIdx] = fReal;
5253 aBSignal[(nExtendedLength<<1) - nIdx] = fImag;
5258 ScTwiddleFactors aTF(nExtendedLength,
false );
5262 ScComplexFFT2 aFFT2A(aASignal,
false ,
false , 0.0 ,
5263 aTF,
false ,
true );
5266 ScComplexFFT2 aFFT2B(aBSignal,
false ,
false , 0.0 ,
5267 aTF,
false ,
true );
5270 double fAR, fAI, fBR, fBI;
5271 for (
SCSIZE nIdx = 0; nIdx < nExtendedLength; ++nIdx)
5273 fAR = aASignal[nIdx];
5274 fAI = aASignal[nExtendedLength + nIdx];
5275 fBR = aBSignal[nIdx];
5276 fBI = aBSignal[nExtendedLength + nIdx];
5279 aASignal[nIdx] = fAR*fBR - fAI*fBI;
5280 aASignal[nExtendedLength + nIdx] = fAR*fBI + fAI*fBR;
5285 ScComplexFFT2 aFFT2AI(aASignal,
true ,
false , 0.0 , aTF);
5290 for (
SCSIZE nIdx = 0; nIdx < mnPoints; ++nIdx)
5292 fReal = aASignal[nIdx];
5293 fImag = aASignal[nExtendedLength + nIdx];
5294 mrArray[nIdx] = fReal*aRealScalars[nIdx] - fImag*aImagScalars[nIdx];
5295 mrArray[mnPoints + nIdx] = fReal*aImagScalars[nIdx] + fImag*aRealScalars[nIdx];
5304 if (mbInverse && !mbDisableNormalize)
5317 ScRealFFT(std::vector<double>& rInArray, std::vector<double>& rOutArray,
bool bInverse,
5318 bool bPolar,
double fMinMag) :
5319 mrInArray(rInArray),
5320 mrOutArray(rOutArray),
5322 mbInverse(bInverse),
5329 std::vector<double>& mrInArray;
5330 std::vector<double>& mrOutArray;
5338void ScRealFFT::Compute()
5341 assert(mrInArray.size() % 2 == 0);
5342 assert(mrInArray.size()*2 == mrOutArray.size());
5345 const SCSIZE nN = mrInArray.size()/2;
5348 mrOutArray[0] = mrInArray[0];
5349 mrOutArray[1] = 0.0;
5354 std::vector<double> aWorkArray(nN*2);
5355 for (
SCSIZE nIdx = 0; nIdx < nN; ++nIdx)
5357 SCSIZE nDoubleIdx = 2*nIdx;
5359 aWorkArray[nIdx] = mrInArray[nDoubleIdx];
5361 aWorkArray[nN+nIdx] = mrInArray[nDoubleIdx+1];
5364 ScTwiddleFactors aTFs(nN*2, mbInverse);
5366 SCSIZE nNextPow2 = nN, nTmp = 0;
5369 if (nNextPow2 == nN)
5371 ScComplexFFT2 aFFT2(aWorkArray, mbInverse,
false , 0.0 ,
5372 aTFs,
true ,
true );
5377 ScComplexBluesteinFFT aFFT(aWorkArray,
false , mbInverse,
false ,
5384 const SCSIZE nTwoN = 2*nN, nThreeN = 3*nN;
5385 double fY1R, fY2R, fY1I, fY2I, fResR, fResI, fWR, fWI;
5386 for (
SCSIZE nIdx = 0; nIdx < nN; ++nIdx)
5388 const SCSIZE nIdxRev = nIdx ? (nN - nIdx) : 0;
5389 fY1R = aWorkArray[nIdx];
5390 fY2R = aWorkArray[nIdxRev];
5391 fY1I = aWorkArray[nN + nIdx];
5392 fY2I = aWorkArray[nN + nIdxRev];
5393 fWR = aTFs.mfWReal[nIdx];
5394 fWI = aTFs.mfWImag[nIdx];
5399 mrOutArray[nIdx] = fResR = 0.5*(
5401 fWR * (fY1I + fY2I) +
5402 fWI * (fY1R - fY2R) );
5405 mrOutArray[nTwoN + nIdx] = fResI = 0.5*(
5407 fWI * (fY1I + fY2I) -
5408 fWR * (fY1R - fY2R) );
5414 mrOutArray[nN + nIdxRev] = fResR;
5416 mrOutArray[nThreeN + nIdxRev] = -fResI;
5420 mrOutArray[nN] = fY1R - fY1I;
5421 mrOutArray[nThreeN] = 0.0;
5444 ScFFT(
ScMatrixRef& pMat,
bool bReal,
bool bInverse,
bool bPolar,
double fMinMag) :
5448 mbInverse(bInverse),
5452 ScMatrixRef Compute(
const std::function<ScMatrixGenerator>& rMatGenFunc);
5464ScMatrixRef ScFFT::Compute(
const std::function<ScMatrixGenerator>& rMatGenFunc)
5466 std::vector<double> aArray;
5467 mpInputMat->GetDoubleArray(aArray);
5468 SCSIZE nPoints = mbReal ? aArray.size() : (aArray.size()/2);
5471 std::vector<double> aOutArray(2);
5472 aOutArray[0] = aArray[0];
5473 aOutArray[1] = mbReal ? 0.0 : aArray[1];
5476 return rMatGenFunc(2, 1, aOutArray);
5479 if (mbReal && (nPoints % 2) == 0)
5481 std::vector<double> aOutArray(nPoints*2);
5482 ScRealFFT aFFT(aArray, aOutArray, mbInverse, mbPolar, mfMinMag);
5484 return rMatGenFunc(2, nPoints, aOutArray);
5487 SCSIZE nNextPow2 = nPoints, nTmp = 0;
5489 if (nNextPow2 == nPoints && !mbReal)
5491 ScTwiddleFactors aTF(nPoints, mbInverse);
5493 ScComplexFFT2 aFFT2(aArray, mbInverse, mbPolar, mfMinMag, aTF);
5495 return rMatGenFunc(2, nPoints, aArray);
5499 aArray.resize(nPoints*2, 0.0);
5500 ScComplexBluesteinFFT aFFT(aArray, mbReal, mbInverse, mbPolar, mfMinMag);
5502 return rMatGenFunc(2, nPoints, aArray);
5511 bool bInverse =
false;
5512 bool bPolar =
false;
5513 double fMinMag = 0.0;
5515 if (nParamCount == 5)
5523 if (nParamCount >= 4)
5531 if (nParamCount >= 3)
5539 bool bGroupedByColumn =
GetBool();
5549 pInputMat->GetDimensions(nC, nR);
5551 if ((bGroupedByColumn && nC > 2) || (!bGroupedByColumn && nR > 2))
5559 if (!pInputMat->IsNumeric())
5565 bool bRealInput =
true;
5566 if (!bGroupedByColumn)
5568 pInputMat->MatTrans(*pInputMat);
5569 bRealInput = (nR == 1);
5573 bRealInput = (nC == 1);
5576 ScFFT aFFT(pInputMat, bRealInput, bInverse, bPolar, fMinMag);
5577 std::function<ScMatrixGenerator> aFunc = [
this](
SCSIZE nCol,
SCSIZE nRow, std::vector<double>& rVec) ->
ScMatrixRef
5579 return this->
GetNewMat(nCol, nRow, rVec);
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 ...
This class provides LO with Kahan summation algorithm About this algorithm: https://en....
double get() const
Returns the final sum.
virtual ~ScBetaDistFunction()
ScBetaDistFunction(ScInterpreter &rI, double fpVal, double fAlphaVal, double fBetaVal)
double GetValue(double x) const override
double GetValue(double x) const override
ScChiDistFunction(ScInterpreter &rI, double fpVal, double fDFVal)
virtual ~ScChiDistFunction()
virtual ~ScChiSqDistFunction()
double GetValue(double x) const override
ScChiSqDistFunction(ScInterpreter &rI, double fpVal, double fDFVal)
ScSheetLimits & GetSheetLimits() const
double GetValue(double x) const override
virtual ~ScFDistFunction()
ScFDistFunction(ScInterpreter &rI, double fpVal, double fF1Val, double fF2Val)
ScGammaDistFunction(ScInterpreter &rI, double fpVal, double fAlphaVal, double fBetaVal)
double GetValue(double x) const override
virtual ~ScGammaDistFunction()
void ScNormDist(int nMinParamCount)
void SetError(FormulaError nError)
double GetBetaDistPDF(double fX, double fA, double fB)
double GetBinomDistPMF(double x, double n, double p)
double ConvertStringToValue(const OUString &)
bool CalculateSkew(KahanSum &fSum, double &fCount, std::vector< double > &values)
static double gauss(double x)
double GetChiDist(double fChi, double fDF)
You must ensure fDF>0.0.
bool MustHaveParamCount(short nAct, short nMust)
bool MustHaveParamCountMin(short nAct, short nMin)
SubtotalFlags mnSubTotalFlags
static const double fMaxGammaArgument
void CalculateSkewOrSkewp(bool bSkewp)
void PushIllegalParameter()
FormulaError nGlobalError
void PushIllegalArgument()
double GetGamma(double x)
You must ensure non integer arguments for fZ<1.
void ScLogNormDist(int nMinParamCount)
void ScTDist_T(int nTails)
static double taylor(const double *pPolynom, sal_uInt16 nMax, double x)
void ScRank(bool bAverage)
ScInterpreterContext & mrContext
void CalculateSmallLarge(bool bSmall)
static double integralPhi(double x)
void ScBetaDist_MS()
Microsoft version has parameters in different order Also, upper and lowerbound are optional and have ...
void PushError(FormulaError nError)
sal_uInt8 GetByte() const
void CalculatePearsonCovar(bool _bPearson, bool _bStexy, bool _bSample)
double GetBeta(double fAlpha, double fBeta)
std::vector< double > GetRankNumberArray(SCSIZE &rCol, SCSIZE &rRow)
void ScModalValue_MS(bool bSingle)
ScMatrixRef GetNewMat(SCSIZE nC, SCSIZE nR, bool bEmpty=false)
double GetTInv(double fAlpha, double fSize, int nType)
static double GetLogBeta(double fAlpha, double fBeta)
double GetLowRegIGamma(double fA, double fX)
You must ensure fA>0.0 && fX>0.0)
void ScChiDist(bool bODFF)
double GetFDist(double x, double fF1, double fF2)
static double GetChiSqDistPDF(double fX, double fDF)
static double BinomKoeff(double n, double k)
double GetGammaDistPDF(double fX, double fAlpha, double fLambda)
Gamma distribution, probability density function.
double Fakultaet(double x)
void PushDouble(double nVal)
void ScQuartile(bool bInclusive)
void PopSingleRef(ScAddress &)
void ReverseStack(sal_uInt8 nParamCount)
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 GetHypGeomDist(double x, double n, double M, double N)
Calculates a value of the hypergeometric distribution.
double GetChiSqDistCDF(double fX, double fDF)
You must ensure fDF>0.0.
double GetMedian(::std::vector< double > &rArray)
void PopDoubleRef(ScRange &rRange, short &rParam, size_t &rRefInList)
If formula::StackVar formula::svDoubleRef pop ScDoubleRefToken and return values of ScComplexRefData.
double GetTDist(double T, double fDF, int nType)
double GetUpRegIGamma(double fA, double fX)
You must ensure fA>0.0 && fX>0.0)
void ScPercentile(bool bInclusive)
bool CalculateTest(bool _bTemplin, const SCSIZE nC1, const SCSIZE nC2, const SCSIZE nR1, const SCSIZE nR2, const ScMatrixRef &pMat1, const ScMatrixRef &pMat2, double &fT, double &fF)
void GetStVarParams(bool bTextAsZero, double(*VarResult)(double fVal, size_t nValCount))
void PushMatrix(const sc::RangeMatrix &rMat)
void GetNumberSequenceArray(sal_uInt8 nParamCount, ::std::vector< double > &rArray, bool bConvertTextInArray)
void ScGammaDist(bool bODFF)
void CalculateSlopeIntercept(bool bSlope)
static double phi(double x)
double GetPercentileExclusive(::std::vector< double > &rArray, double fPercentile)
static void QuickSort(::std::vector< double > &rSortArray, ::std::vector< tools::Long > *pIndexOrder)
double GetCellValue(const ScAddress &, ScRefCellValue &rCell)
static double GetLogGamma(double x)
You must ensure fZ>0.
void ScHypGeomDist(int nMinParamCount)
Calculates a value of the hypergeometric distribution.
void GetSortArray(sal_uInt8 nParamCount, ::std::vector< double > &rSortArray, ::std::vector< tools::Long > *pIndexOrder, bool bConvertTextInArray, bool bAllowEmptyArray)
double GetGammaDist(double fX, double fAlpha, double fLambda)
Gamma distribution, cumulative distribution function.
double GetBetaDist(double x, double alpha, double beta)
static double GetPercentile(::std::vector< double > &rArray, double fPercentile)
formula::StackVar GetStackType()
Stack type with replacement of defaults, e.g. svMissing and formula::svEmptyCell will result in formu...
static double GetPercentrank(::std::vector< double > &rArray, double fVal, bool bInclusive)
static double gaussinv(double x)
void ScPercentrank(bool bInclusive)
void ScPoissonDist(bool bODFF)
ScTDistFunction(ScInterpreter &rI, double fpVal, double fDFVal, int nType)
double GetValue(double x) const override
virtual ~ScTDistFunction()
bool GetFirst(double &rValue, FormulaError &rErr)
Does NOT reset rValue if no value found!
bool GetNext(double &rValue, FormulaError &rErr)
Does NOT reset rValue if no value found!
double CreateDoubleError(FormulaError nErr)
static void lcl_convertToPolar(std::vector< double > &rCmplxArray, double fMinMag)
static size_t MAX_COUNT_DOUBLE_FOR_SORT(const ScSheetLimits &rSheetLimits)
Two columns of data should be sortable with GetSortArray() and QuickSort()
static double lcl_IterateInverse(const ScDistFunc &rFunction, double fAx, double fBx, bool &rConvError)
static void lcl_PutFactorialElements(::std::vector< double > &cn, double fLower, double fUpper, double fBase)
Local function used in the calculation of the hypergeometric distribution.
static double lcl_GetLogGammaHelper(double fZ)
You must ensure fZ>0.
static double lcl_GetGammaHelper(double fZ)
You must ensure fZ>0; fZ>171.624376956302 will overflow.
ScMatrixRef(SCSIZE, SCSIZE, std::vector< double > &) ScMatrixGenerator
static void lcl_normalize(std::vector< double > &rCmplxArray, bool bScaleOnlyReal)
static double lcl_GetBetaHelperContFrac(double fX, double fA, double fB)
static void lcl_QuickSort(tools::Long nLo, tools::Long nHi, vector< double > &rSortArray, vector< tools::Long > *pIndexOrder)
static double lcl_GetBinomDistRange(double n, double xs, double xe, double fFactor, double p, double q)
static bool lcl_HasChangeOfSign(double u, double w)
u*w<0.0 fails for values near zero
static SCSIZE lcl_bitReverse(SCSIZE nIn, SCSIZE nBound)
static void lcl_roundUpNearestPow2(SCSIZE &nNum, SCSIZE &nNumBits)
static double lcl_getLanczosSum(double fZ)
you must ensure fZ>0 Uses a variant of the Lanczos sum with a rational function.
size_t uniform_size_distribution(size_t a, size_t b)
constexpr double alpha[nDetails]
void swap(cow_wrapper< T, P > &a, cow_wrapper< T, P > &b)
std::vector< kOp > kOpSumAndSumSquare
double divide(const double &fNumerator, const double &fDenominator)
Return fNumerator/fDenominator if fDenominator!=0 else +-Infinity if fNumerator!=0 or NaN if fNumerat...
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
std::vector< char * > values
This is very similar to ScCellValue, except that it references the original value instead of copying ...
SCROW GetMaxRowCount() const
::boost::intrusive_ptr< ScMatrix > ScMatrixRef