47  : 
name(theName), 
n(0), sum(0.), mean(0.), var(0.), sd(0.), r(0.), efficiency(0.),
 
   48    r2eff(0.), r2int(0.), shift(0.), vov(0.), fom(0.), largest(0.),
 
   49    largest_score_happened(0), mean_1(0.), var_1(0.), sd_1(0.), r_1(0.),
 
   50    shift_1(0.), vov_1(0.), fom_1(0.), noBinOfHistory(16), slope(0.),
 
   51    noBinOfPDF(10), minimizer(0), noPass(0), noTotal(8), statsAreUpdated(true)
 
   52    , showHistory(true) , calcSLOPE(true)
 
   54    nonzero_histories.clear();
 
   55    largest_scores.clear();
 
   56    largest_scores.push_back( 0.0 );
 
   58    history_grid.resize( noBinOfHistory , 0 );
 
   59    mean_history.resize( noBinOfHistory , 0.0 );
 
   60    var_history.resize( noBinOfHistory , 0.0 );
 
   61    sd_history.resize( noBinOfHistory , 0.0 );
 
   62    r_history.resize( noBinOfHistory , 0.0 );
 
   63    vov_history.resize( noBinOfHistory , 0.0 );
 
   64    fom_history.resize( noBinOfHistory , 0.0 );
 
   65    shift_history.resize( noBinOfHistory , 0.0 );
 
   66    e_history.resize( noBinOfHistory , 0.0 );
 
   67    r2eff_history.resize( noBinOfHistory , 0.0 );
 
   68    r2int_history.resize( noBinOfHistory , 0.0 );
 
   73    cpu_time.push_back( 0.0 );
 
   94       G4cout << 
"Warning: G4convergenceTester expects zero or positive number as inputs, but received a negative number." << 
G4endl;
 
  102        nonzero_histories.insert( std::pair< G4int , G4double > ( n , x ) );
 
  103        if ( x > largest_scores.back() )  
 
  106           std::vector< G4double >::iterator it; 
 
  107           for ( it = largest_scores.begin() ; it != largest_scores.end() ; it++ )
 
  111                 largest_scores.insert( it , x );
 
  116           if ( largest_scores.size() > 201 )
 
  118              largest_scores.pop_back();
 
  126    statsAreUpdated = 
