sc/qa/unit/data/functions/statistical/fods/forecast.ets.mult.fods |   22 +--
 sc/source/core/tool/interpr8.cxx                                  |   56 
+++++-----
 2 files changed, 41 insertions(+), 37 deletions(-)

New commits:
commit 38c88aca77f8c8ef47470723557ddf9e5d9d7b66
Author:     dante <dante19031...@gmail.com>
AuthorDate: Wed May 5 10:57:14 2021 +0200
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Fri May 7 14:29:39 2021 +0200

    tdf#137679 Use Kahan summation for interpr8.cxx
    
    Change-Id: Id43765f7d8f51066da4bbebcfc175a0e69a58fde
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115127
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/sc/qa/unit/data/functions/statistical/fods/forecast.ets.mult.fods 
b/sc/qa/unit/data/functions/statistical/fods/forecast.ets.mult.fods
index 0c45eb46cd8c..150ec6b68115 100644
--- a/sc/qa/unit/data/functions/statistical/fods/forecast.ets.mult.fods
+++ b/sc/qa/unit/data/functions/statistical/fods/forecast.ets.mult.fods
@@ -8555,10 +8555,10 @@
      </table:table-cell>
     </table:table-row>
     <table:table-row table:style-name="ro7">
-     <table:table-cell office:value-type="float" 
office:value="190.641123921524" calcext:value-type="float">
-      <text:p>190.641123921524</text:p>
+     <table:table-cell office:value-type="float" 
office:value="190.641123921525" calcext:value-type="float">
+      <text:p>190.641123921525</text:p>
      </table:table-cell>
-     <table:table-cell table:style-name="ce14" office:value-type="float" 
office:value="190.641123921524" calcext:value-type="float">
+     <table:table-cell table:style-name="ce14" office:value-type="float" 
office:value="190.641123921525" calcext:value-type="float">
       <text:p>190.641124</text:p>
      </table:table-cell>
      <table:table-cell table:style-name="ce16" 
table:formula="of:=ROUND([.A64];12)=ROUND([.B64];12)" 
office:value-type="boolean" office:boolean-value="true" 
calcext:value-type="boolean">
@@ -9014,11 +9014,11 @@
      </table:table-cell>
     </table:table-row>
     <table:table-row table:style-name="ro7">
-     <table:table-cell office:value-type="float" 
office:value="268.59802115122" calcext:value-type="float">
-      <text:p>268.59802115122</text:p>
+     <table:table-cell office:value-type="float" 
office:value="268.598021151221" calcext:value-type="float">
+      <text:p>268.598021151221</text:p>
      </table:table-cell>
-     <table:table-cell office:value-type="float" 
office:value="268.59802115122" calcext:value-type="float">
-      <text:p>268.59802115122</text:p>
+     <table:table-cell office:value-type="float" 
office:value="268.598021151221" calcext:value-type="float">
+      <text:p>268.598021151221</text:p>
      </table:table-cell>
      <table:table-cell table:style-name="ce16" 
table:formula="of:=ROUND([.A79];12)=ROUND([.B79];12)" 
office:value-type="boolean" office:boolean-value="true" 
calcext:value-type="boolean">
       <text:p>TRUE</text:p>
@@ -9196,11 +9196,11 @@
      </table:table-cell>
     </table:table-row>
     <table:table-row table:style-name="ro7">
-     <table:table-cell office:value-type="float" 
office:value="267.531016699979" calcext:value-type="float">
-      <text:p>267.531016699979</text:p>
+     <table:table-cell office:value-type="float" 
office:value="267.531016699980" calcext:value-type="float">
+      <text:p>267.531016699980</text:p>
      </table:table-cell>
-     <table:table-cell office:value-type="float" 
office:value="267.531016699979" calcext:value-type="float">
-      <text:p>267.531016699979</text:p>
+     <table:table-cell office:value-type="float" 
office:value="267.531016699980" calcext:value-type="float">
+      <text:p>267.531016699980</text:p>
      </table:table-cell>
      <table:table-cell table:style-name="ce16" 
