LibreOffice Module sc (master)  1
kahan.hxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  */
9 
10 #pragma once
11 
12 #include <cmath>
13 
21 class KahanSum
22 {
23 public:
24  constexpr KahanSum() = default;
25 
26  constexpr KahanSum(double x_0)
27  : m_fSum(x_0)
28  {
29  }
30 
31  constexpr KahanSum(const KahanSum& fSum) = default;
32 
33 public:
38  void add(double x_i)
39  {
40  double t = m_fSum + x_i;
41  if (std::abs(m_fSum) >= std::abs(x_i))
42  m_fError += (m_fSum - t) + x_i;
43  else
44  m_fError += (x_i - t) + m_fSum;
45  m_fSum = t;
46  }
47 
52  inline void add(const KahanSum& fSum)
53  {
54  add(fSum.m_fSum);
55  add(fSum.m_fError);
56  }
57 
62  inline void subtract(const KahanSum& fSum)
63  {
64  add(-fSum.m_fSum);
65  add(-fSum.m_fError);
66  }
67 
68 public:
69  constexpr KahanSum operator-() const
70  {
71  KahanSum fKahanSum;
72  fKahanSum.m_fSum = -m_fSum;
73  fKahanSum.m_fError = -m_fError;
74  return fKahanSum;
75  }
76 
77  constexpr KahanSum& operator=(double fSum)
78  {
79  m_fSum = fSum;
80  m_fError = 0;
81  return *this;
82  }
83 
84  constexpr KahanSum& operator=(const KahanSum& fSum) = default;
85 
86  inline void operator+=(const KahanSum& fSum) { add(fSum); }
87 
88  inline void operator+=(double fSum) { add(fSum); }
89 
90  inline void operator-=(const KahanSum& fSum) { subtract(fSum); }
91 
92  inline void operator-=(double fSum) { add(-fSum); }
93 
94  inline KahanSum operator+(double fSum) const
95  {
96  KahanSum fNSum(*this);
97  fNSum.add(fSum);
98  return fNSum;
99  }
100 
101  inline KahanSum operator+(const KahanSum& fSum) const
102  {
103  KahanSum fNSum(*this);
104  fNSum += fSum;
105  return fNSum;
106  }
107 
108  inline KahanSum operator-(double fSum) const
109  {
110  KahanSum fNSum(*this);
111  fNSum.add(-fSum);
112  return fNSum;
113  }
114 
115  inline KahanSum operator-(const KahanSum& fSum) const
116  {
117  KahanSum fNSum(*this);
118  fNSum -= fSum;
119  return fNSum;
120  }
121 
126  constexpr void operator*=(double fTimes)
127  {
128  m_fSum *= fTimes;
129  m_fError *= fTimes;
130  }
131 
132  constexpr void operator/=(double fDivides)
133  {
134  m_fSum /= fDivides;
135  m_fError /= fDivides;
136  }
137 
138  inline KahanSum operator*(const KahanSum& fTimes) const
139  {
140  return *this * fTimes.m_fSum + *this * fTimes.m_fError;
141  }
142 
143  constexpr KahanSum operator*(double fTimes) const
144  {
145  KahanSum fSum(*this);
146  fSum *= fTimes;
147  return fSum;
148  }
149 
150  inline KahanSum operator/(const KahanSum& fDivides) const { return *this / fDivides.get(); }
151 
152  constexpr KahanSum operator/(double fTimes) const
153  {
154  KahanSum fSum(*this);
155  fSum /= fTimes;
156  return fSum;
157  }
158 
159  constexpr bool operator<(const KahanSum& fSum) const { return get() < fSum.get(); }
160 
161  constexpr bool operator<(double fSum) const { return get() < fSum; }
162 
163  constexpr bool operator>(const KahanSum& fSum) const { return get() > fSum.get(); }
164 
165  constexpr bool operator>(double fSum) const { return get() > fSum; }
166 
167  constexpr bool operator<=(const KahanSum& fSum) const { return get() <= fSum.get(); }
168 
169  constexpr bool operator<=(double fSum) const { return get() <= fSum; }
170 
171  constexpr bool operator>=(const KahanSum& fSum) const { return get() >= fSum.get(); }
172 
173  constexpr bool operator>=(double fSum) const { return get() >= fSum; }
174 
175  constexpr bool operator==(const KahanSum& fSum) const
176  {
177  return fSum.m_fSum == m_fSum && fSum.m_fError == m_fError;
178  }
179 
180  constexpr bool operator!=(const KahanSum& fSum) const
181  {
182  return fSum.m_fSum != m_fSum || fSum.m_fError != m_fError;
183  }
184 
185 public:
190  constexpr double get() const { return m_fSum + m_fError; }
191 
192 private:
193  double m_fSum = 0;
194  double m_fError = 0;
195 };
196 
197 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
void add(double x_i)
Adds a value to the sum using Kahan summation.
Definition: kahan.hxx:38
void operator+=(double fSum)
Definition: kahan.hxx:88
constexpr bool operator<(const KahanSum &fSum) const
Definition: kahan.hxx:159
static o3tl::enumarray< DebugTime, double > fTimes
Definition: datastream.cxx:37
KahanSum operator*(const KahanSum &fTimes) const
Definition: kahan.hxx:138
constexpr KahanSum & operator=(double fSum)
Definition: kahan.hxx:77
KahanSum operator/(const KahanSum &fDivides) const
Definition: kahan.hxx:150
constexpr KahanSum operator-() const
Definition: kahan.hxx:69
KahanSum operator-(const KahanSum &fSum) const
Definition: kahan.hxx:115
constexpr void operator/=(double fDivides)
Definition: kahan.hxx:132
constexpr bool operator>=(double fSum) const
Definition: kahan.hxx:173
constexpr double get() const
Returns the final sum.
Definition: kahan.hxx:190
double m_fSum
Definition: kahan.hxx:193
constexpr KahanSum(double x_0)
Definition: kahan.hxx:26
This class provides LO with Kahan summation algorithm About this algorithm: https://en.wikipedia.org/wiki/Kahan_summation_algorithm For general purpose software we assume first order error is enough.
Definition: kahan.hxx:21
void subtract(const KahanSum &fSum)
Substracts a value to the sum using Kahan summation.
Definition: kahan.hxx:62
constexpr KahanSum operator/(double fTimes) const
Definition: kahan.hxx:152
void operator+=(const KahanSum &fSum)
Definition: kahan.hxx:86
KahanSum operator-(double fSum) const
Definition: kahan.hxx:108
void operator-=(const KahanSum &fSum)
Definition: kahan.hxx:90
constexpr bool operator>(const KahanSum &fSum) const
Definition: kahan.hxx:163
constexpr bool operator==(const KahanSum &fSum) const
Definition: kahan.hxx:175
constexpr KahanSum()=default
constexpr bool operator<=(const KahanSum &fSum) const
Definition: kahan.hxx:167
constexpr KahanSum operator*(double fTimes) const
Definition: kahan.hxx:143
KahanSum operator+(const KahanSum &fSum) const
Definition: kahan.hxx:101
void operator-=(double fSum)
Definition: kahan.hxx:92
constexpr void operator*=(double fTimes)
In some parts of the code of interpr_.cxx this may be used for product instead of sum...
Definition: kahan.hxx:126
XPropertyListType t
constexpr bool operator>=(const KahanSum &fSum) const
Definition: kahan.hxx:171
constexpr bool operator<(double fSum) const
Definition: kahan.hxx:161
constexpr bool operator>(double fSum) const
Definition: kahan.hxx:165
void add(const KahanSum &fSum)
Adds a value to the sum using Kahan summation.
Definition: kahan.hxx:52
constexpr bool operator<=(double fSum) const
Definition: kahan.hxx:169
constexpr bool operator!=(const KahanSum &fSum) const
Definition: kahan.hxx:180
KahanSum operator+(double fSum) const
Definition: kahan.hxx:94
double m_fError
Definition: kahan.hxx:194