00001 #ifndef _PROFILE_BIN_H_
00002 #define _PROFILE_BIN_H_ 1
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
00037 class Profile_Bin: public I_Bin {
00038 public:
00040 H_IID_IMPLEMENT( Profile_Bin );
00041 public:
00042 typedef Profile_Bin Like_Current;
00043 typedef I_Bin Like_Parent;
00044 public:
00046 Profile_Bin(): I_Bin(), sum_w_(0), sum_wk_(0), sum_wkk_(0), count_(0){}
00048 ~Profile_Bin() {}
00049 public:
00057 double value( Index i = 0 ) const {
00058
00059 if( i == 1 ) return sum_w_;
00060 if( i == 2 ) return sum_wk_;
00061 if( i == 3 ) return sum_wkk_;
00062 return (sum_w_ != 0) ? sum_wk_/sum_w_ : 0.0;
00063 }
00064
00068 double error( Index i = 0 ) const {
00069 double v = fabs(value());
00070 if (sum_w_>=0.) {
00071 double ee = (sum_w_ != 0) ? sum_wkk_/sum_w_ : 0.0;
00072 double s = sqrt( fabs( ee - v*v ) );
00073
00074 switch(i) {
00075 case 0:
00076 if( sum_w_ == 0.0 ) return 0.0;
00077 if( s == 0.0 ) return sqrt( v/sum_w_ );
00078 return s / sqrt( sum_w_ );
00079 default:
00080 if( sum_w_ == 0.0 ) return 0.0;
00081 if( s == 0.0 ) return sqrt( v );
00082 return s;
00083 }
00084 } else {
00085 HTL_ERR( "Inconsistency in Profile Bin: l<0. Error is zero" );
00086 return 0;
00087 }
00088 }
00089
00091 Size count() const { return count_; }
00092
00101 void set_value( double other, Index i = 0 ) {
00102 if( i == 1 ) sum_w_ = other;
00103 if( i == 2 )sum_wk_ = other;
00104 if( i == 3 )sum_wkk_ = other;
00105 }
00106
00110 void set_error(double , Index = 0){
00111 HTL_ERR("set_error() Not implemented");
00112 }
00113
00115 void set_count( Size other ) { count_ = Size(other); }
00116
00118 void reset() { T_Value x = T_Value(0); sum_w_ = x; sum_wk_ = x;
00119 sum_wkk_ = x; count_ = 0; }
00120 public:
00123 void put( T_Value a_weight, T_Value a_character ) {
00124 sum_w_ += a_weight;
00125 sum_wk_ += a_weight*a_character;
00126 sum_wkk_ += a_weight*a_character*a_character;
00127 count_ ++;
00128 }
00129
00130 public:
00132 int operator==( const Like_Current &other ) const
00133 {
00134 return(
00135 (sum_w_ == other.value(1)) &&
00136 (sum_wk_ == other.value(2)) &&
00137 (sum_wkk_ == other.value(3)) &&
00138 (count() == other.count())
00139 );
00140 }
00141
00143 void make( const Like_Parent &other )
00144 {
00145 sum_w_ = other.value(1);
00146 sum_wk_ = other.value(2);
00147 sum_wkk_ = other.value(3);
00148 count_ = other.count();
00149 }
00150
00152 void add( const Like_Parent &other )
00153 {
00154
00155 if (H_IID_IS_EQUAL((*this), other)) {
00156
00157
00158
00159
00160
00161
00162
00163
00164 sum_w_ = T_Value( sum_w_ + other.value(1) );
00165 sum_wk_ = T_Value( sum_wk_ + other.value(2) );
00166 sum_wkk_ = T_Value( sqrt( sum_wkk_*sum_wkk_ +
00167 other.value(3)*other.value(3) ) );
00168 count_ += other.count();
00169 } else
00170 HTL_ERR("Cant add in Profile_Bin. Incompatible bins");
00171 }
00172
00174 void sub( const Like_Parent &other )
00175 {
00176
00177 if (H_IID_IS_EQUAL((*this), other)) {
00178 sum_w_ = T_Value( sum_w_ - other.value(1) );
00179 sum_wk_ = T_Value( sum_wk_ - other.value(2) );
00180 sum_wkk_ = T_Value( sqrt( sum_wkk_*sum_wkk_ +
00181 other.value(3)*other.value(3) ) );
00182 count_ += other.count();
00183 } else
00184 HTL_ERR("Cant sub in Profile_Bin. Incompatible bins" );
00185 }
00186
00188 void mul( const Like_Parent &other )
00189 {
00190 sum_w_ = T_Value( sum_w_ * other.value(1) );
00191 sum_wk_ = T_Value( sum_wk_ * other.value(2) );
00192 sum_wkk_ = T_Value( sqrt( sum_wkk_*sum_wkk_ +
00193 other.value(3)*other.value(3) ) );
00194 count_ += other.count();
00195 }
00196
00201 void div( const Like_Parent &other )
00202 {
00203 if( T_Value( other.value(1) ) == T_Value(0.) ) {
00204 HTL_ERR( "WARNING: Division by 0 in Profile_Bin: L" );
00205 sum_w_ = T_Value(0.);
00206 } else {
00207 sum_w_ = T_Value( sum_w_ / other.value(1) );
00208 }
00209 if( T_Value( other.value(2) ) == T_Value(0.) ) {
00210 HTL_ERR( "WARNING: Division by 0 in Profile_Bin: H" );
00211 sum_wk_ = T_Value(0.);
00212 } else {
00213 sum_wk_ = T_Value( sum_wk_ / other.value(2) );
00214 }
00215 sum_wkk_ = T_Value( sqrt( sum_wkk_*sum_wkk_ +
00216 other.value(3)*other.value(3) ) );
00217 count_ += other.count();
00218 }
00219
00224 void binomial_div( const Like_Parent &other )
00225 {
00226 if( T_Value( other.value(1) ) == T_Value(0.) ) {
00227 HTL_ERR( "WARNING: Division by 0 in Profile_Bin: L" );
00228 sum_w_ = T_Value(0.);
00229 } else {
00230 sum_w_ = T_Value( sum_w_ / other.value(1) );
00231 }
00232 if( T_Value( other.value(2) ) == T_Value(0.) ) {
00233 HTL_ERR( "WARNING: Division by 0 in Profile_Bin: H" );
00234 sum_wk_ = T_Value(0.);
00235 } else {
00236 sum_wk_ = T_Value( sum_wk_ / other.value(2) );
00237 }
00238 T_Value e = T_Value( other.value(3) );
00239 if( e == T_Value(0.) ) {
00240 HTL_ERR( "WARNING: Division by 0 in Weighted_Bin" );
00241 sum_wkk_ = T_Value(0.);
00242 } else {
00243
00244 sum_wkk_ = sqrt( sum_wkk_ / e );
00245 sum_wkk_ = sum_wkk_ * (1-sum_wkk_);
00246
00247 sum_wkk_ = T_Value( sum_wkk_ / e );
00248 }
00249 }
00250
00252 void add( double x ) { sum_wk_ = T_Value( sum_wk_ + x ); }
00254 void sub( double x ) { sum_wk_ = T_Value( sum_wk_ - x ); }
00256 void mul( double x ) { sum_wk_ = T_Value( sum_wk_ * x ); }
00258 void div( double x )
00259 {
00260 if( x != 0. ) {
00261 sum_wk_ = T_Value( sum_wk_ / x );
00262 return;
00263 }
00264 HTL_ERR( "WARNING: Division in Profile_Bin: div(x) " );
00265 sum_wk_ = T_Value(0.);
00266 }
00267
00268 private:
00269 T_Value sum_w_;
00270 T_Value sum_wk_;
00271 T_Value sum_wkk_;
00272 Size count_;
00273 };
00274
00275 #undef T_Value
00276
00277 #endif // _PROFILE_BIN_H_
00278