IsoSpec  1.95
summator.h
1 /*
2  * Copyright (C) 2015-2019 Mateusz Łącki and Michał Startek.
3  *
4  * This file is part of IsoSpec.
5  *
6  * IsoSpec is free software: you can redistribute it and/or modify
7  * it under the terms of the Simplified ("2-clause") BSD licence.
8  *
9  * IsoSpec is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * You should have received a copy of the Simplified BSD Licence
14  * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
15  */
16 
17 #pragma once
18 
19 #include <cmath>
20 
21 namespace IsoSpec
22 {
23 
24 class SSummator
25 {
26  // Shewchuk algorithm
27  std::vector<double> partials;
28  int maxpart;
29 public:
30  inline SSummator()
31  { maxpart = 0; }
32 
33  inline SSummator(SSummator& other)
34  {
35  this->partials = other.partials;
36  this->maxpart = other.maxpart;
37  }
38  inline void add(double x)
39  {
40  unsigned int i=0;
41  for(int pidx=0; pidx<maxpart; pidx++)
42  {
43  double y = partials[pidx];
44  if(std::abs(x) < std::abs(y))
45  std::swap(x, y);
46  double hi = x+y;
47  double lo = y-(hi-x);
48  if(lo != 0.0)
49  {
50  partials[i] = lo;
51  i += 1;
52  }
53  x = hi;
54  }
55  while(partials.size() <= i)
56  partials.push_back(0.0);
57  partials[i] = x;
58  maxpart = i+1;
59  }
60  inline double get()
61  {
62  double ret = 0.0;
63  for(int i=0; i<maxpart; i++)
64  ret += partials[i];
65  return ret;
66  }
67 };
68 
69 
70 
71 
72 
73 
74 
75 class Summator{
76  // Kahan algorithm
77  double sum;
78  double c;
79 
80 public:
81  inline Summator()
82  { sum = 0.0; c = 0.0;}
83 
84  inline void add(double what)
85  {
86  double y = what - c;
87  double t = sum + y;
88  c = (t - sum) - y;
89  sum = t;
90  }
91 
92  inline double get()
93  {
94  return sum;
95  }
96 };
97 
98 class TSummator
99 {
100  // Trivial algorithm, for testing only
101  double sum;
102 public:
103  inline TSummator()
104  { sum = 0.0; }
105 
106  inline void add(double what)
107  {
108  sum += what;
109  }
110  inline double get()
111  {
112  return sum;
113  }
114 };
115 
116 
117 } // namespace IsoSpec
118 
IsoSpec
Definition: allocator.cpp:21
IsoSpec::SSummator
Definition: summator.h:24
IsoSpec::TSummator
Definition: summator.h:98
IsoSpec::Summator
Definition: summator.h:75