sc/source/core/tool/interpr5.cxx |   50 +++++++++++++++++++--------------------
 1 file changed, 25 insertions(+), 25 deletions(-)

New commits:
commit 2b90807fd474cb4e26c80ba5407aca4b66f6d3a2
Author:     dante <dante19031...@gmail.com>
AuthorDate: Wed May 5 11:06:54 2021 +0200
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Fri May 7 00:22:18 2021 +0200

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

diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx
index 4f10bb8961d2..f7dd527780ea 100644
--- a/sc/source/core/tool/interpr5.cxx
+++ b/sc/source/core/tool/interpr5.cxx
@@ -90,15 +90,14 @@ struct MatrixPow
 void lcl_MFastMult(const ScMatrixRef& pA, const ScMatrixRef& pB, const 
ScMatrixRef& pR,
                    SCSIZE n, SCSIZE m, SCSIZE l)
 {
-    double sum;
     for (SCSIZE row = 0; row < n; row++)
     {
         for (SCSIZE col = 0; col < l; col++)
         {   // result element(col, row) =sum[ (row of A) * (column of B)]
-            sum = 0.0;
+            KahanSum fSum = 0.0;
             for (SCSIZE k = 0; k < m; k++)
-                sum += pA->GetDouble(k,row) * pB->GetDouble(col,k);
-            pR->PutDouble(sum, col, row);
+                fSum += pA->GetDouble(k,row) * pB->GetDouble(col,k);
+            pR->PutDouble(fSum.get(), col, row);
         }
     }
 }
@@ -886,7 +885,7 @@ static void lcl_LUP_solve( const ScMatrix* mLU, const 
SCSIZE n,
     // Define y=Ux and solve for y in Ly=Pb using forward substitution.
     for (SCSIZE i=0; i < n; ++i)
     {
-        double fSum = B[P[i]];
+        KahanSum fSum = B[P[i]];
         // Matrix inversion comes with a lot of zeros in the B vectors, we
         // don't have to do all the computing with results multiplied by zero.
         // Until then, simply lookout for the position of the first nonzero
@@ -894,19 +893,19 @@ static void lcl_LUP_solve( const ScMatrix* mLU, const 
SCSIZE n,
         if (nFirst != SCSIZE_MAX)
         {
             for (SCSIZE j = nFirst; j < i; ++j)
-                fSum -= mLU->GetDouble( j, i) * X[j];   // X[j] === y[j]
+                fSum -= mLU->GetDouble( j, i) * X[j];         // X[j] === y[j]
         }
-        else if (fSum)
+        else if (fSum != 0)
             nFirst = i;
-        X[i] = fSum;                                    // X[i] === y[i]
+        X[i] = fSum.get();                                    // X[i] === y[i]
     }
     // Solve for x in Ux=y using back substitution.
     for (SCSIZE i = n; i--; )
     {
-        double fSum = X[i];                             // X[i] === y[i]
+        KahanSum fSum = X[i];                                 // X[i] === y[i]
         for (SCSIZE j = i+1; j < n; ++j)
-            fSum -= mLU->GetDouble( j, i) * X[j];       // X[j] === x[j]
-        X[i] = fSum / mLU->GetDouble( i, i);            // X[i] === x[i]
+            fSum -= mLU->GetDouble( j, i) * X[j];             // X[j] === x[j]
+        X[i] = fSum.get() / mLU->GetDouble( i, i);            // X[i] === x[i]
     }
 #ifdef DEBUG_SC_LUP_DECOMPOSITION
     fprintf( stderr, "\n%s\n", "lcl_LUP_solve():");
@@ -1098,17 +1097,17 @@ void ScInterpreter::ScMatMult()
                 pRMat = GetNewMat(nC2, nR1, /*bEmpty*/true);
                 if (pRMat)
                 {
-                    double sum;
+                    KahanSum fSum;
                     for (SCSIZE i = 0; i < nR1; i++)
                     {
                         for (SCSIZE j = 0; j < nC2; j++)
                         {
-                            sum = 0.0;
+                            fSum = 0.0;
                             for (SCSIZE k = 0; k < nC1; k++)
                             {
-                                sum += 
pMat1->GetDouble(k,i)*pMat2->GetDouble(j,k);
+                                fSum += 
pMat1->GetDouble(k,i)*pMat2->GetDouble(j,k);
                             }
-                            pRMat->PutDouble(sum, j, i);
+                            pRMat->PutDouble(fSum.get(), j, i);
                         }
                     }
                     PushMatrix(pRMat);
@@ -1804,7 +1803,8 @@ void ScInterpreter::CalculateSumX2MY2SumX2DY2(bool 
_bSumX2DY2)
         PushNoValue();
         return;
     }
-    double fVal, fSum = 0.0;
+    double fVal;
+    KahanSum fSum = 0.0;
     for (i = 0; i < nC1; i++)
         for (j = 0; j < nR1; j++)
             if (!pMat1->IsStringOrEmpty(i,j) && !pMat2->IsStringOrEmpty(i,j))
@@ -1817,7 +1817,7 @@ void ScInterpreter::CalculateSumX2MY2SumX2DY2(bool 
_bSumX2DY2)
                 else
                     fSum -= fVal * fVal;
             }
-    PushDouble(fSum);
+    PushDouble(fSum.get());
 }
 
 void ScInterpreter::ScSumX2DY2()
