![]() |
Reference Documentation |
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) |