[Libreoffice-commits] core.git: sc/source

dante (via logerrit) logerrit at kemper.freedesktop.org
Fri Apr 30 21:30:39 UTC 2021


 sc/source/core/inc/interpre.hxx  |    2 -
 sc/source/core/tool/interpr3.cxx |   41 +++++++++++++++++++--------------------
 2 files changed, 21 insertions(+), 22 deletions(-)

New commits:
commit 4283fb9d4a6152643364bfe1f98ee1f36aabbb78
Author:     dante <dante19031999 at gmail.com>
AuthorDate: Wed Apr 28 19:37:21 2021 +0200
Commit:     Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Fri Apr 30 23:29:59 2021 +0200

    tdf#137679 Use kahan summation for ScInterpreter::CalculateSkew
    
    Change-Id: Ib9e34fd14d9968a5a8c79805da4f12d9a3422de8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114818
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>

diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index bdde25a12c24..c7b93798bc58 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -835,7 +835,7 @@ private:
     void ScSumX2DY2();
     void ScSumXMY2();
     void ScGrowth();
-    bool CalculateSkew(double& fSum,double& fCount,double& vSum,std::vector<double>& values);
+    bool CalculateSkew(KahanSum& fSum, double& fCount, std::vector<double>& values);
     void CalculateSkewOrSkewp( bool bSkewp );
     void CalculateSlopeIntercept(bool bSlope);
     void CalculateSmallLarge(bool bSmall);
diff --git a/sc/source/core/tool/interpr3.cxx b/sc/source/core/tool/interpr3.cxx
index 7adee328c37a..d41f4f98b475 100644
--- a/sc/source/core/tool/interpr3.cxx
+++ b/sc/source/core/tool/interpr3.cxx
@@ -2872,9 +2872,10 @@ void ScInterpreter::ScChiTest()
 
 void ScInterpreter::ScKurt()
 {
-    double fSum,fCount,vSum;
+    KahanSum fSum;
+    double fCount;
     std::vector<double> values;
-    if ( !CalculateSkew(fSum,fCount,vSum,values) )
+    if ( !CalculateSkew(fSum, fCount, values) )
         return;
 
     // ODF 1.2 constraints: # of numbers >= 4
@@ -2885,31 +2886,30 @@ void ScInterpreter::ScKurt()
         return;
     }
 
-    double fMean = fSum / fCount;
-
+    KahanSum vSum;
+    double fMean = fSum.get() / fCount;
     for (double v : values)
         vSum += (v - fMean) * (v - fMean);
 
-    double fStdDev = sqrt(vSum / (fCount - 1.0));
-    double xpower4 = 0.0;
-
+    double fStdDev = sqrt(vSum.get() / (fCount - 1.0));
     if (fStdDev == 0.0)
     {
         PushError( FormulaError::DivisionByZero);
         return;
     }
 
+    KahanSum xpower4 = 0.0;
     for (double v : values)
     {
         double dx = (v - fMean) / fStdDev;
-        xpower4 = xpower4 + (dx * dx * dx * dx);
+        xpower4 += (dx * dx) * (dx * dx);
     }
 
     double k_d = (fCount - 2.0) * (fCount - 3.0);
     double k_l = fCount * (fCount + 1.0) / ((fCount - 1.0) * k_d);
     double k_t = 3.0 * (fCount - 1.0) * (fCount - 1.0) / k_d;
 
-    PushDouble(xpower4 * k_l - k_t);
+    PushDouble(xpower4.get() * k_l - k_t);
 }
 
 void ScInterpreter::ScHarMean()
@@ -3220,7 +3220,7 @@ void ScInterpreter::ScStandard()
             PushDouble((x-mue)/sigma);
     }
 }
-bool ScInterpreter::CalculateSkew(double& fSum,double& fCount,double& vSum,std::vector<double>& values)
+bool ScInterpreter::CalculateSkew(KahanSum& fSum, double& fCount, std::vector<double>& values)
 {
     short nParamCount = GetByte();
     if ( !MustHaveParamCountMin( nParamCount, 1 )  )
@@ -3228,7 +3228,6 @@ bool ScInterpreter::CalculateSkew(double& fSum,double& fCount,double& vSum,std::
 
     fSum   = 0.0;
     fCount = 0.0;
-    vSum   = 0.0;
     double fVal = 0.0;
     ScAddress aAdr;
     ScRange aRange;
@@ -3328,9 +3327,10 @@ bool ScInterpreter::CalculateSkew(double& fSum,double& fCount,double& vSum,std::
 
 void ScInterpreter::CalculateSkewOrSkewp( bool bSkewp )
 {
-    double fSum, fCount, vSum;
+    KahanSum fSum;
+    double fCount;
     std::vector<double> values;
-    if (!CalculateSkew( fSum, fCount, vSum, values))
+    if (!CalculateSkew( fSum, fCount, values))
         return;
      // SKEW/SKEWP's constraints: they require at least three numbers
     if (fCount < 3.0)
@@ -3340,30 +3340,29 @@ void ScInterpreter::CalculateSkewOrSkewp( bool bSkewp )
         return;
     }
 
-    double fMean = fSum / fCount;
-
+    KahanSum vSum;
+    double fMean = fSum.get() / fCount;
     for (double v : values)
         vSum += (v - fMean) * (v - fMean);
 
-    double fStdDev = sqrt( vSum / (bSkewp ? fCount : (fCount - 1.0)));
-    double xcube = 0.0;
-
+    double fStdDev = sqrt( vSum.get() / (bSkewp ? fCount : (fCount - 1.0)));
     if (fStdDev == 0)
     {
         PushIllegalArgument();
         return;
     }
 
+    KahanSum xcube = 0.0;
     for (double v : values)
     {
         double dx = (v - fMean) / fStdDev;
-        xcube = xcube + (dx * dx * dx);
+        xcube += dx * dx * dx;
     }
 
     if (bSkewp)
-        PushDouble( xcube / fCount );
+        PushDouble( xcube.get() / fCount );
     else
-        PushDouble( ((xcube * fCount) / (fCount - 1.0)) / (fCount - 2.0) );
+        PushDouble( ((xcube.get() * fCount) / (fCount - 1.0)) / (fCount - 2.0) );
 }
 
 void ScInterpreter::ScSkew()


More information about the Libreoffice-commits mailing list