@@ -2701,7 +2701,7 @@ void ScInterpreter::CalculateRGPRKP(bool _bRKP)
                     // = RMSE * sqrt( Xmean * (R' R)^(-1) * Xmean' + 1/N)
                     // (R' R)^(-1) = R^(-1) * (R')^(-1). Do not calculate it as
                     // a whole matrix, but iterate over unit vectors.
-                    double fSigmaIntercept = 0.0;
+                    KahanSum aSigmaIntercept = 0.0;
                     double fPart; // for Xmean * single column of (R' R)^(-1)
                     for (SCSIZE col = 0; col < K; col++)
                     {
@@ -2719,13 +2719,13 @@ void ScInterpreter::CalculateRGPRKP(bool _bRKP)
                         if (bConstant)
                         {
                             fPart = lcl_GetSumProduct(pMeans, pMatZ, K);
-                            fSigmaIntercept += fPart * pMeans->GetDouble(col);
+                            aSigmaIntercept += fPart * pMeans->GetDouble(col);
                         }
                     }
                     if (bConstant)
                     {
-                        fSigmaIntercept = fRMSE
-                                          * sqrt(fSigmaIntercept + 1.0 / 
static_cast<double>(N));
+                        double fSigmaIntercept = fRMSE
+                                          * sqrt( (aSigmaIntercept + 1.0 / 
static_cast<double>(N) ).get() );
                         pResMat->PutDouble(fSigmaIntercept, K, 1);
                     }
                     else
@@ -2859,7 +2859,7 @@ void ScInterpreter::CalculateRGPRKP(bool _bRKP)
                     // (R' R)^(-1) = R^(-1) * (R')^(-1). Do not calculate it as
                     // a whole matrix, but iterate over unit vectors.
                     // (R' R) ^(-1) is symmetric
-                    double fSigmaIntercept = 0.0;
+                    KahanSum aSigmaIntercept = 0.0;
                     double fPart; // for Xmean * single col of (R' R)^(-1)
                     for (SCSIZE row = 0; row < K; row++)
                     {
@@ -2876,13 +2876,13 @@ void ScInterpreter::CalculateRGPRKP(bool _bRKP)
                         if (bConstant)
                         {
                             fPart = lcl_GetSumProduct(pMeans, pMatZ, K);
-                            fSigmaIntercept += fPart * pMeans->GetDouble(row);
+                            aSigmaIntercept += fPart * pMeans->GetDouble(row);
                         }
                     }
                     if (bConstant)
                     {
-                        fSigmaIntercept = fRMSE
-                                          * sqrt(fSigmaIntercept + 1.0 / 
static_cast<double>(N));
+                        double fSigmaIntercept = fRMSE
+                                          * sqrt( (aSigmaIntercept + 1.0 / 
static_cast<double>(N) ).get() );
                         pResMat->PutDouble(fSigmaIntercept, K, 1);
                     }
                     else
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to