Estimate.h
1 //-*-C++-*-
2 /***************************************************************************
3  *
4  * Copyright (C) 2003 by Willem van Straten
5  * Licensed under the Academic Free License version 2.1
6  *
7  ***************************************************************************/
8 
9 // epsic/src/util/Estimate.h
10 
11 #ifndef __Estimate_h
12 #define __Estimate_h
13 
14 #include "PromoteTraits.h"
15 #include "Traits.h"
16 
17 #include <iostream>
18 #include <math.h>
19 #include <limits>
20 
21 // forward declarations
22 template <typename T, typename U=T> class MeanEstimate;
23 template <typename T, typename U=T> class MeanRadian;
24 
26 
32 template <typename T, typename U=T>
33 class Estimate
34 {
35 
36  public:
37 
38  typedef T val_type;
39  typedef U var_type;
40 
42  T val;
44  U var;
45 
47  Estimate (T _val=0, U _var=0) { val=_val; var=_var; }
48 
50  template <typename V, typename W>
51  Estimate (const Estimate<V,W>& d) { val=d.val; var=d.var; }
52 
54  template <typename V, typename W>
55  Estimate (const MeanEstimate<V,W>& m) { operator=( m.get_Estimate() ); }
56 
58  template <typename V, typename W>
59  Estimate (const MeanRadian<V,W>& m) { operator=( m.get_Estimate() ); }
60 
62  const Estimate& operator= (const Estimate& d)
63  { val=d.val; var=d.var; return *this; }
64 
66  void set_value (const T& t) { val = t; }
67 
69  T get_value () const { return val; }
70 
72  void set_variance (const U& u) { var = u; }
73 
75  U get_variance () const { return var; }
76 
78  void set_error (const U& u) { var = u*u; }
79 
81  U get_error () const { return sqrt(var); }
82 
84  T& operator [] (unsigned) { return val; }
85 
87  T operator [] (unsigned) const { return val; }
88 
90  const Estimate& operator+= (const Estimate& d)
91  { val += d.val; var += d.var; return *this; }
92 
94  const Estimate& operator-= (const Estimate& d)
95  { val -= d.val; var += d.var; return *this; }
96 
98 
99  const Estimate& operator*= (const Estimate& d)
100  { var=val*val*d.var+d.val*d.val*var; val*=d.val; return *this; }
101 
103  const Estimate& operator/= (const Estimate& d)
104  { return operator *= (d.inverse()); }
105 
107  bool operator == (const Estimate& d) const
108  { return val == d.val; }
109 
111  bool operator != (const Estimate& d) const
112  { return ! operator == (d); }
113 
115  bool operator < (const Estimate& d) const
116  { return val < d.val; }
117 
119  bool operator > (const Estimate& d) const
120  { return val > d.val; }
121 
123 
124  const Estimate inverse () const
125  { T v=1.0/val; return Estimate (v,var*v*v*v*v); }
126 
127  friend const Estimate operator + (Estimate a, const Estimate& b)
128  { return a+=b; }
129 
130  friend const Estimate operator - (Estimate a, const Estimate& b)
131  { return a-=b; }
132 
133  friend const Estimate operator * (Estimate a, const Estimate& b)
134  { return a*=b; }
135 
136  friend const Estimate operator / (Estimate a, const Estimate& b)
137  { return a/=b; }
138 
140  friend const Estimate operator - (Estimate a)
141  { return Estimate (-a.val, a.var); }
142 
143 #if COMPLEX_SPECIALIZE
144  friend const std::complex<Estimate> operator * (const std::complex<Estimate>& a, const std::complex<Estimate>& b)
145  {
146  return std::complex<Estimate> (
147  a.real()*b.real() - a.imag()*b.imag(),
148  a.real()*b.imag() + a.imag()*b.real()
149  );
150  }
151 
152  friend const Estimate norm (const std::complex<Estimate>& u)
153  { return u.real()*u.real() + u.imag()*u.imag(); }
154 #endif
155 
157  friend const Estimate exp (const Estimate& u)
158  { T val = ::exp (u.val); return Estimate (val, val*val*u.var); }
159 
161  friend const Estimate log (const Estimate& u)
162  { return Estimate (::log (u.val), u.var/(u.val*u.val)); }
163 
165  friend const Estimate sqrt (const Estimate& u)
166  { return Estimate (::sqrt (u.val), 0.25*u.var/fabs(u.val)); }
167 
169  friend const Estimate sin (const Estimate& u)
170  { T val = ::sin (u.val); return Estimate (val, (1-val*val)*u.var); }
171 
173  friend const Estimate cos (const Estimate& u)
174  { T val = ::cos (u.val); return Estimate (val, (1-val*val)*u.var); }
175 
177  friend const Estimate acos (const Estimate& u)
178  { T val = ::acos (u.val); T del=-1.0/sqrt(1.0-u.val*u.val);
179  return Estimate (val, del*del*u.var); }
180 
182  friend const Estimate atan (const Estimate& u)
183  { T val = ::atan (u.val); T del=1/(1+u.val*u.val);
184  return Estimate (val, del*del*u.var); }
185 
187  friend const Estimate atan2 (const Estimate& s, const Estimate& c)
188  { T c2 = c.val*c.val; T s2 = s.val*s.val; T sc2 = c2+s2;
189  return Estimate (::atan2 (s.val, c.val),(c2*s.var+s2*c.var)/(sc2*sc2)); }
190 
192  friend const Estimate sinh (const Estimate& u)
193  { T val = ::sinh (u.val); return Estimate (val, (1+val*val)*u.var); }
194 
196  friend const Estimate cosh (const Estimate& u)
197  { T val = ::cosh (u.val); return Estimate (val, (val*val-1)*u.var); }
198 
200  friend const Estimate atanh (const Estimate& u)
201  { T val = ::atanh (u.val); T del=1/(1-u.val*u.val);
202  return Estimate (val, del*del*u.var); }
203 
204  friend int myfinite (const Estimate& u)
205  { return myfinite (u.val); }
206 
207  friend int isinf (const Estimate& u)
208  { return isinf (u.val); }
209 
210  friend int isnan (const Estimate& u)
211  { return isnan (u.val); }
212 
213  friend const T abs (const Estimate& u)
214  { return std::abs (u.val); }
215 
216  friend const Estimate copysign (const Estimate& u, const Estimate& v)
217  { return Estimate (::copysign (u.val, v.val), u.var); }
218 };
219 
220 
222 template <class T, class U> struct DatumTraits< Estimate<T,U> >
223 {
225  static inline unsigned ndim () { return 1; }
226  static inline T& element (Estimate<T,U>& t, unsigned)
227  { return t.val; }
228  static inline const T& element (const Estimate<T,U>& t, unsigned)
229  { return t.val; }
230 };
231 
232 template <class T, class U, class V, class W>
233 class PromoteTraits< Estimate<T,U>, Estimate<V,W> >
234 {
235  public:
237  typename PromoteTraits<U,W>::promote_type > promote_type;
238 };
239 
240 template <class T, class U, class V>
241 class PromoteTraits< Estimate<T,U>, V >
242 {
243  public:
245 };
246 
247 template <class T, class U, class V>
248 class PromoteTraits< V, Estimate<T,U> >
249 {
250  public:
252 };
253 
254 namespace std
255 {
256  template <class T, class U>
257  struct numeric_limits< Estimate<T,U> >
258  : public numeric_limits<T> { };
259 }
260 
262 template<typename T, typename U>
263 std::ostream& operator<< (std::ostream& ostr, const Estimate<T,U>& estimate)
264 {
265  return ostr << "(" << estimate.val << "+-" << sqrt(estimate.var) << ")";
266 }
267 
268 static inline bool expect (std::istream& is, char c)
269 {
270  if (is.peek() != c) {
271  is.setstate (std::ios::failbit);
272  return false;
273  }
274  is.get();
275  return true;
276 }
277 
278 template<typename T, typename U>
279 std::istream& operator >> (std::istream& is, Estimate<T,U>& estimate)
280 {
281  char open_brace;
282  is >> open_brace;
283 
284  bool bracketed=true;
285  if (open_brace != '(') {
286  is.unget ();
287  bracketed=false;
288  }
289 
290  double value;
291  is >> value;
292 
293  if (!expect(is, '+'))
294  return is;
295  if (!expect(is, '-'))
296  return is;
297 
298  double error;
299  is >> error;
300 
301  if (bracketed)
302  {
303  if (!expect(is, ')'))
304  return is;
305  }
306 
307  estimate.set_value (value);
308  estimate.set_error (error);
309  return is;
310 }
311 
313 std::string latex (const Estimate<double>&);
314 
320 template <typename T, typename U>
321 class MeanEstimate
322 {
323  public:
325  T norm_val;
327  U inv_var;
328 
330  MeanEstimate (T _val=0, U _var=0) { norm_val=_val; inv_var=_var; }
331 
333  MeanEstimate (const MeanEstimate& d)
334  { norm_val=d.norm_val; inv_var=d.inv_var; }
335 
337  MeanEstimate (const Estimate<T,U>& d)
338  { norm_val = 0; inv_var = 0; operator += (d); }
339 
341  const MeanEstimate& operator= (const MeanEstimate& d)
342  { norm_val=d.norm_val; inv_var=d.inv_var; return *this; }
343 
345  const MeanEstimate& operator+= (const MeanEstimate& d)
346  { norm_val += d.norm_val; inv_var += d.inv_var; return *this; }
347 
349  const MeanEstimate& operator+= (const Estimate<T,U>& d)
350  { if (d.var){ U v=1.0/d.var; norm_val+=d.val*v; inv_var+=v; } return *this; }
351 
353  bool operator == (T _norm_val) const
354  { return norm_val == _norm_val; }
355 
356  Estimate<T,U> get_Estimate () const
357  { U var=0.0; if (inv_var != 0.0) var = 1.0/inv_var;
358  return Estimate<T,U> (norm_val*var, var); }
359 
360 };
361 
363 template<typename T, typename U>
364 std::ostream& operator<< (std::ostream& ostr, const MeanEstimate<T,U>& mean)
365 {
366  return ostr << mean.get_Estimate();
367 }
368 
370 
372 template <typename T, typename U>
373 class MeanRadian
374 {
375 
376  public:
377 
379  MeanRadian () { }
380 
382  MeanRadian (const MeanRadian& mean)
383  { operator = (mean); }
384 
386  const MeanRadian& operator= (const MeanRadian& mean)
387  { cosine = mean.cosine; sine = mean.sine; return *this; }
388 
390  MeanRadian (const Estimate<T,U>& d)
391  { operator = (d); }
392 
394  const MeanRadian& operator= (const Estimate<T,U>& d)
395  { cosine = cos(d); sine = sin(d); return *this; }
396 
398  const MeanRadian& operator+= (const MeanRadian& d)
399  { cosine += d.cosine; sine += d.sine; return *this; }
400 
402  const MeanRadian& operator+= (const Estimate<T,U>& d)
403  { cosine += cos(d); sine += sin(d); return *this; }
404 
405  Estimate<T,U> get_Estimate () const
406  { if (sine.norm_val==0 && cosine.norm_val==0) return Estimate<T,U>(0,0);
407  return atan2 (sine.get_Estimate(), cosine.get_Estimate()); }
408 
409  Estimate<T,U> get_sin () const
410  { return sine.get_Estimate(); }
411 
412  Estimate<T,U> get_cos () const
413  { return cosine.get_Estimate(); }
414 
415  protected:
418 
421 
422 };
423 
425 template<typename T, typename U>
426 std::ostream& operator<< (std::ostream& ostr, const MeanRadian<T,U>& mean)
427 {
428  return ostr << mean.get_Estimate();
429 }
430 
431 #endif
432 
const MeanEstimate & operator+=(const MeanEstimate &d)
friend const friend Estimate sin(const Estimate &u)
friend const friend Estimate cosh(const Estimate &u)
friend const friend Estimate sinh(const Estimate &u)
MeanEstimate(T _val=0, U _var=0)
Calculates the mean of a value in radians.
Definition: Estimate.h:23
friend const friend Estimate exp(const Estimate &u)
friend const friend Estimate cos(const Estimate &u)
const Estimate & operator+=(const Estimate &d)
bool operator==(T _norm_val) const
T val
The value, .
Definition: Estimate.h:42
const Estimate & operator*=(const Estimate &d)
friend const friend Estimate acos(const Estimate &u)
U get_error() const
bool operator<(const Estimate &d) const
void set_error(const U &u)
U var
The variance of the value, .
Definition: Estimate.h:44
bool operator==(const Estimate &d) const
T norm_val
The value, normalized by its variance.
Definition: Estimate.h:325
const Estimate & operator=(const Estimate &d)
MeanEstimate< T, U > sine
The average sine.
Definition: Estimate.h:420
friend const friend Estimate log(const Estimate &u)
U inv_var
The inverse of its variance.
Definition: Estimate.h:327
T & operator[](unsigned)
void set_value(const T &t)
friend const friend Estimate atan2(const Estimate &s, const Estimate &c)
Definition: Estimate.h:22
bool operator!=(const Estimate &d) const
friend const friend Estimate atan(const Estimate &u)
T get_value() const
E element_traits
Traits of the elements of the data type.
Definition: Traits.h:73
const Estimate & operator-=(const Estimate &d)
friend const friend Estimate sqrt(const Estimate &u)
Estimate(T _val=0, U _var=0)
friend const friend Estimate operator-(Estimate a)
bool operator>(const Estimate &d) const
const Estimate & operator/=(const Estimate &d)
U get_variance() const
MeanEstimate< T, U > cosine
The average cosine.
Definition: Estimate.h:417
const MeanRadian & operator+=(const MeanRadian &d)
const Estimate inverse() const
const MeanEstimate & operator=(const MeanEstimate &d)
friend const friend Estimate atanh(const Estimate &u)
const MeanRadian & operator=(const MeanRadian &mean)
Traits of the data type.
Definition: Traits.h:70
void set_variance(const U &u)

Generated using doxygen 1.8.17