Scippy

SoPlex

Sequential object-oriented simPlex

stablesum.h
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the class library */
4 /* SoPlex --- the Sequential object-oriented simPlex. */
5 /* */
6 /* Copyright (C) 1996-2019 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SoPlex is distributed under the terms of the ZIB Academic Licence. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SoPlex; see the file COPYING. If not email to soplex@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 #ifndef _SOPLEX_STABLE_SUM_H_
17 #define _SOPLEX_STABLE_SUM_H_
18 
19 // #define CHECK_STABLESUM // double check the stable sum computation
20 
21 #include <type_traits>
22 
23 namespace soplex
24 {
25 
26 template <typename T>
27 class StableSum
28 {
29  typename std::remove_const<T>::type sum;
30 
31 public:
32  StableSum() : sum(0) {}
33  StableSum(const T& init) : sum(init) {}
34 
35  void operator+=(const T& input)
36  {
37  sum += input;
38  }
39 
40  void operator-=(const T& input)
41  {
42  sum -= input;
43  }
44 
45  operator typename std::remove_const<T>::type() const
46  {
47  return sum;
48  }
49 };
50 
51 template <>
52 class StableSum<double>
53 {
54  double sum = 0;
55  double c = 0;
56 #ifdef CHECK_STABLESUM
57  double checksum = 0;
58 #endif
59 
60 public:
61  StableSum() = default;
62  StableSum(double init) : sum(init), c(0) {}
63 
64  void operator+=(double input)
65  {
66 #if defined(_MSC_VER) || defined(__INTEL_COMPILER)
67 #pragma float_control( precise, on )
68 #endif
69 #ifdef CHECK_STABLESUM
70  checksum += input;
71 #endif
72  double t = sum + input;
73  double z = t - sum;
74  double y = (sum - (t - z)) + (input - z);
75  c += y;
76 
77  sum = t;
78  }
79 
80  void operator-=(double input)
81  {
82  (*this) += -input;
83  }
84 
85  operator double() const
86  {
87 #ifdef CHECK_STABLESUM
88  if(spxAbs(checksum - (sum + c)) >= 1e-6)
89  printf("stablesum viol: %g, rel: %g, checksum: %g\n", spxAbs(checksum - (sum + c)),
90  spxAbs(checksum - (sum + c))/MAXIMUM(1.0, MAXIMUM(spxAbs(checksum), spxAbs(sum+c))), checksum);
91  assert(spxAbs(checksum - (sum + c)) < 1e-6);
92 #endif
93  return sum + c;
94  }
95 };
96 }
97 
98 #endif
Rational spxAbs(const Rational &r)
Absolute.
Definition: rational.cpp:3018
void operator+=(double input)
Definition: stablesum.h:64
void operator-=(double input)
Definition: stablesum.h:80
#define MAXIMUM(x, y)
Definition: spxdefines.h:246
void operator+=(const T &input)
Definition: stablesum.h:35
Everything should be within this namespace.
std::remove_const< T >::type sum
Definition: stablesum.h:29
void operator-=(const T &input)
Definition: stablesum.h:40
StableSum(const T &init)
Definition: stablesum.h:33