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

dante (via logerrit) logerrit at kemper.freedesktop.org
Tue May 4 18:35:11 UTC 2021


 sc/inc/kahan.hxx                 |   40 ++++++++++++++++++++++++++++++++++++++-
 sc/source/core/tool/interpr3.cxx |   26 ++++++++++++++-----------
 2 files changed, 54 insertions(+), 12 deletions(-)

New commits:
commit 94977bb43d8dc91023bee7afa037f6319c36ccc3
Author:     dante <dante19031999 at gmail.com>
AuthorDate: Sat May 1 11:04:21 2021 +0200
Commit:     Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Tue May 4 20:34:11 2021 +0200

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

diff --git a/sc/inc/kahan.hxx b/sc/inc/kahan.hxx
index ffeeab0867df..23a29f6ee13f 100644
--- a/sc/inc/kahan.hxx
+++ b/sc/inc/kahan.hxx
@@ -53,6 +53,16 @@ public:
         add(fSum.m_fError);
     }
 
+    /**
+      * Substracts a value to the sum using Kahan summation.
+      * @param fSum
+      */
+    inline void subtract(const KahanSum& fSum)
+    {
+        add(-fSum.m_fSum);
+        add(-fSum.m_fError);
+    }
+
 public:
     constexpr KahanSum operator-() const
     {
@@ -75,7 +85,7 @@ public:
 
     inline void operator+=(double fSum) { add(fSum); }
 
-    inline void operator-=(const KahanSum& fSum) { add(-fSum); }
+    inline void operator-=(const KahanSum& fSum) { subtract(fSum); }
 
     inline void operator-=(double fSum) { add(-fSum); }
 
@@ -86,6 +96,13 @@ public:
         return fNSum;
     }
 
+    inline KahanSum operator+(const KahanSum& fSum) const
+    {
+        KahanSum fNSum(*this);
+        fNSum += fSum;
+        return fNSum;
+    }
+
     inline KahanSum operator-(double fSum) const
     {
         KahanSum fNSum(*this);
@@ -93,6 +110,13 @@ public:
         return fNSum;
     }
 
+    inline KahanSum operator-(const KahanSum& fSum) const
+    {
+        KahanSum fNSum(*this);
+        fNSum -= fSum;
+        return fNSum;
+    }
+
     /**
       * In some parts of the code of interpr_.cxx this may be used for
       * product instead of sum. This operator shall be used for that task.
@@ -109,6 +133,20 @@ public:
         m_fError /= fDivides;
     }
 
+    constexpr KahanSum operator*(double fTimes) const
+    {
+        KahanSum fSum(*this);
+        fSum *= fTimes;
+        return fSum;
+    }
+
+    constexpr KahanSum operator/(double fTimes) const
+    {
+        KahanSum fSum(*this);
+        fSum /= fTimes;
+        return fSum;
+    }
+
     constexpr bool operator<(const KahanSum& fSum) const { return get() < fSum.get(); }
 
     constexpr bool operator<(double fSum) const { return get() < fSum; }
diff --git a/sc/source/core/tool/interpr3.cxx b/sc/source/core/tool/interpr3.cxx
index 17fe63381362..c339a68dd80f 100644
--- a/sc/source/core/tool/interpr3.cxx
+++ b/sc/source/core/tool/interpr3.cxx
@@ -84,32 +84,36 @@ static double lcl_IterateInverse( const ScDistFunc& rFunction, double fAx, doubl
 
     //  find enclosing interval
 
+    KahanSum fkAx = fAx;
+    KahanSum fkBx = fBx;
     double fAy = rFunction.GetValue(fAx);
     double fBy = rFunction.GetValue(fBx);
-    double fTemp;
+    KahanSum fTemp;
     unsigned short nCount;
     for (nCount = 0; nCount < 1000 && !lcl_HasChangeOfSign(fAy,fBy); nCount++)
     {
         if (std::abs(fAy) <= std::abs(fBy))
         {
-            fTemp = fAx;
-            fAx += 2.0 * (fAx - fBx);
-            if (fAx < 0.0)
-                fAx = 0.0;
-            fBx = fTemp;
+            fTemp = fkAx;
+            fkAx += (fkAx - fkBx) * 2.0;
+            if (fkAx < 0.0)
+                fkAx = 0.0;
+            fkBx = fTemp;
             fBy = fAy;
-            fAy = rFunction.GetValue(fAx);
+            fAy = rFunction.GetValue(fkAx.get());
         }
         else
         {
-            fTemp = fBx;
-            fBx += 2.0 * (fBx - fAx);
-            fAx = fTemp;
+            fTemp = fkBx;
+            fkBx += (fkBx - fkAx) * 2.0;
+            fkAx = fTemp;
             fAy = fBy;
-            fBy = rFunction.GetValue(fBx);
+            fBy = rFunction.GetValue(fkBx.get());
         }
     }
 
+    fAx = fkAx.get();
+    fBx = fkBx.get();
     if (fAy == 0.0)
         return fAx;
     if (fBy == 0.0)


More information about the Libreoffice-commits mailing list