Anaphe Home Page Reference Documentation

Main Page     Namespaces     Classes     Source Code    

Gravity_Bin_1D.h

Go to the documentation of this file.
00001 #ifndef _GRAVITY_BIN_1D_H_
00002 #define _GRAVITY_BIN_1D_H_
00003 
00004 
00005 #include <math.h>
00006 #include "HTL/I_Bin.h"
00007 #include "HTL/HTL_std.h"
00008 
00009 #undef T_Value
00010 #define T_Value double
00011 
00029 class Gravity_Bin_1D: public I_Bin {
00030 public:
00032   H_IID_IMPLEMENT( Gravity_Bin_1D );
00033 public:
00034   typedef Gravity_Bin_1D Like_Current;
00035   typedef I_Bin Like_Parent;
00036 public:
00038   Gravity_Bin_1D(): I_Bin(), value_(0), error_(0), count_(0), center_(0) {}
00040   ~Gravity_Bin_1D() {}
00041 public: // Inherited from I_Bin:
00043         double value( Index = 0 ) const { return value_; }
00044 
00046         double error( Index = 0 ) const { return sqrt(error_); }
00047 
00049         Size count() const { return count_; }
00050 
00052         void set_value( double other, Index = 0 ){ value_ = T_Value(other); }
00053 
00055         void set_error(double other,Index = 0){ error_ = T_Value(other*other);}
00056 
00058         void set_count( Size other ) { count_ = Size(other); }
00059 
00061         double center( Index = 0 ) const { return center_; }
00062 
00064         void set_center( double other ) { center_ = T_Value(other); }
00065 
00072   int offset( Index = 0 ) const { return 0; }
00073 
00075         void reset() { center_ = T_Value(0); value_ = T_Value(0);
00076                        error_ = T_Value(0); count_ = 0; }
00077 
00078 protected:
00079   void put( T_Value a_weight )
00080     {
00081       value_ += a_weight;
00082       error_ += a_weight * a_weight;
00083       count_ ++;
00084     }
00085 
00086 public:
00088   void put( T_Value a_weight, T_Value a_point )
00089     {
00090       if (a_weight == 0.) {     // shortcut ...
00091         count_ ++;
00092         return;
00093       }
00094 
00095       T_Value w_abs = a_weight < 0 ? a_weight : -a_weight ;
00096       T_Value v_abs = value_   < 0 ? value_   : -value_   ;
00097 
00098       center_ = (v_abs*center_ + w_abs*a_point)/(v_abs + w_abs);
00099 
00100       put( a_weight );          // only now update the other values ...
00101 
00102     }
00103 
00104 public:
00106   int operator==( const Like_Current &other ) const
00107     {
00108       return(
00109              (T_Value( value() ) == T_Value( other.value() )) &&
00110              (T_Value( error() ) == T_Value( other.error() )) &&
00111              (count() == other.count()) &&
00112              (T_Value( center(0) ) == T_Value( other.center(0) ))
00113              );
00114     }
00115 
00117   void make( const Like_Parent &other )
00118     {
00119       value_ = T_Value( other.value() );
00120       error_ = T_Value( other.error() * other.error() );
00121       count_ = other.count();
00122       center_ = T_Value( other.center(0) );
00123     }
00124 
00126   void combine_centers ( const Like_Parent &other )
00127     {
00128       T_Value v1,v2;
00129       v1 = fabs (value_);
00130       v2 = fabs (other.value());
00131       if ((v1 + v2) != 0)
00132         center_ = T_Value((v2*other.center(0) + v1*center_)/ (v1+v2));
00133       else
00134         center_ = T_Value ((other.center(0) + center_)/2.);
00135     }
00137   void add( const Like_Parent &other )
00138     {
00139       combine_centers (other);
00140       value_ = T_Value( value_ + other.value() );
00141       error_ = T_Value( other.error()*other.error() + error_ );
00142       count_ += other.count();
00143     }
00145   void sub( const Like_Parent &other )
00146     {
00147       combine_centers (other);
00148       value_ = T_Value( value_ - other.value() );
00149       error_ = T_Value( other.error() * other.error() + error_ );
00150       count_ += other.count();
00151     }
00152 
00154   void mul( const Like_Parent &other )
00155     {
00156       combine_centers (other);
00157       value_ = T_Value( value_ * other.value() );
00158       error_ = T_Value( error_ * other.value()*other.value() +
00159                         other.error()*other.error() * value_*value_ ) ;
00160       count_ += other.count();
00161     }
00162 
00167   void div( const Like_Parent &other )
00168     {
00169       combine_centers (other);
00170       T_Value e = T_Value( other.error() );
00171       e = T_Value( e*e * e*e * e*e * e*e );
00172       if( T_Value(other.value()) == T_Value(0.) ) {
00173         HTL_ERR( "WARNING: Division by 0 in Gravity_Bin_1D" );
00174         value_ = T_Value(0.);
00175       } else {
00176         value_ = T_Value( value_ / other.value() );
00177       }
00178       error_  = T_Value( error_ * other.value()*other.value() +
00179                          other.error()*other.error() * value_*value_ ) ;
00180       if( e == T_Value(0.) ) {
00181         HTL_ERR( "WARNING: Division by 0 in Gravity_Bin_1D" );
00182         error_ = T_Value(0.);
00183       } else {
00184         error_ = T_Value( error_/e );
00185       }
00186       count_ += other.count();
00187     }
00188 
00193   void binomial_div( const Like_Parent &other )
00194     {
00195       combine_centers (other);
00196       if( T_Value(other.value()) == T_Value(0.) ) {
00197         HTL_ERR( "WARNING: Division by 0 in Weighted_Bin" );
00198         value_ = T_Value(0.);
00199       } else {
00200         value_ = T_Value( value_ / other.value() );
00201       }
00202       T_Value e = T_Value( other.error() );
00203       if( e == T_Value(0.) ) {
00204         HTL_ERR( "WARNING: Division by 0 in Weighted_Bin" );
00205         error_ = T_Value(0.);
00206       } else {
00207         e = e * e;
00208         error_ = sqrt( error_ / e );
00209         error_ = error_ * (1-error_);
00210         error_ = error_ * error_;
00211         error_ = T_Value( error_ / e );
00212       }
00213       count_ += other.count();
00214     }
00215 
00217   void add( double x ) { value_ = T_Value( value_ + x ); }
00219   void sub( double x ) { value_ = T_Value( value_ - x ); }
00221   void mul( double x ) { value_ = T_Value( value_ * x ); }
00223   void div( double x )
00224     {
00225       if( x != 0. ) {
00226         value_ = T_Value( value_ / x );
00227         return;
00228       }
00229       HTL_ERR("WARNING: Division by 0 in Gravity_Bin_1D: div(x)" );
00230       value_ = T_Value(0.);
00231     }
00232 
00233 private:
00234   T_Value value_; // *Real* value.
00235   T_Value error_; // Square of the *real* error.
00236   Size  count_;
00237   T_Value center_;
00238 };
00239 
00240 #undef T_Value
00241 
00242 #endif // _GRAVITY_BIN_1D_H_
00243 
00244 
00245 /*
00246 
00247 This class does not need to be friend of itself for the assignment operator,
00248 because, as for Weighted_Bin, the value and the error are directly stored 
00249 in the bin and can be accessed from the interface methods.
00250 For the assignment operator we could have used I_Histo instead of 
00251 Like_Parent. We use the last one because of Profile_Bin.
00252 
00253 */
00254 


Anaphe documentation generated by Doxygen (www.doxygen.org)