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#include "true_math.h"
17
18#include <iostream>
19#include <math.h>
20#include <limits>
21
22// forward declarations
23template <typename T, typename U=T> class MeanEstimate;
24template <typename T, typename U=T> class MeanRadian;
25
27
33template <typename T, typename U=T>
34class Estimate
35{
36
37 public:
38
39 typedef T val_type;
40 typedef U var_type;
41
43 T val;
45 U var;
46
48 Estimate (T _val=0, U _var=0) { val=_val; var=_var; }
49
51 template <typename V, typename W>
52 Estimate (const Estimate<V,W>& d) { val=d.val; var=d.var; }
53
55 template <typename V, typename W>
56 Estimate (const MeanEstimate<V,W>& m) { operator=( m.get_Estimate() ); }
57
59 template <typename V, typename W>
60 Estimate (const MeanRadian<V,W>& m) { operator=( m.get_Estimate() ); }
61
63 const Estimate& operator= (const Estimate& d)
64 { val=d.val; var=d.var; return *this; }
65
67 void set_value (const T& t) { val = t; }
68
70 T get_value () const { return val; }
71
73 void set_variance (const U& u) { var = u; }
74
76 U get_variance () const { return var; }
77
79 void set_error (const U& u) { var = u*u; }
80
82 U get_error () const { return sqrt(var); }
83
85 T& operator [] (unsigned) { return val; }
86
88 T operator [] (unsigned) const { return val; }
89
91 const Estimate& operator+= (const Estimate& d)
92 { val += d.val; var += d.var; return *this; }
93
95 const Estimate& operator-= (const Estimate& d)
96 { val -= d.val; var += d.var; return *this; }
97
99
100 const Estimate& operator*= (const Estimate& d)
101 { var=val*val*d.var+d.val*d.val*var; val*=d.val; return *this; }
102
104 const Estimate& operator/= (const Estimate& d)
105 { return operator *= (d.inverse()); }
106
108 bool operator == (const Estimate& d) const
109 { return val == d.val; }
110
112 bool operator != (const Estimate& d) const
113 { return ! operator == (d); }
114
116 bool operator < (const Estimate& d) const
117 { return val < d.val; }
118
120 bool operator > (const Estimate& d) const
121 { return val > d.val; }
122
124
125 const Estimate inverse () const
126 { T v=1.0/val; return Estimate (v,var*v*v*v*v); }
127
128 friend const Estimate operator + (Estimate a, const Estimate& b)
129 { return a+=b; }
130
131 friend const Estimate operator - (Estimate a, const Estimate& b)
132 { return a-=b; }
133
134 friend const Estimate operator * (Estimate a, const Estimate& b)
135 { return a*=b; }
136
137 friend const Estimate operator / (Estimate a, const Estimate& b)
138 { return a/=b; }
139
141 friend const Estimate operator - (Estimate a)
142 { return Estimate (-a.val, a.var); }
143
144#if COMPLEX_SPECIALIZE
145 friend const std::complex<Estimate> operator * (const std::complex<Estimate>& a, const std::complex<Estimate>& b)
146 {
147 return std::complex<Estimate> (
148 a.real()*b.real() - a.imag()*b.imag(),
149 a.real()*b.imag() + a.imag()*b.real()
150 );
151 }
152
153 friend const Estimate norm (const std::complex<Estimate>& u)
154 { return u.real()*u.real() + u.imag()*u.imag(); }
155#endif
156
158 friend const Estimate exp (const Estimate& u)
159 { T val = ::exp (u.val); return Estimate (val, val*val*u.var); }
160
162 friend const Estimate log (const Estimate& u)
163 { return Estimate (::log (u.val), u.var/(u.val*u.val)); }
164
166 friend const Estimate sqrt (const Estimate& u)
167 { return Estimate (::sqrt (u.val), 0.25*u.var/fabs(u.val)); }
168
170 friend const Estimate sin (const Estimate& u)
171 { T val = ::sin (u.val); return Estimate (val, (1-val*val)*u.var); }
172
174 friend const Estimate cos (const Estimate& u)
175 { T val = ::cos (u.val); return Estimate (val, (1-val*val)*u.var); }
176
178 friend const Estimate acos (const Estimate& u)
179 { T val = ::acos (u.val); T del=-1.0/sqrt(1.0-u.val*u.val);
180 return Estimate (val, del*del*u.var); }
181
183 friend const Estimate atan (const Estimate& u)
184 { T val = ::atan (u.val); T del=1/(1+u.val*u.val);
185 return Estimate (val, del*del*u.var); }
186
188 friend const Estimate atan2 (const Estimate& s, const Estimate& c)
189 { T c2 = c.val*c.val; T s2 = s.val*s.val; T sc2 = c2+s2;
190 return Estimate (::atan2 (s.val, c.val),(c2*s.var+s2*c.var)/(sc2*sc2)); }
191
193 friend const Estimate sinh (const Estimate& u)
194 { T val = ::sinh (u.val); return Estimate (val, (1+val*val)*u.var); }
195
197 friend const Estimate cosh (const Estimate& u)
198 { T val = ::cosh (u.val); return Estimate (val, (val*val-1)*u.var); }
199
201 friend const Estimate atanh (const Estimate& u)
202 { T val = ::atanh (u.val); T del=1/(1-u.val*u.val);
203 return Estimate (val, del*del*u.var); }
204
205 friend int finite (const Estimate& u)
206 { return true_math::finite (u.val); }
207
208 friend int isinf (const Estimate& u)
209 { return isinf (u.val); }
210
211 friend int isnan (const Estimate& u)
212 { return isnan (u.val); }
213
214 friend const T abs (const Estimate& u)
215 { return std::abs (u.val); }
216
217 friend const Estimate copysign (const Estimate& u, const Estimate& v)
218 { return Estimate (::copysign (u.val, v.val), u.var); }
219};
220
221
223template <class T, class U> struct DatumTraits< Estimate<T,U> >
224{
225 ElementTraits<T> element_traits;
226 static inline unsigned ndim () { return 1; }
227 static inline T& element (Estimate<T,U>& t, unsigned)
228 { return t.val; }
229 static inline const T& element (const Estimate<T,U>& t, unsigned)
230 { return t.val; }
231};
232
233template <class T, class U, class V, class W>
234class PromoteTraits< Estimate<T,U>, Estimate<V,W> >
235{
236 public:
237 typedef Estimate< typename PromoteTraits<T,V>::promote_type,
238 typename PromoteTraits<U,W>::promote_type > promote_type;
239};
240
241template <class T, class U, class V>
242class PromoteTraits< Estimate<T,U>, V >
243{
244 public:
245 typedef Estimate<typename PromoteTraits<T,V>::promote_type,U> promote_type;
246};
247
248template <class T, class U, class V>
249class PromoteTraits< V, Estimate<T,U> >
250{
251 public:
252 typedef Estimate<typename PromoteTraits<T,V>::promote_type,U> promote_type;
253};
254
255namespace std
256{
257 template <class T, class U>
258 struct numeric_limits< Estimate<T,U> >
259 : public numeric_limits<T> { };
260}
261
263template<typename T, typename U>
264std::ostream& operator<< (std::ostream& ostr, const Estimate<T,U>& estimate)
265{
266 return ostr << "(" << estimate.val << "+-" << sqrt(estimate.var) << ")";
267}
268
269static inline bool expect (std::istream& is, char c)
270{
271 if (is.peek() != c) {
272 is.setstate (std::ios::failbit);
273 return false;
274 }
275 is.get();
276 return true;
277}
278
279template<typename T, typename U>
280std::istream& operator >> (std::istream& is, Estimate<T,U>& estimate)
281{
282 char open_brace;
283 is >> open_brace;
284
285 bool bracketed=true;
286 if (open_brace != '(') {
287 is.unget ();
288 bracketed=false;
289 }
290
291 double value;
292 is >> value;
293
294 if (!expect(is, '+'))
295 return is;
296 if (!expect(is, '-'))
297 return is;
298
299 double error;
300 is >> error;
301
302 if (bracketed)
303 {
304 if (!expect(is, ')'))
305 return is;
306 }
307
308 estimate.set_value (value);
309 estimate.set_error (error);
310 return is;
311}
312
314std::string latex (const Estimate<double>&);
315
321template <typename T, typename U>
322class MeanEstimate
323{
324 public:
326 T norm_val;
328 U inv_var;
329
331 MeanEstimate (T _val=0, U _var=0) { norm_val=_val; inv_var=_var; }
332
334 MeanEstimate (const MeanEstimate& d)
336
338 MeanEstimate (const Estimate<T,U>& d)
339 { norm_val = 0; inv_var = 0; operator += (d); }
340
342 const MeanEstimate& operator= (const MeanEstimate& d)
343 { norm_val=d.norm_val; inv_var=d.inv_var; return *this; }
344
346 const MeanEstimate& operator+= (const MeanEstimate& d)
347 { norm_val += d.norm_val; inv_var += d.inv_var; return *this; }
348
350 const MeanEstimate& operator+= (const Estimate<T,U>& d)
351 { if (d.var){ U v=1.0/d.var; norm_val+=d.val*v; inv_var+=v; } return *this; }
352
354 bool operator == (T _norm_val) const
355 { return norm_val == _norm_val; }
356
357 Estimate<T,U> get_Estimate () const
358 { U var=0.0; if (inv_var != 0.0) var = 1.0/inv_var;
359 return Estimate<T,U> (norm_val*var, var); }
360
361};
362
364template<typename T, typename U>
365std::ostream& operator<< (std::ostream& ostr, const MeanEstimate<T,U>& mean)
366{
367 return ostr << mean.get_Estimate();
368}
369
371
373template <typename T, typename U>
374class MeanRadian
375{
376
377 public:
378
380 MeanRadian () { }
381
383 MeanRadian (const MeanRadian& mean)
384 { operator = (mean); }
385
387 const MeanRadian& operator= (const MeanRadian& mean)
388 { cosine = mean.cosine; sine = mean.sine; return *this; }
389
391 MeanRadian (const Estimate<T,U>& d)
392 { operator = (d); }
393
395 const MeanRadian& operator= (const Estimate<T,U>& d)
396 { cosine = cos(d); sine = sin(d); return *this; }
397
399 const MeanRadian& operator+= (const MeanRadian& d)
400 { cosine += d.cosine; sine += d.sine; return *this; }
401
403 const MeanRadian& operator+= (const Estimate<T,U>& d)
404 { cosine += cos(d); sine += sin(d); return *this; }
405
406 Estimate<T,U> get_Estimate () const
407 { if (sine.norm_val==0 && cosine.norm_val==0) return Estimate<T,U>(0,0);
408 return atan2 (sine.get_Estimate(), cosine.get_Estimate()); }
409
410 Estimate<T,U> get_sin () const
411 { return sine.get_Estimate(); }
412
413 Estimate<T,U> get_cos () const
414 { return cosine.get_Estimate(); }
415
416 protected:
418 MeanEstimate<T,U> cosine;
419
421 MeanEstimate<T,U> sine;
422
423};
424
426template<typename T, typename U>
427std::ostream& operator<< (std::ostream& ostr, const MeanRadian<T,U>& mean)
428{
429 return ostr << mean.get_Estimate();
430}
431
432#endif
433
U get_error() const
bool operator<(const Estimate &d) const
T get_value() const
friend friend const Estimate cos(const Estimate &u)
bool operator>(const Estimate &d) const
friend friend const Estimate cosh(const Estimate &u)
T val
Definition Estimate.h:43
void set_value(const T &t)
friend friend const Estimate atan(const Estimate &u)
friend friend const Estimate log(const Estimate &u)
bool operator!=(const Estimate &d) const
const Estimate & operator/=(const Estimate &d)
bool operator==(const Estimate &d) const
T & operator[](unsigned)
friend friend const Estimate atanh(const Estimate &u)
U var
Definition Estimate.h:45
const Estimate & operator=(const Estimate &d)
const Estimate & operator+=(const Estimate &d)
Estimate(T _val=0, U _var=0)
friend friend const Estimate sqrt(const Estimate &u)
friend friend const Estimate atan2(const Estimate &s, const Estimate &c)
const Estimate & operator*=(const Estimate &d)
friend friend const Estimate operator-(Estimate a)
friend friend const Estimate sinh(const Estimate &u)
const Estimate & operator-=(const Estimate &d)
friend friend const Estimate acos(const Estimate &u)
friend friend const Estimate sin(const Estimate &u)
void set_error(const U &u)
const Estimate inverse() const
U get_variance() const
void set_variance(const U &u)
friend friend const Estimate exp(const Estimate &u)
const MeanEstimate & operator+=(const MeanEstimate &d)
const MeanEstimate & operator=(const MeanEstimate &d)
T norm_val
Definition Estimate.h:326
bool operator==(T _norm_val) const
U inv_var
Definition Estimate.h:328
MeanEstimate(T _val=0, U _var=0)
const MeanRadian & operator=(const MeanRadian &mean)
MeanEstimate< T, U > sine
Definition Estimate.h:421
MeanEstimate< T, U > cosine
Definition Estimate.h:418
const MeanRadian & operator+=(const MeanRadian &d)
STL namespace.
E element_traits
Definition Traits.h:73

Generated using doxygen 1.14.0