table:formula="of:=ROUND([.A86];12)=ROUND([.B86];12)" 
office:value-type="boolean" office:boolean-value="true" 
calcext:value-type="boolean">
       <text:p>TRUE</text:p>
diff --git a/sc/source/core/tool/interpr8.cxx b/sc/source/core/tool/interpr8.cxx
index 750b42572706..64bb3d1d8a8e 100644
--- a/sc/source/core/tool/interpr8.cxx
+++ b/sc/source/core/tool/interpr8.cxx
@@ -353,9 +353,9 @@ bool ScETSForecastCalculation::PreprocessDataRange( const 
ScMatrixRef& rMatX, co
             {
                 // gap, insert missing data points
                 double fYGap = ( maRange[ i ].Y + maRange[ i - 1 ].Y ) / 2.0;
-                for ( double fXGap = maRange[ i - 1].X + mfStepSize;  fXGap < 
maRange[ i ].X; fXGap += mfStepSize )
+                for ( KahanSum fXGap = maRange[ i - 1].X + mfStepSize;  fXGap 
< maRange[ i ].X; fXGap += mfStepSize )
                 {
-                    maRange.insert( maRange.begin() + i, DataPoint( fXGap, ( 
bDataCompletion ? fYGap : 0.0 ) ) );
+                    maRange.insert( maRange.begin() + i, DataPoint( 
fXGap.get(), ( bDataCompletion ? fYGap : 0.0 ) ) );
                     i++;
                     mnCount++;
                     nMissingXCount++;
@@ -419,10 +419,13 @@ bool ScETSForecastCalculation::prefillTrendData()
             return false;
         }
 
-        double fSum = 0.0;
+        KahanSum fSum = 0.0;
         for ( SCSIZE i = 0; i < mnSmplInPrd; i++ )
-            fSum += maRange[ i + mnSmplInPrd ].Y - maRange[ i ].Y;
-        double fTrend = fSum / static_cast< double >( mnSmplInPrd * 
mnSmplInPrd );
+        {
+            fSum += maRange[ i + mnSmplInPrd ].Y;
+            fSum -= maRange[ i ].Y;
+        }
+        double fTrend = fSum.get() / static_cast< double >( mnSmplInPrd * 
mnSmplInPrd );
 
         mpTrend[ 0 ] = fTrend;
     }
@@ -442,7 +445,7 @@ bool ScETSForecastCalculation::prefillPerIdx()
             return false;
         }
         SCSIZE nPeriods = mnCount / mnSmplInPrd;
