00001 #if 0
00002 #include "HTL/P_Histo_2D.h"
00003 #else
00004 #include "HTL/T_Histo_2D.h"
00005 #endif
00006
00007
00008
00009
00010 #define TEMPLATE___ \
00011 template< class T_Life, class T_Bin \
00012 , class T_Point_X, class T_Partition_X \
00013 , class T_Point_Y, class T_Partition_Y >
00014
00015 #define CLASS___ \
00016 T_Histo_2D < T_Life, T_Bin \
00017 , T_Point_X, T_Partition_X, T_Point_Y, T_Partition_Y >
00018
00019
00020
00021
00022
00023 TEMPLATE___
00024 CLASS___::T_Histo_2D ( const char *a_name
00025 , const T_Partition_X &a_partition_X
00026 , const T_Partition_Y &a_partition_Y )
00027 : T_I_Histo_2D()
00028 , name_(a_name)
00029 , partition_X_( a_partition_X )
00030 , partition_Y_( a_partition_Y )
00031 , bins_( (a_partition_X.bin_count()+2)*(a_partition_Y.bin_count()+2) +
00032 dim()*dim()*(dim()-1))
00033 {
00034
00035 }
00036
00037 TEMPLATE___
00038 CLASS___::T_Histo_2D( I_Histo &a_histo, int copy_data )
00039 : name_( a_histo.name() )
00040 , partition_X_( a_histo.i_partition(0) )
00041 , partition_Y_( a_histo.i_partition(1) )
00042 , bins_( a_histo.bin_count() + a_histo.extra_bin_count() +
00043 a_histo.dim()*a_histo.dim()*(a_histo.dim()-1))
00044 {
00045 if (a_histo.dim() == 2) {
00046 if( copy_data ) {
00047
00048
00049 for( Index i=0; i<Index(bin_count()+extra_bin_count()); i++ )
00050 bins_[i].make( a_histo.i_bin(i) );
00051 }
00052 } else
00053 HTL_ERR("1st argument is not a 2D-histo interface");
00054 }
00055
00056 TEMPLATE___
00057 CLASS___::T_Histo_2D(const I_Histo &a_histo, int copy_data )
00058 : name_( a_histo.name() )
00059 , partition_X_( a_histo.i_partition(0) )
00060 , partition_Y_( a_histo.i_partition(1) )
00061 , bins_( a_histo.bin_count() + a_histo.extra_bin_count() +
00062 a_histo.dim()*a_histo.dim()*(a_histo.dim()-1))
00063 {
00064 if (a_histo.dim() == 2) {
00065 if( copy_data ) {
00066
00067
00068 for( Index i=0; i<Index(bin_count()+extra_bin_count()); i++ )
00069 bins_[i] .make( a_histo.i_bin(i) );
00070 }
00071 } else
00072 HTL_ERR("1st argument is not a 2D-histo interface");
00073 }
00074
00075 TEMPLATE___
00076 I_Bin & CLASS___::i_bin( I_Bin_Location &a_location )
00077 {
00078 if(a_location.size() >= (unsigned long) dim()) {
00079 return (I_Bin &) bin( a_location[0], a_location[1] );
00080 } else {
00081 HTL_ERR("Invalid dimension for location in i_bin(..)");
00082 return (I_Bin &) bin(0, 0 );
00083 }
00084 }
00085
00086 TEMPLATE___
00087 I_Bin & CLASS___::i_bin( I_Bin_Location &a_location ) const
00088 {
00089 if(a_location.size() >= (unsigned long) dim()) {
00090 return (I_Bin &) bin( a_location[0], a_location[1] );
00091 } else {
00092 HTL_ERR("Invalid dimension for location in i_bin(..)");
00093 return (I_Bin &) bin(0, 0 );
00094 }
00095 }
00096
00097 TEMPLATE___
00098 I_Bin & CLASS___::i_bin( Index i )
00099 {
00100 if (i>=0 && i<Index(bin_count()+extra_bin_count())) {
00101 return (I_Bin &) bins_[i];
00102 } else {
00103 HTL_ERR("Invalid index in i_bin( Index i )");
00104 return (I_Bin &) bins_[0];
00105 }
00106 }
00107
00108 TEMPLATE___
00109 I_Bin & CLASS___::i_bin( Index i ) const
00110 {
00111 if (i>=0 && i<Index(bin_count()+extra_bin_count())) {
00112 return (I_Bin &) bins_[i];
00113 } else {
00114 HTL_ERR("Invalid index in i_bin( Index i )");
00115 return (I_Bin &) bins_[0];
00116 }
00117 }
00118
00119 TEMPLATE___
00120 I_Bin & CLASS___::i_extra_bin( I_Extra_Bin_Location &a_location)
00121 {
00122 if(a_location.size() >= (unsigned long) dim()) {
00123 return (I_Bin &) extra_bin( a_location[0], a_location[1]);
00124 } else {
00125 HTL_ERR("Invalid dimension for location in i_extra_bin(..)");
00126 return (I_Bin &) bin(0, 0 );
00127 }
00128 }
00129
00130 TEMPLATE___
00131 I_Bin & CLASS___::i_extra_bin( I_Extra_Bin_Location &a_location) const
00132 {
00133 if(a_location.size() >= (unsigned long) dim()) {
00134 return (I_Bin &) extra_bin( a_location[0], a_location[1] );
00135 } else {
00136 HTL_ERR("Invalid dimension for location in i_extra_bin(..)");
00137 return (I_Bin &) bin(0, 0 );
00138 }
00139 }
00140
00141 TEMPLATE___
00142 I_Partition & CLASS___::i_partition( Index p )
00143 {
00144 if(p>=0 && p<=1) {
00145 switch( p ) {
00146 case 0: return (I_Partition &) partition_X_;
00147 case 1: return (I_Partition &) partition_Y_;
00148 default: break;
00149 }
00150 return (I_Partition &) partition_X_;
00151 } else {
00152 HTL_ERR("Invalid partition index in i_partition(..)");
00153 return (I_Partition &) partition_X_;
00154 }
00155 }
00156
00157 TEMPLATE___
00158 I_Partition & CLASS___::i_partition( Index p ) const
00159 {
00160 if(p>=0 && p<=1) {
00161 switch( p ) {
00162 case 0: return (I_Partition &) partition_X_;
00163 case 1: return (I_Partition &) partition_Y_;
00164 default: break;
00165 }
00166 return (I_Partition &) partition_X_;
00167 } else {
00168 HTL_ERR("Invalid partition index in i_partition(..)");
00169 return (I_Partition &) partition_X_;
00170 }
00171 }
00172
00174
00175
00176 TEMPLATE___
00177 T_Bin & CLASS___::extra_bin( Extra_Index an_ei,Extra_Index an_ej)
00178 {
00179 if(EXTRA_VALID(an_ei) && EXTRA_VALID(an_ej)) {
00180 if ( version() == 0) {
00181
00182 return (T_Bin &) bins_[ bin_count() + EXTRA_VALUE(an_ei) +
00183 EXTRA_VALUE(an_ej) * partition_X().extra_bin_count() ];
00184 } else {
00185
00186 return (T_Bin &) bins_[summaryOUInfo(an_ei,an_ej)];
00187 }
00188 } else {
00189 HTL_ERR("Invalid index in extra_bin(..)");
00190 return (T_Bin &) bins_[ bin_count()];
00191 }
00192 }
00193
00194 TEMPLATE___
00195 T_Bin & CLASS___::extra_bin( Extra_Index an_ei,Extra_Index an_ej ) const
00196 {
00197 if(EXTRA_VALID(an_ei) && EXTRA_VALID(an_ej)) {
00198 if ( version() == 0) {
00199
00200 return (T_Bin &) bins_[ bin_count() + EXTRA_VALUE(an_ei) +
00201 EXTRA_VALUE(an_ej) * partition_X().extra_bin_count() ];
00202 } else {
00203
00204 HTL_ERR("Can't get the extra_bin information in const method");
00205 return (T_Bin &) bins_[ bin_count()];
00206 }
00207 } else {
00208 HTL_ERR("Invalid index in extra_bin(..)");
00209 return (T_Bin &) bins_[ bin_count()];
00210 }
00211 }
00212
00213 TEMPLATE___
00214 void CLASS___::reset()
00215 {
00216 for( Index i=0; i<Index(bin_count()+extra_bin_count()); i++ )
00217 bins_[i] .reset();
00218 }
00219
00220 TEMPLATE___
00221 T_Bin & CLASS___::mapped_bin( T_Point_X x, T_Point_Y y )
00222 {
00223
00224
00225 Index an_index_x;
00226 Extra_Index an_extra_index_x;
00227 partition_X().map_index( x, an_index_x, an_extra_index_x );
00228
00229
00230
00231 Index an_index_y;
00232 Extra_Index an_extra_index_y;
00233 partition_Y().map_index( y, an_index_y, an_extra_index_y );
00234
00235
00236 if( is_in_range( an_extra_index_x, an_extra_index_y ) )
00237 return _bin(an_index_x + an_index_y * partition_X().bin_count());
00238 else
00239 return _bin (bin_count() + realOutRange(an_extra_index_x, an_extra_index_y,
00240 an_index_x , an_index_y));
00241 }
00242
00243 TEMPLATE___
00244 void CLASS___::compute_(const I_Histo &other, binHistoOp &oper)
00245 {
00246 H_BIN_UPDATE;
00247 for( Index i=0; i<Index(bin_count()+extra_bin_count()); i++ )
00248 oper.eval(i_bin(i), other.i_bin(i) );
00249 }
00250
00251 TEMPLATE___
00252 void CLASS___::compute_(double value, binScalarOp &oper)
00253 {
00254 H_BIN_UPDATE;
00255 for( Index i=0; i<Index(bin_count()+extra_bin_count()); i++ )
00256 oper.eval(i_bin(i), value );
00257 }
00258
00259 TEMPLATE___
00260 void CLASS___::add_( const I_Histo &other )
00261 {
00262 if (compatiblePartitions(other,"add_(..)")) {
00263 binHistoAdd operation;
00264 compute_ (other, operation);
00265 }
00266 }
00267
00268 TEMPLATE___
00269 T_REF_I_Histo CLASS___::add1_( const I_Histo &other )
00270 {
00271 add_( other );
00272 return H_T_THIS;
00273 }
00274
00275
00276 TEMPLATE___
00277 void CLASS___::sub_( const I_Histo &other )
00278 {
00279 if (compatiblePartitions(other,"sub_(..)")) {
00280 binHistoSub operation;
00281 compute_ (other, operation);
00282 }
00283 }
00284
00285 TEMPLATE___
00286 T_REF_I_Histo CLASS___::sub1_( const I_Histo &other )
00287 {
00288 sub_( other );
00289 return H_T_THIS;
00290 }
00291
00292
00293 TEMPLATE___
00294 void CLASS___::mul_( const I_Histo &other )
00295 {
00296 if (compatiblePartitions(other,"mul_(..)")) {
00297 binHistoMul operation;
00298 compute_ (other, operation);
00299 }
00300 }
00301
00302 TEMPLATE___
00303 T_REF_I_Histo CLASS___::mul1_( const I_Histo &other )
00304 {
00305 mul_( other );
00306 return H_T_THIS;
00307 }
00308
00309
00310 TEMPLATE___
00311 void CLASS___::div_( const I_Histo &other )
00312 {
00313 if (compatiblePartitions(other,"div_(..)")) {
00314 binHistoDiv operation;
00315 compute_ (other, operation);
00316 }
00317 }
00318
00319 TEMPLATE___
00320 T_REF_I_Histo CLASS___::div1_( const I_Histo &other )
00321 {
00322 div_( other );
00323 return H_T_THIS;
00324 }
00325
00326
00327 TEMPLATE___
00328 void CLASS___::binomial_div_( const I_Histo &other )
00329 {
00330 if (compatiblePartitions(other,"div_(..)")) {
00331 binHistoBinDiv operation;
00332 compute_ (other, operation);
00333 }
00334 }
00335
00336 TEMPLATE___
00337 T_REF_I_Histo CLASS___::binomial_div1_( const I_Histo &other )
00338 {
00339 binomial_div_( other );
00340 return H_T_THIS;
00341 }
00342
00343 TEMPLATE___
00344 void CLASS___::add_( double x )
00345 {
00346 binScalarAdd operation;
00347 compute_ (x,operation );
00348 }
00349
00350 TEMPLATE___
00351 void CLASS___::sub_( double x )
00352 {
00353 binScalarSub operation;
00354 compute_ (x, operation);
00355 }
00356
00357 TEMPLATE___
00358 void CLASS___::mul_( double x )
00359 {
00360 binScalarMul operation;
00361 compute_ (x, operation);
00362 }
00363
00364 TEMPLATE___
00365 void CLASS___::div_( double x )
00366 {
00367 binScalarDiv operation;
00368 compute_ (x, operation);
00369 }
00370
00371 TEMPLATE___
00372 bool CLASS___::compatiblePartitions (const I_Histo &other, const char *oper) {
00373 if( (partition_X().is_compatible_with(((I_Histo &) other).i_partition(0)))
00374 &&(partition_Y().is_compatible_with(((I_Histo &) other).i_partition(1)))){
00375 return true;
00376 } else {
00377 char msg [128];
00378 strcpy (msg, "Incompatible partitions in (..)");
00379 strcat (msg,oper);
00380 HTL_ERR(msg );
00381 return false;
00382 }
00383 }
00384
00389 TEMPLATE___
00390 Index CLASS___::realOutRange( Extra_Index an_ei,Extra_Index an_ej ,
00391 Index an_i, Index an_j) const
00392 {
00393 Index n = partition_X().bin_count();
00394 Index m = partition_Y().bin_count();
00395 if (an_ei == H_UNDERFLOW) {
00396 if (an_ej == H_UNDERFLOW) return 0;
00397 else {
00398 if (an_ej == H_OVERFLOW) return n+n+m+3;
00399 else return n+m+n+3+(m-an_j);
00400 }
00401 } else {
00402 if (an_ei == H_OVERFLOW) {
00403 if (an_ej == H_UNDERFLOW) return n+1;
00404 else {
00405 if (an_ej == H_OVERFLOW) return n+m+2;
00406 else return n+2+an_j;
00407 }
00408 } else {
00409 if (an_ej == H_OVERFLOW)
00410 return n+m+2+(n-an_i);
00411 else
00412 return an_i+1;
00413 }
00414 }
00415
00416 return 0;
00417 }
00418
00422 TEMPLATE___
00423 Index CLASS___::summaryOUInfo( Extra_Index an_ei,Extra_Index an_ej)
00424 {
00425 Index n = partition_X().bin_count();
00426 Index m = partition_Y().bin_count();
00427 if (an_ei == H_UNDERFLOW) {
00428 if (an_ej == H_UNDERFLOW) return bin_count()+0;
00429 else {
00430 if (an_ej == H_OVERFLOW) return bin_count()+n+n+m+3;
00431 else {
00432
00433 return computeSummary(3,n+m+n+4,m);
00434 }
00435 }
00436 } else {
00437 if (an_ei == H_OVERFLOW) {
00438 if (an_ej == H_UNDERFLOW) return bin_count()+n+1;
00439 else {
00440 if (an_ej == H_OVERFLOW) return bin_count()+n+m+2;
00441 else {
00442
00443 return computeSummary(1,n+2,m);
00444 }
00445 }
00446 } else {
00447 if (an_ej == H_OVERFLOW) {
00448
00449 return computeSummary(2,n+m+3,n);
00450 } else {
00451
00452 return computeSummary(0,1,n);
00453 }
00454 }
00455 }
00456
00457 return 0;
00458 }
00459
00460 TEMPLATE___
00461 Index CLASS___::computeSummary( Index which, Index from, Index howMany) {
00462 Index retval = bin_count()+extra_bin_count()+which;
00463 bins_[retval] = bins_[bin_count()+from];
00464 for (Index i = 1; i < howMany; i++) {
00465 bins_[retval].add(bins_[bin_count()+from+i]);
00466 }
00467 return retval;
00468 }
00469
00470 TEMPLATE___
00471 I_Bin & CLASS___::i_any_bin ( I_Bin_Location &a_loc ) const {
00472 if (a_loc.size() >= (unsigned long) dim()) {
00473 if ((a_loc[0] >= 0 ) && (a_loc[1] >= 0))
00474 return i_bin( a_loc );
00475 else {
00476 Extra_Index an_ei = H_IN_RANGE;
00477 Extra_Index an_ej = H_IN_RANGE;
00478 if (a_loc[0] == I_Histo::UNDERFLOW_BIN)
00479 an_ei = H_UNDERFLOW;
00480 else
00481 if (a_loc[0] == I_Histo::OVERFLOW_BIN)
00482 an_ei = H_OVERFLOW;
00483 if (a_loc[1] == I_Histo::UNDERFLOW_BIN)
00484 an_ej = H_UNDERFLOW;
00485 else
00486 if (a_loc[1] == I_Histo::OVERFLOW_BIN)
00487 an_ej = H_OVERFLOW;
00488 return i_bin (bin_count() +
00489 realOutRange(an_ei, an_ej,a_loc[0],a_loc[1]));
00490 }
00491 } else {
00492 HTL_ERR("1st argument is not a 2D-histo interface.");
00493 return (I_Bin &) bin(0,0);
00494 }
00495 }
00496
00497 #undef CLASS___
00498 #undef TEMPLATE___