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 
15 
23 class KahanSum
24 {
25 public:
26  constexpr KahanSum() = default;
27 
28  constexpr KahanSum(double x_0)
29  : m_fSum(x_0)
30  {
31  }
32 
33  constexpr KahanSum(double x_0, double err_0)
34  : m_fSum(x_0)
35  , m_fError(err_0)
36  {
37  }
38 
39  constexpr KahanSum(const sc::op::KahanSumSimple& sum)
40  : m_fSum(sum.m_fSum)
41  , m_fError(sum.m_fError)
42  {
43  }
44 
45  constexpr KahanSum(const KahanSum& fSum) = default;
46 
47 public:
52  void add(double x_i)
53  {
54  double t = m_fSum + x_i;
55  if (std::abs(m_fSum) >= std::abs(x_i))
56  m_fError += (m_fSum - t) + x_i;
57  else
58  m_fError += (x_i - t) + m_fSum;
59  m_fSum = t;
60  }
61 
66  inline void add(const KahanSum& fSum)
67  {
68  add(fSum.m_fSum);
69  add(fSum.m_fError);
70  }
71 
76  inline void subtract(const KahanSum& fSum)
77  {
78  add(-fSum.m_fSum);
79  add(-fSum.m_fError);
80  }
81 
82 public:
83  constexpr KahanSum operator-() const
84  {
85  KahanSum fKahanSum;
86  fKahanSum.m_fSum = -m_fSum;
87  fKahanSum.m_fError = -m_fError;
88  return fKahanSum;
89  }
90 
91  constexpr KahanSum& operator=(double fSum)
92  {
93  m_fSum = fSum;
94  m_fError = 0;
95  return *this;
96  }
97 
98  constexpr KahanSum& operator=(const KahanSum& fSum) = default;
99 
100  inline void operator+=(const KahanSum& fSum) { add(fSum); }
101 
102  inline void operator+=(double fSum) { add(fSum); }
103 
104  inline void operator-=(const KahanSum& fSum) { subtract(fSum); }
105 
106  inline void operator-=(double fSum) { add(-fSum); }
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 
122  inline KahanSum operator-(double fSum) const
123  {
124  KahanSum fNSum(*this);
125  fNSum.add(-fSum);
126  return fNSum;
127  }
128 
129  inline KahanSum operator-(const KahanSum& fSum) const
130  {
131  KahanSum fNSum(*this);
132  fNSum -= fSum;
133  return fNSum;
134  }
135 
140  constexpr void operator*=(double fTimes)
141  {
142  m_fSum *= fTimes;
143  m_fError *= fTimes;
144  }
145 
146  constexpr void operator/=(double fDivides)
147  {
148  m_fSum /= fDivides;
149  m_fError /= fDivides;
150  }
151 
152  inline KahanSum operator*(const KahanSum& fTimes) const
153  {
154  return *this * fTimes.m_fSum + *this * fTimes.m_fError;
155  }
156 
157  constexpr KahanSum operator*(double fTimes) const
158  {
159  KahanSum fSum(*this);
160  fSum *= fTimes;
161  return fSum;
162  }
163 
164  inline KahanSum operator/(const KahanSum& fDivides) const { return *this / fDivides.get(); }
165 
166  constexpr KahanSum operator/(double fTimes) const
167  {
168  KahanSum fSum(*this);
169  fSum /= fTimes;
170  return fSum;
171  }
172 
173  constexpr bool operator<(const KahanSum& fSum) const { return get() < fSum.get(); }
174 
175  constexpr bool operator<(double fSum) const { return get() < fSum; }
176 
177  constexpr bool operator>(const KahanSum& fSum) const { return get() > fSum.get(); }
178 
179  constexpr bool operator>(double fSum) const { return get() > fSum; }
180 
181  constexpr bool operator<=(const KahanSum& fSum) const { return get() <= fSum.get(); }
182 
183  constexpr bool operator<=(double fSum) const { return get() <= fSum; }
184 
185  constexpr bool operator>=(const KahanSum& fSum) const { return get() >= fSum.get(); }
186 
187  constexpr bool operator>=(double fSum) const { return get() >= fSum; }
188 
189  constexpr bool operator==(const KahanSum& fSum) const
190  {
191  return fSum.m_fSum == m_fSum && fSum.m_fError == m_fError;
192  }
193 
194  constexpr bool operator!=(const KahanSum& fSum) const
195  {
196  return fSum.m_fSum != m_fSum || fSum.m_fError != m_fError;
197  }
198 
199  constexpr double* getSum() { return &m_fSum; }
200  constexpr double* getError() { return &m_fError; }
201 
202 public:
207  constexpr double get() const { return m_fSum + m_fError; }
208 
209 private:
210  double m_fSum = 0;
211  double m_fError = 0;
212 };
213 
214 /* 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:52
void operator+=(double fSum)
Definition: kahan.hxx:102
constexpr bool operator<(const KahanSum &fSum) const
Definition: kahan.hxx:173
constexpr KahanSum(const sc::op::KahanSumSimple &sum)
Definition: kahan.hxx:39
constexpr KahanSum(double x_0, double err_0)
Definition: kahan.hxx:33
static o3tl::enumarray< DebugTime, double > fTimes
Definition: datastream.cxx:37
KahanSum operator*(const KahanSum &fTimes) const
Definition: kahan.hxx:152
constexpr KahanSum & operator=(double fSum)
Definition: kahan.hxx:91
KahanSum operator/(const KahanSum &fDivides) const
Definition: kahan.hxx:164
constexpr KahanSum operator-() const
Definition: kahan.hxx:83
KahanSum operator-(const KahanSum &fSum) const
Definition: kahan.hxx:129
constexpr void operator/=(double fDivides)
Definition: kahan.hxx:146
constexpr bool operator>=(double fSum) const
Definition: kahan.hxx:187
constexpr double get() const
Returns the final sum.
Definition: kahan.hxx:207
double m_fSum
Definition: kahan.hxx:210
constexpr KahanSum(double x_0)
Definition: kahan.hxx:28
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:23
void subtract(const KahanSum &fSum)
Substracts a value to the sum using Kahan summation.
Definition: kahan.hxx:76
constexpr KahanSum operator/(double fTimes) const
Definition: kahan.hxx:166
void operator+=(const KahanSum &fSum)
Definition: kahan.hxx:100
KahanSum operator-(double fSum) const
Definition: kahan.hxx:122
constexpr double * getError()
Definition: kahan.hxx:200
void operator-=(const KahanSum &fSum)
Definition: kahan.hxx:104
constexpr bool operator>(const KahanSum &fSum) const
Definition: kahan.hxx:177
constexpr bool operator==(const KahanSum &fSum) const
Definition: kahan.hxx:189
constexpr KahanSum()=default
constexpr bool operator<=(const KahanSum &fSum) const
Definition: kahan.hxx:181
constexpr KahanSum operator*(double fTimes) const
Definition: kahan.hxx:157
KahanSum operator+(const KahanSum &fSum) const
Definition: kahan.hxx:115
void operator-=(double fSum)
Definition: kahan.hxx:106
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:140
XPropertyListType t
constexpr bool operator>=(const KahanSum &fSum) const
Definition: kahan.hxx:185
constexpr bool operator<(double fSum) const
Definition: kahan.hxx:175
constexpr bool operator>(double fSum) const
Definition: kahan.hxx:179
constexpr double * getSum()
Definition: kahan.hxx:199
void add(const KahanSum &fSum)
Adds a value to the sum using Kahan summation.
Definition: kahan.hxx:66
constexpr bool operator<=(double fSum) const
Definition: kahan.hxx:183
constexpr bool operator!=(const KahanSum &fSum) const
Definition: kahan.hxx:194
KahanSum operator+(double fSum) const
Definition: kahan.hxx:108
double m_fError
Definition: kahan.hxx:211