-        std::vector< double > aPeriodAverage( nPeriods, 0.0 );
+        std::vector< KahanSum > aPeriodAverage( nPeriods, 0.0 );
         for ( SCSIZE i = 0; i < nPeriods ; i++ )
         {
             for ( SCSIZE j = 0; j < mnSmplInPrd; j++ )
@@ -458,20 +461,20 @@ bool ScETSForecastCalculation::prefillPerIdx()
 
         for ( SCSIZE j = 0; j < mnSmplInPrd; j++ )
         {
-            double fI = 0.0;
+            KahanSum fI = 0.0;
             for ( SCSIZE i = 0; i < nPeriods ; i++ )
             {
                 // adjust average value for position within period
                 if ( bAdditive )
-                    fI += ( maRange[ i * mnSmplInPrd + j ].Y -
-                            ( aPeriodAverage[ i ] + ( static_cast< double >( j 
) - 0.5 * ( mnSmplInPrd - 1 ) ) *
-                              mpTrend[ 0 ] ) );
+                    fI +=   maRange[ i * mnSmplInPrd + j ].Y -
+                            ( aPeriodAverage[ i ].get() + ( static_cast< 
double >( j ) - 0.5 * ( mnSmplInPrd - 1 ) ) *
+                              mpTrend[ 0 ] );
                 else
-                    fI += ( maRange[ i * mnSmplInPrd + j ].Y /
-                            ( aPeriodAverage[ i ] + ( static_cast< double >( j 
) - 0.5 * ( mnSmplInPrd - 1 ) ) *
-                              mpTrend[ 0 ] ) );
+                    fI +=   maRange[ i * mnSmplInPrd + j ].Y /
+                            ( aPeriodAverage[ i ].get() + ( static_cast< 
double >( j ) - 0.5 * ( mnSmplInPrd - 1 ) ) *
+                              mpTrend[ 0 ] );
             }
-            mpPerIdx[ j ] = fI / nPeriods;
+            mpPerIdx[ j ] = fI.get() / nPeriods;
         }
         if (mnSmplInPrd < mnCount)
             mpPerIdx[mnSmplInPrd] = 0.0;
@@ -500,10 +503,10 @@ void ScETSForecastCalculation::initCalc()
 
 void ScETSForecastCalculation::calcAccuracyIndicators()
 {
-    double fSumAbsErr     = 0.0;
-    double fSumDivisor    = 0.0;
-    double fSumErrSq      = 0.0;
-    double fSumAbsPercErr = 0.0;
+    KahanSum fSumAbsErr     = 0.0;
+    KahanSum fSumDivisor    = 0.0;
+    KahanSum fSumErrSq      = 0.0;
+    KahanSum fSumAbsPercErr = 0.0;
 
     for ( SCSIZE i = 1; i < mnCount; i++ )
     {
@@ -517,11 +520,11 @@ void ScETSForecastCalculation::calcAccuracyIndicators()
         fSumDivisor += fabs( maRange[ i ].Y - maRange[ i - 1 ].Y );
 
     int nCalcCount = mnCount - 1;
-    mfMAE   = fSumAbsErr / nCalcCount;
-    mfMASE  = fSumAbsErr / ( nCalcCount * fSumDivisor / ( nCalcCount - 1 ) );
-    mfMSE   = fSumErrSq / nCalcCount;
+    mfMAE   = fSumAbsErr.get() / nCalcCount;
+    mfMASE  = fSumAbsErr.get() / ( nCalcCount * fSumDivisor.get() / ( 
nCalcCount - 1 ) );
+    mfMSE   = fSumErrSq.get() / nCalcCount;
     mfRMSE  = sqrt( mfMSE );
-    mfSMAPE = fSumAbsPercErr * 2.0 / nCalcCount;
+    mfSMAPE = fSumAbsPercErr.get() * 2.0 / nCalcCount;
 }
 
 /*
@@ -539,7 +542,7 @@ SCSIZE ScETSForecastCalculation::CalcPeriodLen()
 
     for ( SCSIZE nPeriodLen = mnCount / 2; nPeriodLen >= 1; nPeriodLen-- )
     {
-        double fMeanError = 0.0;
+        KahanSum fMeanError = 0.0;
         SCSIZE nPeriods = mnCount / nPeriodLen;
         SCSIZE nStart = mnCount - ( nPeriods * nPeriodLen ) + 1;
         for ( SCSIZE i = nStart; i < ( mnCount - nPeriodLen ); i++ )
@@ -547,12 +550,13 @@ SCSIZE ScETSForecastCalculation::CalcPeriodLen()
             fMeanError += fabs( ( maRange[ i ].Y - maRange[ i - 1 ].Y ) -
                                 ( maRange[ nPeriodLen + i ].Y - maRange[ 
nPeriodLen + i - 1 ].Y ) );
         }
-        fMeanError /= static_cast< double >( ( nPeriods - 1 ) * nPeriodLen - 1 
);
+        double fMeanErrorGet = fMeanError.get();
+        fMeanErrorGet /= static_cast< double >( ( nPeriods - 1 ) * nPeriodLen 
- 1 );
 
-        if ( fMeanError <= fBestME || fMeanError == 0.0 )
+        if ( fMeanErrorGet <= fBestME || fMeanErrorGet == 0.0 )
         {
             nBestVal = nPeriodLen;
-            fBestME = fMeanError;
+            fBestME = fMeanErrorGet;
         }
     }
     return nBestVal;
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to