Accumulator.java
Go to the documentation of this file.
1 
8 package net.sf.geographiclib;
9 
25 public class Accumulator {
26  // _s + _t accumulators for the sum.
27  private double _s, _t;
33  public Accumulator(double y) { _s = y; _t = 0; }
39  public Accumulator(Accumulator a) { _s = a._s; _t = a._t; }
45  public void Set(double y) { _s = y; _t = 0; }
51  public double Sum() { return _s; }
59  public double Sum(double y) {
60  Accumulator a = new Accumulator(this);
61  a.Add(y);
62  return a._s;
63  }
69  public void Add(double y) {
70  // Here's Shewchuk's solution...
71  double u; // hold exact sum as [s, t, u]
72  // Accumulate starting at least significant end
73  { Pair r = GeoMath.sum(y, _t); y = r.first; u = r.second; }
74  { Pair r = GeoMath.sum(y, _s); _s = r.first; _t = r.second; }
75  // Start is _s, _t decreasing and non-adjacent. Sum is now (s + t + u)
76  // exactly with s, t, u non-adjacent and in decreasing order (except for
77  // possible zeros). The following code tries to normalize the result.
78  // Ideally, we want _s = round(s+t+u) and _u = round(s+t+u - _s). The
79  // following does an approximate job (and maintains the decreasing
80  // non-adjacent property). Here are two "failures" using 3-bit floats:
81  //
82  // Case 1: _s is not equal to round(s+t+u) -- off by 1 ulp
83  // [12, -1] - 8 -> [4, 0, -1] -> [4, -1] = 3 should be [3, 0] = 3
84  //
85  // Case 2: _s+_t is not as close to s+t+u as it shold be
86  // [64, 5] + 4 -> [64, 8, 1] -> [64, 8] = 72 (off by 1)
87  // should be [80, -7] = 73 (exact)
88  //
89  // "Fixing" these problems is probably not worth the expense. The
90  // representation inevitably leads to small errors in the accumulated
91  // values. The additional errors illustrated here amount to 1 ulp of the
92  // less significant word during each addition to the Accumulator and an
93  // additional possible error of 1 ulp in the reported sum.
94  //
95  // Incidentally, the "ideal" representation described above is not
96  // canonical, because _s = round(_s + _t) may not be true. For example,
97  // with 3-bit floats:
98  //
99  // [128, 16] + 1 -> [160, -16] -- 160 = round(145).
100  // But [160, 0] - 16 -> [128, 16] -- 128 = round(144).
101  //
102  if (_s == 0) // This implies t == 0,
103  _s = u; // so result is u
104  else
105  _t += u; // otherwise just accumulate u to t.
106  }
112  public void Negate() { _s = -_s; _t = -_t; }
113 }
net.sf.geographiclib.Pair.second
double second
Definition: Pair.java:23
net.sf.geographiclib.GeoMath.sum
static Pair sum(double u, double v)
Definition: GeoMath.java:135
net.sf.geographiclib.Accumulator.Sum
double Sum(double y)
Definition: Accumulator.java:59
net.sf.geographiclib.Accumulator.Sum
double Sum()
Definition: Accumulator.java:51
net.sf.geographiclib.Accumulator
Definition: Accumulator.java:25
net.sf.geographiclib.Accumulator.Accumulator
Accumulator(Accumulator a)
Definition: Accumulator.java:39
net.sf.geographiclib.Pair.first
double first
Definition: Pair.java:19
net.sf.geographiclib.Accumulator.Add
void Add(double y)
Definition: Accumulator.java:69
net.sf.geographiclib.Pair
Definition: Pair.java:15
y
Scalar * y
Definition: level1_cplx_impl.h:124
net.sf.geographiclib.Accumulator.Negate
void Negate()
Definition: Accumulator.java:112
a
ArrayXXi a
Definition: Array_initializer_list_23_cxx11.cpp:1
net.sf.geographiclib.GeoMath
Definition: GeoMath.java:16
net.sf.geographiclib.Accumulator.Accumulator
Accumulator(double y)
Definition: Accumulator.java:33
net.sf.geographiclib.Accumulator._s
double _s
Definition: Accumulator.java:27
net.sf.geographiclib.Accumulator.Set
void Set(double y)
Definition: Accumulator.java:45


gtsam
Author(s):
autogenerated on Sat Nov 16 2024 04:01:47