false;
 
  133 void G4ConvergenceTester::calStat()
 
  136    efficiency = double( nonzero_histories.size() ) / n; 
 
  146    std::map< G4int , G4double >::iterator it;
 
  147    for ( it = nonzero_histories.begin() ; it != nonzero_histories.end() ; it++ )
 
  151       var += ( xi - mean ) * ( xi - mean );
 
  152       shift += ( xi - mean ) * ( xi - mean ) * ( xi - mean );
 
  153       vov += ( xi - mean ) * ( xi - mean ) * ( xi - mean ) * ( xi - mean );
 
  156    var += ( n - nonzero_histories.size() ) * mean * mean;
 
  157    shift += ( n - nonzero_histories.size() ) * mean * mean * mean * ( -1 );
 
  158    vov += ( n - nonzero_histories.size() ) * mean * mean * mean * mean;
 
  162       vov = vov / ( var * var ) - 1.0 / n; 
 
  166       sd = std::sqrt ( var );
 
  168       r = sd / mean / std::sqrt ( 
G4double(n) ); 
 
  170       r2eff = ( 1 - efficiency ) / ( efficiency * n );
 
  171       r2int = sum_x2 / ( sum * sum ) - 1 / ( efficiency * n );
 
  173       shift = shift / ( 2 * var * n );
 
  175       fom =  1 / (r*r) / cpu_time.back(); 
 
  181    largest_score_happened = 0;
 
  182    G4double spend_time_of_largest = 0.0;
 
  183    for ( it = nonzero_histories.begin() ; it != nonzero_histories.end() ; it++ )
 
  185       if ( std::abs ( it->second ) > largest )
 
  187          largest = it->second;
 
  188          largest_score_happened = it->first;
 
  189          spend_time_of_largest = cpu_time [ it->first+1 ] - cpu_time [ it->first ];
 
  203    mean_1 = ( sum + largest ) / ( n + 1 );
 
  205    for ( it = nonzero_histories.begin() ; it != nonzero_histories.end() ; it++ )
 
  208       var_1 += ( xi - mean_1 ) * ( xi - mean_1 );
 
  209       shift_1 += ( xi - mean_1 ) * ( xi - mean_1 ) * ( xi - mean_1 );
 
  210       vov_1 += ( xi - mean_1 ) * ( xi - mean_1 ) * ( xi - mean_1 ) * ( xi - mean_1 );
 
  213    var_1 += ( xi - mean_1 ) * ( xi - mean_1 );
 
  214    shift_1 += ( xi - mean_1 ) * ( xi - mean_1 ) * ( xi - mean_1 );
 
  215    vov_1 += ( xi - mean_1 ) * ( xi - mean_1 ) * ( xi - mean_1 ) * ( xi - mean_1 );
 
  217    var_1 += ( n - nonzero_histories.size() ) * mean_1 * mean_1;
 
  219    if ( var_1 != 0.0 ) {
 
  220       shift_1 += ( n - nonzero_histories.size() ) * mean_1 * mean_1 * mean_1 * ( -1 );
 
  221       vov_1 += ( n - nonzero_histories.size() ) * mean_1 * mean_1 * mean_1 * mean_1;
 
  223       vov_1 = vov_1 / ( var_1 * var_1 ) - 1.0 / ( n + 1 ); 
 
  227       sd_1 = std::sqrt ( var_1 );
 
  229       r_1 = sd_1 / mean_1 / std::sqrt ( 
G4double(n + 1) ); 
 
  231       shift_1 = shift_1 / ( 2 * var_1 * ( n + 1 ) );
 
  233       fom_1 = 1 / ( r * r ) / ( cpu_time.back() + spend_time_of_largest );
 
  236    if ( nonzero_histories.size() < 500 ) 
 
  242       G4int i = 
int ( nonzero_histories.size() );
 
  246       while ( 
int( largest_scores.size() ) > j ) 
 
  248          largest_scores.pop_back();
 
  250       calc_slope_fit( largest_scores );   
 
  253    calc_grid_point_of_history();
 
  258    statsAreUpdated = 
true;
 
  263 void G4ConvergenceTester::calc_grid_point_of_history()
 
  272    for ( i = 1 ; i <= noBinOfHistory ; i++ )
 
  274       history_grid [ i-1 ] = 
int ( n / ( 
double( noBinOfHistory ) ) * i - 0.1 );
 
  282 void G4ConvergenceTester::calc_stat_history()
 
  286    if ( history_grid [ 0 ] == 0 ) {
 
  292    for ( i = 1 ; i <=  noBinOfHistory  ; i++ )
 
  295       G4int ith = history_grid [ i-1 ];
 
  297       G4int nonzero_till_ith = 0;
 
  300       std::map< G4int , G4double >::iterator it;
 
  302       for ( it = nonzero_histories.begin() ; it !=nonzero_histories.end() ; it++ )
 
  304          if ( it->first <= ith )
 
  312       if ( nonzero_till_ith == 0 ) 
continue; 
 
  314       mean_till_ith = mean_till_ith / ( ith+1 ); 
 
  315       mean_history [ i-1 ] = mean_till_ith;
 
  322       for ( it = nonzero_histories.begin() ; it !=nonzero_histories.end() ; it++ )
 
  324          if ( it->first <= ith )
 
  327          sum_x2_till_ith += xi * xi; 
 
  328          var_till_ith += ( xi - mean_till_ith ) * ( xi - mean_till_ith );
 
  329          shift_till_ith += ( xi - mean_till_ith ) * ( xi - mean_till_ith ) * ( xi - mean_till_ith );
 
  330          vov_till_ith += ( xi - mean_till_ith ) * ( xi - mean_till_ith ) * ( xi - mean_till_ith ) * ( xi - mean_till_ith );
 
  334       var_till_ith += ( (ith+1) - nonzero_till_ith ) * mean_till_ith * mean_till_ith;
 
  335       vov_till_ith += ( (ith+1) - nonzero_till_ith ) * mean_till_ith * mean_till_ith * mean_till_ith * mean_till_ith ;
 
  338       if ( var_till_ith == 0 ) 
continue; 
 
  339       vov_till_ith = vov_till_ith / ( var_till_ith * var_till_ith ) - 1.0 / (ith+1); 
 
  340       vov_history [ i-1 ] = vov_till_ith;
 
  342       var_till_ith = var_till_ith / ( ith+1 - 1 );
 
  343       var_history [ i-1 ] = var_till_ith;
 
  345       sd_history [ i-1 ] = std::sqrt( var_till_ith );
 
  346       r_history [ i-1 ] = std::sqrt( var_till_ith ) / mean_till_ith / std::sqrt ( 1.0*(ith+1) );
 
  348       fom_history [ i-1 ] = 1 / ( r_history [ i-1 ] *  r_history [ i-1 ] ) / cpu_time [ ith ];
 
  350       shift_till_ith += ( (ith+1) - nonzero_till_ith ) * mean_till_ith * mean_till_ith * mean_till_ith * ( -1 );
 
  351       shift_till_ith = shift_till_ith / ( 2 * var_till_ith * (ith+1) );
 
  352       shift_history [ i-1 ] = shift_till_ith;
 
  354       e_history [ i-1 ] = 1.0*nonzero_till_ith / (ith+1);
 
  355       r2eff_history [ i-1 ] = ( 1 - e_history [ i-1 ] ) / (  e_history [ i-1 ] * (ith+1) );
 
  357       G4double sum_till_ith =  mean_till_ith * (ith+1); 
 
  358       r2int_history [ i-1 ] = ( sum_x2_till_ith ) / ( sum_till_ith * sum_till_ith ) - 1 / ( e_history [ i-1 ] * (ith+1) );
 
  370    if(!statsAreUpdated) { calStat(); }
 
  372    out << std::setprecision( 6 );
 
  375    out << 
"G4ConvergenceTester Output Result of " << 
name << 
G4endl;
 
  376    out << std::setw(20) << 
"EFFICIENCY = " << std::setw(13)  << efficiency << 
G4endl;
 
  377    out << std::setw(20) << 
"MEAN = " << std::setw(13) << mean << 
G4endl;
 
  378    out << std::setw(20) << 
"VAR = " << std::setw(13) << var << 
G4endl;
 
  379    out << std::setw(20) << 
"SD = " << std::setw(13) << sd << 
G4endl;
 
  380    out << std::setw(20) << 
"R = " << std::setw(13) << r << 
G4endl;
 
  381    out << std::setw(20) << 
"SHIFT = "<< std::setw(13) << shift << 
G4endl;
 
  382    out << std::setw(20) << 
"VOV = "<< std::setw(13) << vov << 
G4endl;
 
  383    out << std::setw(20) << 
"FOM = "<< std::setw(13) << fom << 
G4endl;
 
  385    out << std::setw(20) << 
"THE LARGEST SCORE = " << std::setw(13) << largest << 
" and it happend at " << largest_score_happened << 
"th event" << 
G4endl;
 
  387       out << std::setw(20) << 
"Affected Mean = " << std::setw(13) << mean_1 << 
" and its ratio to orignal is " << mean_1/mean << 
G4endl;
 
  389       out << std::setw(20) << 
"Affected Mean = " << std::setw(13) << mean_1 << 
G4endl;
 
  392       out << std::setw(20) << 
"Affected VAR = " << std::setw(13) << var_1 << 
" and its ratio to orignal is " << var_1/var << 
G4endl;
 
  394       out << std::setw(20) << 
"Affected VAR = " << std::setw(13) << var_1 << 
G4endl;
 
  397       out << std::setw(20) << 
"Affected R = " << std::setw(13) << r_1 << 
" and its ratio to orignal is " << r_1/r << 
G4endl;
 
  399       out << std::setw(20) << 
"Affected R = " << std::setw(13) << r_1 << 
G4endl;
 
  402       out << std::setw(20) << 
"Affected SHIFT = " << std::setw(13) << shift_1 << 
" and its ratio to orignal is " << shift_1/shift << 
G4endl;
 
  404       out << std::setw(20) << 
"Affected SHIFT = " << std::setw(13) << shift_1 << 
G4endl;
 
  407       out << std::setw(20) << 
"Affected FOM = " << std::setw(13) << fom_1 << 
" and its ratio to orignal is " << fom_1/fom << 
G4endl;
 
  409       out << std::setw(20) << 
"Affected FOM = " << std::setw(13) << fom_1 << 
G4endl;
 
  412    if ( !showHistory ) {
 
  413       out << 
"Number of events of this run is too small to do convergence tests." << 
G4endl;
 
  417    check_stat_history(out);
 
  424          out << 
"SLOPE is large enough" << 
G4endl; 
 
  428          out << 
"SLOPE is not large enough" << 
G4endl; 
 
  431       out << 
"Number of non zero history too small to calculate SLOPE" << 
G4endl;
 
  434    out << 
"This result passes " << noPass << 
" / "<< noTotal << 
" Convergence Test." << 
G4endl; 
 
  442    if ( !showHistory ) {
 
  443       out << 
"Number of events of this run is too small to show history." << 
G4endl;
 
  447    out << std::setprecision( 6 );
 
  450    out << 
"G4ConvergenceTester Output History of " << 
name << 
G4endl;
 
  451    out << 
"i/" << noBinOfHistory << 
" till_ith      mean"  
  452        << std::setw(13) << 
"var"  
  453        << std::setw(13) << 
"sd"  
  454        << std::setw(13) << 
"r"  
  455        << std::setw(13) << 
"vov"  
  456        << std::setw(13) << 
"fom"  
  457        << std::setw(13) << 
"shift"  
  458        << std::setw(13) << 
"e" 
  459        << std::setw(13) << 
"r2eff" 
  460        << std::setw(13) << 
"r2int"  
  462    for ( 
G4int i = 1 ; i <=  noBinOfHistory  ; i++ )
 
  464       out << std::setw( 4) << i << 
" "  
  465           << std::setw( 5) << history_grid [ i-1 ] 
 
  466           << std::setw(13) << mean_history [ i-1 ] 
 
  467           << std::setw(13) << var_history [ i-1 ] 
 
  468           << std::setw(13) << sd_history [ i-1 ] 
 
  469           << std::setw(13) << r_history [ i-1 ] 
 
  470           << std::setw(13) << vov_history [ i-1 ] 
 
  471           << std::setw(13) << fom_history [ i-1 ] 
 
  472           << std::setw(13) << shift_history [ i-1 ] 
 
  473           << std::setw(13) << e_history [ i-1 ] 
 
  474           << std::setw(13) << r2eff_history [ i-1 ] 
 
  475           << std::setw(13) << r2int_history [ i-1 ]
 
  480 void G4ConvergenceTester::check_stat_history(std::ostream& out)
 
  485    std::vector<G4double> first_ally;
 
  486    std::vector<G4double> second_ally;
 
  489    G4int N = mean_history.size() / 2;
 
  495    first_ally.resize( N );
 
  496    second_ally.resize( N );
 
  499    G4double sum_of_var = std::accumulate ( var_history.begin() , var_history.end() , 0.0 );
 
  500    if ( sum_of_var == 0.0 ) {
 
  501       out << 
"Variances in all historical grids are zero." << 
G4endl; 
 
  502       out << 
"Terminating checking behavior of statistics numbers." << 
G4endl; 
 
  508    for ( i = 0 ; i < 
N ; i++ ) 
 
  510       first_ally [ i ] = history_grid [ N + i ];
 
  511       second_ally [ i ] = mean_history [ N + i ];
 
  514    pearson_r = calc_Pearson_r ( N , first_ally , second_ally );
 
  515    t = pearson_r * std::sqrt ( ( N - 2 ) / ( 1 - pearson_r * pearson_r ) );
 
  519       out << 
"MEAN distribution is  RANDOM" << 
G4endl; 
 
  524       out << 
"MEAN distribution is not RANDOM" << 
G4endl; 
 
  530    for ( i = 0 ; i < 
N ; i++ ) 
 
  532       first_ally [ i ] = 1.0 / std::sqrt ( 
G4double(history_grid [ N + i ]) );
 
  533       second_ally [ i ] = r_history [ N + i ];
 
  536    pearson_r = calc_Pearson_r ( N , first_ally , second_ally );
 
  537    t = pearson_r * std::sqrt ( ( N - 2 ) / ( 1 - pearson_r * pearson_r ) );
 
  541       out << 
"r follows 1/std::sqrt(N)" << 
G4endl; 
 
  546       out << 
"r does not follow 1/std::sqrt(N)" << 
G4endl; 
 
  549    if (  is_monotonically_decrease( second_ally ) == 
true ) 
 
  551       out << 
"r is monotonically decrease " << 
G4endl;
 
  555       out << 
"r is NOT monotonically decrease " << 
G4endl;
 
  558    if ( r_history.back() < 0.1 )  
 
  560       out << 
"r is less than 0.1. r = " <<  r_history.back() << 
G4endl;
 
  565       out << 
"r is NOT less than 0.1. r = " <<  r_history.back() << 
G4endl;
 
  570    for ( i = 0 ; i < 
N ; i++ ) 
 
  572       first_ally [ i ] = 1.0 / history_grid [ N + i ];
 
  573       second_ally [ i ] = vov_history [ N + i ];
 
  576    pearson_r = calc_Pearson_r ( N , first_ally , second_ally );
 
  577    t = pearson_r * std::sqrt ( ( N - 2 ) / ( 1 - pearson_r * pearson_r ) );
 
  581       out << 
"VOV follows 1/std::sqrt(N)" << 
G4endl; 
 
  586       out << 
"VOV does not follow 1/std::sqrt(N)" << 
G4endl; 
 
  589    if ( is_monotonically_decrease( second_ally ) == 
true )
 
  591       out << 
"VOV is monotonically decrease " << 
G4endl;
 
  595       out << 
"VOV is NOT monotonically decrease " << 
G4endl;
 
  600    for ( i = 0 ; i < 
N ; i++ ) 
 
  602       first_ally [ i ] = history_grid [ N + i ];
 
  603       second_ally [ i ] = fom_history [ N + i ];
 
  606    pearson_r = calc_Pearson_r ( N , first_ally , second_ally );
 
  607    t = pearson_r * std::sqrt ( ( N - 2 ) / ( 1 - pearson_r * pearson_r ) );
 
  611       out << 
"FOM distribution is RANDOM" << 
G4endl; 
 
  616       out << 
"FOM distribution is not RANDOM" << 
G4endl; 
 
  623 G4double G4ConvergenceTester::calc_Pearson_r ( 
G4int N , std::vector<G4double> first_ally , std::vector<G4double> second_ally )
 
  629    for ( i = 0 ; i < 
N ; i++ )
 
  631       first_mean += first_ally [ i ]; 
 
  632       second_mean += second_ally [ i ]; 
 
  634    first_mean = first_mean / 
N;
 
  635    second_mean = second_mean / 
N;
 
  638    for ( i = 0 ; i < 
N ; i++ )
 
  640       a += ( first_ally [ i ] - first_mean ) * ( second_ally [ i ] - second_mean );
 
  645    for ( i = 0 ; i < 
N ; i++ )
 
  647       b1 += ( first_ally [ i ] - first_mean ) * ( first_ally [ i ] - first_mean );
 
  648       b2 += ( second_ally [ i ] - second_mean ) * ( second_ally [ i ] - second_mean );
 
  651    G4double rds = a / std::sqrt ( b1 * b2 );  
 
  658 G4bool G4ConvergenceTester::is_monotonically_decrease ( std::vector<G4double> ally )
 
  661    std::vector<G4double>::iterator it;
 
  662    for ( it = ally.begin() ; it != ally.end() - 1 ; it++ )
 
  664       if ( *it < *(it+1) ) 
return FALSE;
 
  674 void G4ConvergenceTester::calc_slope_fit ( std::vector<G4double> )
 
  679    G4int last = 
int ( largest_scores.size() );
 
  681    if (  largest_scores.back() !=  0 ) 
 
  683       min = largest_scores.back();
 
  687       min = largest_scores[ last-1 ];
 
  694    if ( max*0.99 < min )  
 
  701    std::vector < G4double >  pdf_grid;
 
  703    pdf_grid.resize( noBinOfPDF+1 );   
 
  705    pdf_grid[ noBinOfPDF ] = 
min; 
 
  706    G4double log10_max = std::log10( max );
 
  707    G4double log10_min = std::log10( min );
 
  708    G4double log10_delta = log10_max - log10_min;
 
  709    for ( 
G4int i = 1 ; i < noBinOfPDF ; i++ )
 
  711       pdf_grid[i] = std::pow ( 10.0 , log10_max - log10_delta/10.0*(i) );    
 
  715    std::vector < G4double >  pdf;
 
  716    pdf.resize( noBinOfPDF ); 
 
  718    for ( 
G4int j=0 ; j < last ; j ++ )
 
  720       for ( 
G4int i = 0 ; i < 11 ; i++ )
 
  722          if ( largest_scores[j] >= pdf_grid[i+1] )  
 
  724             pdf[i] += 1.0 / ( pdf_grid[i] - pdf_grid[i+1] ) / n;
 
  731    f_xi.resize( noBinOfPDF );
 
  732    f_yi.resize( noBinOfPDF );
 
  733    for ( 
G4int i = 0 ; i < noBinOfPDF ; i++ )
 
  736       f_xi[i] = (pdf_grid[i]+pdf_grid[i+1])/2;
 
  764 G4double G4ConvergenceTester::slope_fitting_function ( std::vector< G4double > 
x )
 
  772       return 3.402823466e+38;  
 
  776       return 3.402823466e+38;  
 
  783    for ( i = 0 ; i < 
int ( f_yi.size() ) ; i++ )
 
  786       if ( ( 1 + k * f_xi [ i ] / a ) < 0 )
 
  792          y += ( f_yi [ i ] - 1/a*std::pow (  1 + k * f_xi [ i ] / a , - 1/k - 1 ) ) * ( f_yi [ i ] - 1/a*std::pow ( 1 + k * f_xi [ i ] / a , - 1/k - 1 ) );
 
G4double GetSystemElapsed() const 
 
std::vector< ExP01TrackerHit * > a
 
G4GLOB_DLL std::ostream G4cout
 
std::vector< G4double > GetMinimumPoint()
 
G4double GetUserElapsed() const 
 
typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData)
 
void ShowHistory(std::ostream &out=G4cout)
 
T max(const T t1, const T t2)
brief Return the largest of the two arguments 
 
T min(const T t1, const T t2)
brief Return the smallest of the two arguments 
 
void ShowResult(std::ostream &out=G4cout)
 
G4ConvergenceTester(G4String theName="NONAME")