Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/global/HEPNumerics/src/G4ConvergenceTester.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /global/HEPNumerics/src/G4ConvergenceTester.cc (Version 11.3.0) and /global/HEPNumerics/src/G4ConvergenceTester.cc (Version 10.6.p1)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // G4ConvergenceTester class implementation    << 
 27 //                                                 26 //
 28 // Author: Koi, Tatsumi (SLAC/SCCS)            <<  27 //
 29 // ------------------------------------------- <<  28 // Convergence Tests for Monte Carlo results.
                                                   >>  29 //
                                                   >>  30 // Reference
                                                   >>  31 // MCNP(TM) -A General Monte Carlo N-Particle Transport Code
                                                   >>  32 // Version 4B
                                                   >>  33 // Judith F. Briesmeister, Editor
                                                   >>  34 // LA-12625-M, Issued: March 1997, UC 705 and UC 700
                                                   >>  35 // CHAPTER 2. GEOMETRY, DATA, PHYSICS, AND MATHEMATICS
                                                   >>  36 //        VI. ESTIMATION OF THE MONTE CARLO PRECISION
                                                   >>  37 //
                                                   >>  38 // Positives numbers are assumed for inputs
                                                   >>  39 //
                                                   >>  40 // Koi, Tatsumi (SLAC/SCCS)
                                                   >>  41 //
 30                                                    42 
 31 #include "G4ConvergenceTester.hh"                  43 #include "G4ConvergenceTester.hh"
 32 #include "G4AutoLock.hh"                       << 
 33 #include <iomanip>                                 44 #include <iomanip>
 34                                                    45 
 35 namespace                                      <<  46 G4ConvergenceTester::G4ConvergenceTester( G4String theName )
 36 {                                              <<  47  : name(theName), n(0), sum(0.), mean(0.), var(0.), sd(0.), r(0.), efficiency(0.),
 37   G4Mutex aMutex = G4MUTEX_INITIALIZER;        <<  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)
                                                   >>  53 {
                                                   >>  54    nonzero_histories.clear();
                                                   >>  55    largest_scores.clear();
                                                   >>  56    largest_scores.push_back( 0.0 );
                                                   >>  57 
                                                   >>  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 );
                                                   >>  69 
                                                   >>  70    timer = new G4Timer();
                                                   >>  71    timer->Start();
                                                   >>  72    cpu_time.clear();
                                                   >>  73    cpu_time.push_back( 0.0 );
 38 }                                                  74 }
 39                                                    75 
 40 G4ConvergenceTester::G4ConvergenceTester(const <<  76 
 41   : name(theName)                              << 
 42 {                                              << 
 43   nonzero_histories.clear();                   << 
 44   largest_scores.clear();                      << 
 45   largest_scores.push_back(0.0);               << 
 46                                                << 
 47   history_grid.resize(noBinOfHistory, 0);      << 
 48   mean_history.resize(noBinOfHistory, 0.0);    << 
 49   var_history.resize(noBinOfHistory, 0.0);     << 
 50   sd_history.resize(noBinOfHistory, 0.0);      << 
 51   r_history.resize(noBinOfHistory, 0.0);       << 
 52   vov_history.resize(noBinOfHistory, 0.0);     << 
 53   fom_history.resize(noBinOfHistory, 0.0);     << 
 54   shift_history.resize(noBinOfHistory, 0.0);   << 
 55   e_history.resize(noBinOfHistory, 0.0);       << 
 56   r2eff_history.resize(noBinOfHistory, 0.0);   << 
 57   r2int_history.resize(noBinOfHistory, 0.0);   << 
 58                                                << 
 59   timer = new G4Timer();                       << 
 60   timer->Start();                              << 
 61   cpu_time.clear();                            << 
 62   cpu_time.push_back(0.0);                     << 
 63 }                                              << 
 64                                                    77 
 65 G4ConvergenceTester::~G4ConvergenceTester()        78 G4ConvergenceTester::~G4ConvergenceTester()
 66 {                                                  79 {
 67   delete timer;                                <<  80    delete timer;
 68 }                                                  81 }
 69                                                    82 
 70 void G4ConvergenceTester::AddScore(G4double x) << 
 71 {                                              << 
 72   G4AutoLock l(&aMutex);                       << 
 73                                                    83 
 74   timer->Stop();                               << 
 75   cpu_time.push_back(timer->GetSystemElapsed() << 
 76                                                << 
 77   if(x < 0.0)                                  << 
 78   {                                            << 
 79     std::ostringstream message;                << 
 80     message << "Expecting zero or positive num << 
 81             << "but received a negative number << 
 82     G4Exception("G4ConvergenceTester::AddScore << 
 83                 JustWarning, message);         << 
 84   }                                            << 
 85                                                << 
 86   if(x == 0.0)                                 << 
 87   {                                            << 
 88   }                                            << 
 89   else                                         << 
 90   {                                            << 
 91     nonzero_histories.insert(std::pair<G4int,  << 
 92     if(x > largest_scores.back())              << 
 93     {                                          << 
 94       // Following search should become faster << 
 95       for(auto it = largest_scores.begin(); it << 
 96       {                                        << 
 97         if(x > *it)                            << 
 98         {                                      << 
 99           largest_scores.insert(it, x);        << 
100           break;                               << 
101         }                                      << 
102       }                                        << 
103                                                    84 
104       if(largest_scores.size() > 201)          <<  85 void G4ConvergenceTester::AddScore( G4double x )
105       {                                        <<  86 { 
106         largest_scores.pop_back();             << 
107       }                                        << 
108     }                                          << 
109     sum += x;                                  << 
110   }                                            << 
111                                                    87 
112   // Data has been added so statistics have no <<  88    //G4cout << x << G4endl;
113   statsAreUpdated = false;                     <<  89 
114   ++n;                                         <<  90    timer->Stop();
115   l.unlock();                                  <<  91    cpu_time.push_back( timer->GetSystemElapsed() + timer->GetUserElapsed() );
116   return;                                      <<  92 
                                                   >>  93    if ( x < 0.0 ) {
                                                   >>  94       G4cout << "Warning: G4convergenceTester expects zero or positive number as inputs, but received a negative number." << G4endl;
                                                   >>  95    }
                                                   >>  96 
                                                   >>  97    if ( x == 0.0 ) 
                                                   >>  98    { 
                                                   >>  99    }
                                                   >> 100    else
                                                   >> 101    {
                                                   >> 102        nonzero_histories.insert( std::pair< G4int , G4double > ( n , x ) );
                                                   >> 103        if ( x > largest_scores.back() )  
                                                   >> 104        { 
                                                   >> 105 //        Following serch should become faster if begin from bottom.
                                                   >> 106           std::vector< G4double >::iterator it; 
                                                   >> 107           for ( it = largest_scores.begin() ; it != largest_scores.end() ; it++ )
                                                   >> 108           { 
                                                   >> 109              if ( x > *it ) 
                                                   >> 110              { 
                                                   >> 111                 largest_scores.insert( it , x );
                                                   >> 112                 break;
                                                   >> 113              }
                                                   >> 114           }
                                                   >> 115 
                                                   >> 116           if ( largest_scores.size() > 201 )
                                                   >> 117           {
                                                   >> 118              largest_scores.pop_back();
                                                   >> 119           } 
                                                   >> 120           //G4cout << largest_scores.size() << " " << largest_scores.front() << " " << largest_scores.back() << G4endl;
                                                   >> 121        }
                                                   >> 122        sum += x; 
                                                   >> 123    }
                                                   >> 124 
                                                   >> 125     // Data has been added so statistics have not been updated to new values
                                                   >> 126    statsAreUpdated = false;
                                                   >> 127    n++;
                                                   >> 128    return; 
117 }                                                 129 }
118                                                   130 
                                                   >> 131 
                                                   >> 132 
119 void G4ConvergenceTester::calStat()               133 void G4ConvergenceTester::calStat()
120 {                                                 134 {
121   if (n == 0) return;                          << 135     
122                                                << 136    efficiency = double( nonzero_histories.size() ) / n; 
123   efficiency = G4double(nonzero_histories.size << 
124                                                   137 
125   mean = sum / n;                              << 138    mean = sum / n;
                                                   >> 139    
                                                   >> 140    G4double sum_x2 = 0.0; 
                                                   >> 141    var = 0.0;
                                                   >> 142    shift = 0.0;
                                                   >> 143    vov = 0.0;
                                                   >> 144 
                                                   >> 145    G4double xi; 
                                                   >> 146    std::map< G4int , G4double >::iterator it;
                                                   >> 147    for ( it = nonzero_histories.begin() ; it != nonzero_histories.end() ; it++ )
                                                   >> 148    {
                                                   >> 149       xi = it->second;
                                                   >> 150       sum_x2 += xi * xi;
                                                   >> 151       var += ( xi - mean ) * ( xi - mean );
                                                   >> 152       shift += ( xi - mean ) * ( xi - mean ) * ( xi - mean );
                                                   >> 153       vov += ( xi - mean ) * ( xi - mean ) * ( xi - mean ) * ( xi - mean );
                                                   >> 154    }
                                                   >> 155 
                                                   >> 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;
                                                   >> 159 
                                                   >> 160    if ( var!=0.0 ) {
                                                   >> 161 
                                                   >> 162       vov = vov / ( var * var ) - 1.0 / n; 
                                                   >> 163 
                                                   >> 164       var = var/(n-1);
                                                   >> 165 
                                                   >> 166       sd = std::sqrt ( var );
                                                   >> 167 
                                                   >> 168       r = sd / mean / std::sqrt ( G4double(n) ); 
                                                   >> 169 
                                                   >> 170       r2eff = ( 1 - efficiency ) / ( efficiency * n );
                                                   >> 171       r2int = sum_x2 / ( sum * sum ) - 1 / ( efficiency * n );
                                                   >> 172    
                                                   >> 173       shift = shift / ( 2 * var * n );
                                                   >> 174    
                                                   >> 175       fom =  1 / (r*r) / cpu_time.back(); 
                                                   >> 176    }
                                                   >> 177 
                                                   >> 178 // Find Largest History 
                                                   >> 179    //G4double largest = 0.0;
                                                   >> 180    largest = 0.0;
                                                   >> 181    largest_score_happened = 0;
                                                   >> 182    G4double spend_time_of_largest = 0.0;
                                                   >> 183    for ( it = nonzero_histories.begin() ; it != nonzero_histories.end() ; it++ )
                                                   >> 184    {
                                                   >> 185       if ( std::abs ( it->second ) > largest )
                                                   >> 186       {
                                                   >> 187          largest = it->second;
                                                   >> 188          largest_score_happened = it->first;
                                                   >> 189          spend_time_of_largest = cpu_time [ it->first+1 ] - cpu_time [ it->first ];
                                                   >> 190       }
                                                   >> 191    }
126                                                   192 
127   G4double sum_x2 = 0.0;                       << 193    mean_1 = 0.0;
128   var             = 0.0;                       << 194    var_1 = 0.0;
129   shift           = 0.0;                       << 195    shift_1 = 0.0;
130   vov             = 0.0;                       << 196    vov_1 = 0.0;
                                                   >> 197    sd_1 = 0.0;
                                                   >> 198    r_1 = 0.0;
                                                   >> 199    vov_1 = 0.0;
                                                   >> 200 
                                                   >> 201 //   G4cout << "The largest history  = " << largest << G4endl;
                                                   >> 202 
                                                   >> 203    mean_1 = ( sum + largest ) / ( n + 1 );
                                                   >> 204 
                                                   >> 205    for ( it = nonzero_histories.begin() ; it != nonzero_histories.end() ; it++ )
                                                   >> 206    {
                                                   >> 207       xi = it->second;
                                                   >> 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 );
                                                   >> 211    }
                                                   >> 212    xi = largest;
                                                   >> 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 );
                                                   >> 216 
                                                   >> 217    var_1 += ( n - nonzero_histories.size() ) * mean_1 * mean_1;
                                                   >> 218 
                                                   >> 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;
                                                   >> 222 
                                                   >> 223       vov_1 = vov_1 / ( var_1 * var_1 ) - 1.0 / ( n + 1 ); 
                                                   >> 224 
                                                   >> 225       var_1 = var_1 / n ;
                                                   >> 226 
                                                   >> 227       sd_1 = std::sqrt ( var_1 );
                                                   >> 228 
                                                   >> 229       r_1 = sd_1 / mean_1 / std::sqrt ( G4double(n + 1) ); 
                                                   >> 230 
                                                   >> 231       shift_1 = shift_1 / ( 2 * var_1 * ( n + 1 ) );
                                                   >> 232 
                                                   >> 233       fom_1 = 1 / ( r * r ) / ( cpu_time.back() + spend_time_of_largest );
                                                   >> 234    }
                                                   >> 235 
                                                   >> 236    if ( nonzero_histories.size() < 500 ) 
                                                   >> 237    {
                                                   >> 238       calcSLOPE = false;
                                                   >> 239    }
                                                   >> 240    else
                                                   >> 241    {
                                                   >> 242       G4int i = int ( nonzero_histories.size() );
                                                   >> 243 
                                                   >> 244       // 5% criterion
                                                   >> 245       G4int j = int ( i * 0.05 );
                                                   >> 246       while ( int( largest_scores.size() ) > j ) 
                                                   >> 247       {
                                                   >> 248          largest_scores.pop_back();
                                                   >> 249       }
                                                   >> 250       calc_slope_fit( largest_scores );   
                                                   >> 251    }
131                                                   252 
132   G4double xi;                                 << 253    calc_grid_point_of_history();
133   for(const auto& nonzero_historie : nonzero_h << 254    calc_stat_history();
134   {                                            << 255    
135     xi = nonzero_historie.second;              << 256    // statistics have been calculated and this function does not need
136     sum_x2 += xi * xi;                         << 257    // to be called again until data has been added
137     var += (xi - mean) * (xi - mean);          << 258    statsAreUpdated = true;
138     shift += (xi - mean) * (xi - mean) * (xi - << 259 }
139     vov += (xi - mean) * (xi - mean) * (xi - m << 
140   }                                            << 
141                                                   260 
142   var += (n - nonzero_histories.size()) * mean << 
143   shift += (n - nonzero_histories.size()) * me << 
144   vov += (n - nonzero_histories.size()) * mean << 
145                                                   261 
146   if(var != 0.0)                               << 
147   {                                            << 
148     vov = vov / (var * var) - 1.0 / n;         << 
149                                                   262 
150     var = var / (n - 1);                       << 263 void G4ConvergenceTester::calc_grid_point_of_history()
                                                   >> 264 {
151                                                   265 
152     sd = std::sqrt(var);                       << 266 // histroy_grid [ 0,,,15 ] 
                                                   >> 267 // history_grid [0] 1/16 ,,, history_grid [15] 16/16
                                                   >> 268 // if number of event is x then history_grid [15] become x-1. 
                                                   >> 269 // 16 -> noBinOfHisotry
                                                   >> 270 
                                                   >> 271    G4int i;
                                                   >> 272    for ( i = 1 ; i <= noBinOfHistory ; i++ )
                                                   >> 273    { 
                                                   >> 274       history_grid [ i-1 ] = int ( n / ( double( noBinOfHistory ) ) * i - 0.1 );
                                                   >> 275       //G4cout << "history_grid " << i-1  << " " << history_grid [ i-1 ] << G4endl;
                                                   >> 276    }
153                                                   277 
154     r = sd / mean / std::sqrt(G4double(n));    << 278 }
155                                                   279 
156     r2eff = (1 - efficiency) / (efficiency * n << 
157     r2int = sum_x2 / (sum * sum) - 1 / (effici << 
158                                                   280 
159     shift = shift / (2 * var * n);             << 
160                                                   281 
161     fom = 1 / (r * r) / cpu_time.back();       << 282 void G4ConvergenceTester::calc_stat_history()
162   }                                            << 283 {
                                                   >> 284 //   G4cout << "i/16  till_ith  mean  var  sd  r  vov  fom  shift  e  r2eff  r2int" << G4endl;
163                                                   285 
164   // Find Largest History                      << 286     if ( history_grid [ 0 ] == 0 ) {
165   // G4double largest = 0.0;                   << 287         showHistory=false;
166   largest                        = 0.0;        << 288         return;
167   largest_score_happened         = 0;          << 
168   G4double spend_time_of_largest = 0.0;        << 
169   for(const auto& nonzero_historie : nonzero_h << 
170   {                                            << 
171     if(std::abs(nonzero_historie.second) > lar << 
172     {                                          << 
173       largest                = nonzero_histori << 
174       largest_score_happened = nonzero_histori << 
175       spend_time_of_largest =                  << 
176         cpu_time[nonzero_historie.first + 1] - << 
177     }                                             289     }
178   }                                            << 
179                                                   290 
180   mean_1  = 0.0;                               << 291     for (G4int i = 0 ; i < noBinOfHistory; ++i )
181   var_1   = 0.0;                               << 
182   shift_1 = 0.0;                               << 
183   vov_1   = 0.0;                               << 
184   sd_1    = 0.0;                               << 
185   r_1     = 0.0;                               << 
186   vov_1   = 0.0;                               << 
187                                                << 
188   mean_1 = (sum + largest) / (n + 1);          << 
189                                                << 
190   for(const auto& nonzero_historie : nonzero_h << 
191   {                                            << 
192     xi = nonzero_historie.second;              << 
193     var_1 += (xi - mean_1) * (xi - mean_1);    << 
194     shift_1 += (xi - mean_1) * (xi - mean_1) * << 
195     vov_1 += (xi - mean_1) * (xi - mean_1) * ( << 
196   }                                            << 
197   xi = largest;                                << 
198   var_1 += (xi - mean_1) * (xi - mean_1);      << 
199   shift_1 += (xi - mean_1) * (xi - mean_1) * ( << 
200   vov_1 += (xi - mean_1) * (xi - mean_1) * (xi << 
201                                                << 
202   var_1 += (n - nonzero_histories.size()) * me << 
203                                                << 
204   if(var_1 != 0.0)                             << 
205   {                                            << 
206     shift_1 += (n - nonzero_histories.size())  << 
207     vov_1 += (n - nonzero_histories.size()) *  << 
208                                                << 
209     vov_1 = vov_1 / (var_1 * var_1) - 1.0 / (n << 
210                                                << 
211     var_1 = var_1 / n;                         << 
212                                                << 
213     sd_1 = std::sqrt(var_1);                   << 
214                                                << 
215     r_1 = sd_1 / mean_1 / std::sqrt(G4double(n << 
216                                                << 
217     shift_1 = shift_1 / (2 * var_1 * (n + 1)); << 
218                                                << 
219     fom_1 = 1 / (r * r) / (cpu_time.back() + s << 
220   }                                            << 
221                                                << 
222   if(nonzero_histories.size() < 500)           << 
223   {                                            << 
224     calcSLOPE = false;                         << 
225   }                                            << 
226   else                                         << 
227   {                                            << 
228     auto i = G4int(nonzero_histories.size());  << 
229                                                << 
230     // 5% criterion                            << 
231     auto j = G4int(i * 0.05);                  << 
232     while(G4int(largest_scores.size()) > j)    << 
233     {                                             292     {
234       largest_scores.pop_back();               << 
235     }                                          << 
236     calc_slope_fit(largest_scores);            << 
237   }                                            << 
238                                                   293 
239   calc_grid_point_of_history();                << 294         G4int ith = history_grid [ i ];
240   calc_stat_history();                         << 
241                                                   295 
242   // statistics have been calculated and this  << 296         G4int nonzero_till_ith = 0;
243   // to be called again until data has been ad << 297         G4double xi;
244   statsAreUpdated = true;                      << 298         G4double mean_till_ith = 0.0;
245 }                                              << 299         std::map< G4int , G4double >::iterator it;
246                                                   300 
247 void G4ConvergenceTester::calc_grid_point_of_h << 301         for(const auto& itr : nonzero_histories)
248 {                                              << 302         {
249   // histroy_grid [ 0,,,15 ]                   << 303             if( itr.first <= ith )
250   // history_grid [0] 1/16 ,,, history_grid [1 << 304             {
251   // if number of event is x then history_grid << 305                 xi = itr.second;
252   // 16 -> noBinOfHisotry                      << 306                 mean_till_ith += xi;
253                                                << 307                 nonzero_till_ith++;
254   for(G4int i = 1; i <= noBinOfHistory; ++i)   << 308             }
255   {                                            << 309         }
256     history_grid[i - 1] = G4int(n / (G4double( << 
257   }                                            << 
258 }                                              << 
259                                                   310 
260 void G4ConvergenceTester::calc_stat_history()  << 311         if ( nonzero_till_ith == 0 )
261 {                                              << 312             continue;
262   if(history_grid[0] == 0)                     << 
263   {                                            << 
264     showHistory = false;                       << 
265     return;                                    << 
266   }                                            << 
267                                                << 
268   for(G4int i = 0; i < noBinOfHistory; ++i)    << 
269   {                                            << 
270     G4int ith = history_grid[i];               << 
271                                                << 
272     G4int nonzero_till_ith = 0;                << 
273     G4double xi;                               << 
274     G4double mean_till_ith = 0.0;              << 
275                                                   313 
276     for(const auto& itr : nonzero_histories)   << 314         mean_till_ith = mean_till_ith / ( ith+1 );
277     {                                          << 315         mean_history [ i ] = mean_till_ith;
278       if(itr.first <= ith)                     << 
279       {                                        << 
280         xi = itr.second;                       << 
281         mean_till_ith += xi;                   << 
282         ++nonzero_till_ith;                    << 
283       }                                        << 
284     }                                          << 
285                                                   316 
286     if(nonzero_till_ith == 0)                  << 317         G4double sum_x2_till_ith = 0.0;
287     {                                          << 318         G4double var_till_ith = 0.0;
288       continue;                                << 319         G4double vov_till_ith = 0.0;
289     }                                          << 320         G4double shift_till_ith = 0.0;
290                                                << 
291     mean_till_ith   = mean_till_ith / (ith + 1 << 
292     mean_history[i] = mean_till_ith;           << 
293                                                   321 
294     G4double sum_x2_till_ith = 0.0;            << 322         for(const auto& itr : nonzero_histories)
295     G4double var_till_ith    = 0.0;            << 323         {
296     G4double vov_till_ith    = 0.0;            << 324             if ( itr.first <= ith )
297     G4double shift_till_ith  = 0.0;            << 325             {
                                                   >> 326                 xi = itr.second;
                                                   >> 327                 sum_x2_till_ith += std::pow( xi, 2.0 );
                                                   >> 328                 var_till_ith    += std::pow( xi - mean_till_ith, 2.0 ) ;
                                                   >> 329                 shift_till_ith  += std::pow( xi - mean_till_ith, 3.0 );
                                                   >> 330                 vov_till_ith    += std::pow( xi - mean_till_ith, 4.0 );
                                                   >> 331             }
                                                   >> 332         }
298                                                   333 
299     for(const auto& itr : nonzero_histories)   << 334         var_till_ith += ((ith+1) - nonzero_till_ith) * std::pow(mean_till_ith, 2.0);
300     {                                          << 335         vov_till_ith += ((ith+1) - nonzero_till_ith) * std::pow(mean_till_ith, 4.0);
301       if(itr.first <= ith)                     << 
302       {                                        << 
303         xi = itr.second;                       << 
304         sum_x2_till_ith += std::pow(xi, 2.0);  << 
305         var_till_ith += std::pow(xi - mean_til << 
306         shift_till_ith += std::pow(xi - mean_t << 
307         vov_till_ith += std::pow(xi - mean_til << 
308       }                                        << 
309     }                                          << 
310                                                   336 
311     var_till_ith +=                            << 337         G4double sum_till_ith =  mean_till_ith * (ith+1);
312       ((ith + 1) - nonzero_till_ith) * std::po << 
313     vov_till_ith +=                            << 
314       ((ith + 1) - nonzero_till_ith) * std::po << 
315                                                   338 
316     G4double sum_till_ith = mean_till_ith * (i << 339         if(!(std::fabs(var_till_ith) > 0.0))
                                                   >> 340             continue;
                                                   >> 341         if(!(std::fabs(mean_till_ith) > 0.0))
                                                   >> 342             continue;
                                                   >> 343         if(!(std::fabs(sum_till_ith) > 0.0))
                                                   >> 344             continue;
                                                   >> 345 
                                                   >> 346         vov_till_ith = vov_till_ith
                                                   >> 347                        / std::pow( var_till_ith, 2.0 ) - 1.0 / (ith+1);
                                                   >> 348         vov_history [ i ] = vov_till_ith;
                                                   >> 349 
                                                   >> 350         var_till_ith = var_till_ith / ( ith+1 - 1 );
                                                   >> 351         var_history [ i ] = var_till_ith;
                                                   >> 352         sd_history [ i ] = std::sqrt( var_till_ith );
                                                   >> 353         r_history  [ i ] = std::sqrt( var_till_ith )
                                                   >> 354                              / mean_till_ith
                                                   >> 355                              / std::sqrt ( 1.0*(ith+1) );
317                                                   356 
318     if(!(std::fabs(var_till_ith) > 0.0))       << 357         if(std::fabs(cpu_time [ ith ]) > 0.0 && std::fabs(r_history [ i ]) > 0.0)
319     {                                          << 358         {
320       continue;                                << 359             fom_history [ i ] = 1.0
321     }                                          << 360                                   / std::pow( r_history [ i ], 2.0 )
322     if(!(std::fabs(mean_till_ith) > 0.0))      << 361                                   / cpu_time [ ith ];
323     {                                          << 362         }
324       continue;                                << 363         else
325     }                                          << 364         {
326     if(!(std::fabs(sum_till_ith) > 0.0))       << 365             fom_history [ i ] = 0.0;
327     {                                          << 366         }
328       continue;                                << 
329     }                                          << 
330                                                   367 
331     vov_till_ith = vov_till_ith / std::pow(var << 368         shift_till_ith += ((ith+1) - nonzero_till_ith) *
332     vov_history[i] = vov_till_ith;             << 369                           std::pow(mean_till_ith, 3.0) * ( -1.0 );
                                                   >> 370         shift_till_ith = shift_till_ith
                                                   >> 371                          / ( 2 * var_till_ith * (ith+1) );
                                                   >> 372         shift_history [ i ] = shift_till_ith;
                                                   >> 373 
                                                   >> 374         e_history [ i ] = 1.0 * nonzero_till_ith
                                                   >> 375                             / (ith+1);
                                                   >> 376         if(std::fabs(e_history [ i ]) > 0.0)
                                                   >> 377         {
                                                   >> 378             r2eff_history [ i ] = ( 1 - e_history [ i ] )
                                                   >> 379                                     / ( e_history [ i ] * (ith+1) );
333                                                   380 
334     var_till_ith   = var_till_ith / (ith + 1 - << 381             r2int_history [ i ] = ( sum_x2_till_ith )
335     var_history[i] = var_till_ith;             << 382                                     / std::pow( sum_till_ith, 2.0 ) - 1
336     sd_history[i]  = std::sqrt(var_till_ith);  << 383                                     / ( e_history [ i ] * (ith+1) );
337     r_history[i] =                             << 384         }
338       std::sqrt(var_till_ith) / mean_till_ith  << 
339                                                   385 
340     if(std::fabs(cpu_time[ith]) > 0.0 && std:: << 
341     {                                          << 
342       fom_history[i] = 1.0 / std::pow(r_histor << 
343     }                                          << 
344     else                                       << 
345     {                                          << 
346       fom_history[i] = 0.0;                    << 
347     }                                             386     }
348                                                   387 
349     shift_till_ith +=                          << 388 }
350       ((ith + 1) - nonzero_till_ith) * std::po << 
351     shift_till_ith   = shift_till_ith / (2 * v << 
352     shift_history[i] = shift_till_ith;         << 
353                                                   389 
354     e_history[i] = 1.0 * nonzero_till_ith / (i << 
355     if(std::fabs(e_history[i]) > 0.0)          << 
356     {                                          << 
357       r2eff_history[i] = (1 - e_history[i]) /  << 
358                                                   390 
359       r2int_history[i] = (sum_x2_till_ith) / s << 
360                          1 / (e_history[i] * ( << 
361     }                                          << 
362   }                                            << 
363 }                                              << 
364                                                   391 
365 void G4ConvergenceTester::ShowResult(std::ostr    392 void G4ConvergenceTester::ShowResult(std::ostream& out)
366 {                                                 393 {
367   // if data has been added since the last com << 394     // if data has been added since the last computation of the statistical values (not statsAreUpdated)
368   // (not statsAreUpdated) call calStat to rec << 395     // call calStat to recompute the statistical values
369   if(!statsAreUpdated)                         << 396    if(!statsAreUpdated) { calStat(); }
370   {                                            << 397 
371     calStat();                                 << 398    out << std::setprecision( 6 );
372   }                                            << 399 
373                                                << 400    out << G4endl;
374   out << std::setprecision(6);                 << 401    out << "G4ConvergenceTester Output Result of " << name << G4endl;
375                                                << 402    out << std::setw(20) << "EFFICIENCY = " << std::setw(13)  << efficiency << G4endl;
376   out << G4endl;                               << 403    out << std::setw(20) << "MEAN = " << std::setw(13) << mean << G4endl;
377   out << "G4ConvergenceTester Output Result of << 404    out << std::setw(20) << "VAR = " << std::setw(13) << var << G4endl;
378   out << std::setw(20) << "EFFICIENCY = " << s << 405    out << std::setw(20) << "SD = " << std::setw(13) << sd << G4endl;
379       << G4endl;                               << 406    out << std::setw(20) << "R = " << std::setw(13) << r << G4endl;
380   out << std::setw(20) << "MEAN = " << std::se << 407    out << std::setw(20) << "SHIFT = "<< std::setw(13) << shift << G4endl;
381   out << std::setw(20) << "VAR = " << std::set << 408    out << std::setw(20) << "VOV = "<< std::setw(13) << vov << G4endl;
382   out << std::setw(20) << "SD = " << std::setw << 409    out << std::setw(20) << "FOM = "<< std::setw(13) << fom << G4endl;
383   out << std::setw(20) << "R = " << std::setw( << 410 
384   out << std::setw(20) << "SHIFT = " << std::s << 411    out << std::setw(20) << "THE LARGEST SCORE = " << std::setw(13) << largest << " and it happened at " << largest_score_happened << "th event" << G4endl;
385   out << std::setw(20) << "VOV = " << std::set << 412    if ( mean!=0 ) {
386   out << std::setw(20) << "FOM = " << std::set << 413       out << std::setw(20) << "Affected Mean = " << std::setw(13) << mean_1 << " and its ratio to original is " << mean_1/mean << G4endl;
387                                                << 414    } else {
388   out << std::setw(20) << "THE LARGEST SCORE = << 415       out << std::setw(20) << "Affected Mean = " << std::setw(13) << mean_1 << G4endl;
389       << " and it happened at " << largest_sco << 416    }
390       << G4endl;                               << 417    if ( var!=0 ) {
391   if(mean != 0)                                << 418       out << std::setw(20) << "Affected VAR = " << std::setw(13) << var_1 << " and its ratio to original is " << var_1/var << G4endl;
392   {                                            << 419    } else {
393     out << std::setw(20) << "Affected Mean = " << 420       out << std::setw(20) << "Affected VAR = " << std::setw(13) << var_1 << G4endl;
394         << " and its ratio to original is " << << 421    }
395   }                                            << 422    if ( r!=0 ) {
396   else                                         << 423       out << std::setw(20) << "Affected R = " << std::setw(13) << r_1 << " and its ratio to original is " << r_1/r << G4endl;
397   {                                            << 424    } else {
398     out << std::setw(20) << "Affected Mean = " << 425       out << std::setw(20) << "Affected R = " << std::setw(13) << r_1 << G4endl;
399         << G4endl;                             << 426    }
400   }                                            << 427    if ( shift!=0 ) {
401   if(var != 0)                                 << 428       out << std::setw(20) << "Affected SHIFT = " << std::setw(13) << shift_1 << " and its ratio to original is " << shift_1/shift << G4endl;
402   {                                            << 429    } else {
403     out << std::setw(20) << "Affected VAR = "  << 430       out << std::setw(20) << "Affected SHIFT = " << std::setw(13) << shift_1 << G4endl;
404         << " and its ratio to original is " << << 431    }
405   }                                            << 432    if ( fom!=0 ) {
406   else                                         << 433       out << std::setw(20) << "Affected FOM = " << std::setw(13) << fom_1 << " and its ratio to original is " << fom_1/fom << G4endl;
407   {                                            << 434    } else {
408     out << std::setw(20) << "Affected VAR = "  << 435       out << std::setw(20) << "Affected FOM = " << std::setw(13) << fom_1 << G4endl;
409         << G4endl;                             << 436    }
410   }                                            << 437 
411   if(r != 0)                                   << 438    if ( !showHistory ) {
412   {                                            << 439       out << "Number of events of this run is too small to do convergence tests." << G4endl;
413     out << std::setw(20) << "Affected R = " << << 440       return;
414         << " and its ratio to original is " << << 441    }
415   }                                            << 442 
416   else                                         << 443    check_stat_history(out);
417   {                                            << 444 
418     out << std::setw(20) << "Affected R = " << << 445 // check SLOPE and output result
419   }                                            << 446    if ( calcSLOPE ) {
420   if(shift != 0)                               << 447       if ( slope >= 3 )
421   {                                            << 448       {    
422     out << std::setw(20) << "Affected SHIFT =  << 449          noPass++;
423         << " and its ratio to original is " << << 450          out << "SLOPE is large enough" << G4endl; 
424   }                                            << 451       }
425   else                                         << 452       else
426   {                                            << 453       {
427     out << std::setw(20) << "Affected SHIFT =  << 454          out << "SLOPE is not large enough" << G4endl; 
428         << G4endl;                             << 455       }
429   }                                            << 456    } else { 
430   if(fom != 0)                                 << 457       out << "Number of non zero history too small to calculate SLOPE" << G4endl;
431   {                                            << 458    }
432     out << std::setw(20) << "Affected FOM = "  << 459 
433         << " and its ratio to original is " << << 460    out << "This result passes " << noPass << " / "<< noTotal << " Convergence Test." << G4endl; 
434   }                                            << 461    out << G4endl;
435   else                                         << 462 
436   {                                            << 
437     out << std::setw(20) << "Affected FOM = "  << 
438         << G4endl;                             << 
439   }                                            << 
440                                                << 
441   if(!showHistory)                             << 
442   {                                            << 
443     out << "Number of events of this run is to << 
444         << G4endl;                             << 
445     return;                                    << 
446   }                                            << 
447                                                << 
448   check_stat_history(out);                     << 
449                                                << 
450   // check SLOPE and output result             << 
451   if(calcSLOPE)                                << 
452   {                                            << 
453     if(slope >= 3)                             << 
454     {                                          << 
455       noPass++;                                << 
456       out << "SLOPE is large enough" << G4endl << 
457     }                                          << 
458     else                                       << 
459     {                                          << 
460       out << "SLOPE is not large enough" << G4 << 
461     }                                          << 
462   }                                            << 
463   else                                         << 
464   {                                            << 
465     out << "Number of non zero history too sma << 
466   }                                            << 
467                                                << 
468   out << "This result passes " << noPass << "  << 
469       << " Convergence Test." << G4endl;       << 
470   out << G4endl;                               << 
471 }                                                 463 }
472                                                   464 
473 void G4ConvergenceTester::ShowHistory(std::ost    465 void G4ConvergenceTester::ShowHistory(std::ostream& out)
474 {                                                 466 {
475   if(!showHistory)                             << 467 
476   {                                            << 468    if ( !showHistory ) {
477     out << "Number of events of this run is to << 469       out << "Number of events of this run is too small to show history." << G4endl;
478         << G4endl;                             << 470       return;
479     return;                                    << 471    }
480   }                                            << 472    
481                                                << 473    out << std::setprecision( 6 );
482   out << std::setprecision(6);                 << 474 
483                                                << 475    out << G4endl;
484   out << G4endl;                               << 476    out << "G4ConvergenceTester Output History of " << name << G4endl;
485   out << "G4ConvergenceTester Output History o << 477    out << "i/" << noBinOfHistory << " till_ith      mean" 
486   out << "i/" << noBinOfHistory << " till_ith  << 478        << std::setw(13) << "var" 
487       << "var" << std::setw(13) << "sd" << std << 479        << std::setw(13) << "sd" 
488       << "vov" << std::setw(13) << "fom" << st << 480        << std::setw(13) << "r" 
489       << std::setw(13) << "e" << std::setw(13) << 481        << std::setw(13) << "vov" 
490       << "r2int" << G4endl;                    << 482        << std::setw(13) << "fom" 
491   for(G4int i = 1; i <= noBinOfHistory; i++)   << 483        << std::setw(13) << "shift" 
492   {                                            << 484        << std::setw(13) << "e"
493     out << std::setw(4) << i << " " << std::se << 485        << std::setw(13) << "r2eff"
494         << std::setw(13) << mean_history[i - 1 << 486        << std::setw(13) << "r2int" 
495         << var_history[i - 1] << std::setw(13) << 487        << G4endl;
496         << std::setw(13) << r_history[i - 1] < << 488    for ( G4int i = 1 ; i <=  noBinOfHistory  ; i++ )
497         << vov_history[i - 1] << std::setw(13) << 489    {
498         << std::setw(13) << shift_history[i -  << 490       out << std::setw( 4) << i << " " 
499         << e_history[i - 1] << std::setw(13) < << 491           << std::setw( 5) << history_grid [ i-1 ] 
500         << std::setw(13) << r2int_history[i -  << 492           << std::setw(13) << mean_history [ i-1 ] 
501   }                                            << 493           << std::setw(13) << var_history [ i-1 ] 
                                                   >> 494           << std::setw(13) << sd_history [ i-1 ] 
                                                   >> 495           << std::setw(13) << r_history [ i-1 ] 
                                                   >> 496           << std::setw(13) << vov_history [ i-1 ] 
                                                   >> 497           << std::setw(13) << fom_history [ i-1 ] 
                                                   >> 498           << std::setw(13) << shift_history [ i-1 ] 
                                                   >> 499           << std::setw(13) << e_history [ i-1 ] 
                                                   >> 500           << std::setw(13) << r2eff_history [ i-1 ] 
                                                   >> 501           << std::setw(13) << r2int_history [ i-1 ]
                                                   >> 502           << G4endl;
                                                   >> 503    }
502 }                                                 504 }
503                                                   505 
504 void G4ConvergenceTester::check_stat_history(s    506 void G4ConvergenceTester::check_stat_history(std::ostream& out)
505 {                                                 507 {
506   // 1 sigma rejection for null hypothesis     << 
507                                                   508 
508   std::vector<G4double> first_ally;            << 509 // 1 sigma rejection for null hypothesis 
509   std::vector<G4double> second_ally;           << 
510                                                   510 
511   // use 2nd half of hisories                  << 511    std::vector<G4double> first_ally;
512   std::size_t N = mean_history.size() / 2;     << 512    std::vector<G4double> second_ally;
513   std::size_t i;                               << 513 
514                                                << 514 // use 2nd half of hisories
515   G4double pearson_r;                          << 515    G4int N = mean_history.size() / 2;
516   G4double t;                                  << 516    G4int i;
517                                                << 517  
518   first_ally.resize(N);                        << 518    G4double pearson_r;
519   second_ally.resize(N);                       << 519    G4double t;
520                                                << 520 
521   G4double sum_of_var =                        << 521    first_ally.resize( N );
522     std::accumulate(var_history.begin(), var_h << 522    second_ally.resize( N );
523   if(sum_of_var == 0.0)                        << 523 
524   {                                            << 524 // 
525     out << "Variances in all historical grids  << 525    G4double sum_of_var = std::accumulate ( var_history.begin() , var_history.end() , 0.0 );
526     out << "Terminating checking behavior of s << 526    if ( sum_of_var == 0.0 ) {
527     return;                                    << 527       out << "Variances in all historical grids are zero." << G4endl; 
528   }                                            << 528       out << "Terminating checking behavior of statistics numbers." << G4endl; 
529                                                << 529       return;
530   // Mean                                      << 530    }
531                                                << 531 
532   for(i = 0; i < N; ++i)                       << 532 // Mean
533   {                                            << 533 
534     first_ally[i]  = history_grid[N + i];      << 534    for ( i = 0 ; i < N ; i++ ) 
535     second_ally[i] = mean_history[N + i];      << 535    {
536   }                                            << 536       first_ally [ i ] = history_grid [ N + i ];
537                                                << 537       second_ally [ i ] = mean_history [ N + i ];
538   pearson_r = calc_Pearson_r((G4int)N, first_a << 538    }
539   t         = pearson_r * std::sqrt((N - 2) /  << 539 
540                                                << 540    pearson_r = calc_Pearson_r ( N , first_ally , second_ally );
541   if(t < 0.429318)  // Student t of (Degree of << 541    t = pearson_r * std::sqrt ( ( N - 2 ) / ( 1 - pearson_r * pearson_r ) );
542   {                                            << 542 
543     out << "MEAN distribution is  RANDOM" << G << 543    if ( t < 0.429318 ) // Student t of (Degree of freedom = N-2 )  
544     noPass++;                                  << 544    {    
545   }                                            << 545       out << "MEAN distribution is  RANDOM" << G4endl; 
546   else                                         << 546       noPass++;
547   {                                            << 547    }
548     out << "MEAN distribution is not RANDOM" < << 548    else
549   }                                            << 549    {
550                                                << 550       out << "MEAN distribution is not RANDOM" << G4endl; 
551   // R                                         << 551    }
552                                                << 552 
553   for(i = 0; i < N; ++i)                       << 553 
554   {                                            << 554 // R
555     first_ally[i]  = 1.0 / std::sqrt(G4double( << 555 
556     second_ally[i] = r_history[N + i];         << 556    for ( i = 0 ; i < N ; i++ ) 
557   }                                            << 557    {
558                                                << 558       first_ally [ i ] = 1.0 / std::sqrt ( G4double(history_grid [ N + i ]) );
559   pearson_r = calc_Pearson_r(G4int(N), first_a << 559       second_ally [ i ] = r_history [ N + i ];
560   t         = pearson_r * std::sqrt((N - 2) /  << 560    }
561                                                << 561 
562   if(t > 1.090546)                             << 562    pearson_r = calc_Pearson_r ( N , first_ally , second_ally );
563   {                                            << 563    t = pearson_r * std::sqrt ( ( N - 2 ) / ( 1 - pearson_r * pearson_r ) );
564     out << "r follows 1/std::sqrt(N)" << G4end << 564       
565     noPass++;                                  << 565    if ( t > 1.090546 )
566   }                                            << 566    {    
567   else                                         << 567       out << "r follows 1/std::sqrt(N)" << G4endl; 
568   {                                            << 568       noPass++;
569     out << "r does not follow 1/std::sqrt(N)"  << 569    }
570   }                                            << 570    else
571                                                << 571    {
572   if(is_monotonically_decrease(second_ally))   << 572       out << "r does not follow 1/std::sqrt(N)" << G4endl; 
573   {                                            << 573    }
574     out << "r is monotonically decrease " << G << 574 
575   }                                            << 575    if (  is_monotonically_decrease( second_ally ) == true ) 
576   else                                         << 576    {
577   {                                            << 577       out << "r is monotonically decrease " << G4endl;
578     out << "r is NOT monotonically decrease "  << 578    }
579   }                                            << 579    else
580                                                << 580    {
581   if(r_history.back() < 0.1)                   << 581       out << "r is NOT monotonically decrease " << G4endl;
582   {                                            << 582    }
583     out << "r is less than 0.1. r = " << r_his << 583 
584     noPass++;                                  << 584    if ( r_history.back() < 0.1 )  
585   }                                            << 585    {
586   else                                         << 586       out << "r is less than 0.1. r = " <<  r_history.back() << G4endl;
587   {                                            << 587       noPass++;
588     out << "r is NOT less than 0.1. r = " << r << 588    }
589   }                                            << 589    else
590                                                << 590    {
591   // VOV                                       << 591       out << "r is NOT less than 0.1. r = " <<  r_history.back() << G4endl;
592   for(i = 0; i < N; ++i)                       << 592    }
593   {                                            << 593 
594     first_ally[i]  = 1.0 / history_grid[N + i] << 594 
595     second_ally[i] = vov_history[N + i];       << 595 // VOV
596   }                                            << 596    for ( i = 0 ; i < N ; i++ ) 
597                                                << 597    {
598   pearson_r = calc_Pearson_r(G4int(N), first_a << 598       first_ally [ i ] = 1.0 / history_grid [ N + i ];
599   t         = pearson_r * std::sqrt((N - 2) /  << 599       second_ally [ i ] = vov_history [ N + i ];
600                                                << 600    }
601   if(t > 1.090546)                             << 601 
602   {                                            << 602    pearson_r = calc_Pearson_r ( N , first_ally , second_ally );
603     out << "VOV follows 1/std::sqrt(N)" << G4e << 603    t = pearson_r * std::sqrt ( ( N - 2 ) / ( 1 - pearson_r * pearson_r ) );
604     noPass++;                                  << 604       
605   }                                            << 605    if ( t > 1.090546 )
606   else                                         << 606    {    
607   {                                            << 607       out << "VOV follows 1/std::sqrt(N)" << G4endl; 
608     out << "VOV does not follow 1/std::sqrt(N) << 608       noPass++;
609   }                                            << 609    }
610                                                << 610    else
611   if(is_monotonically_decrease(second_ally))   << 611    {
612   {                                            << 612       out << "VOV does not follow 1/std::sqrt(N)" << G4endl; 
613     out << "VOV is monotonically decrease " << << 613    }
614   }                                            << 614 
615   else                                         << 615    if ( is_monotonically_decrease( second_ally ) == true )
616   {                                            << 616    {
617     out << "VOV is NOT monotonically decrease  << 617       out << "VOV is monotonically decrease " << G4endl;
618   }                                            << 618    }
619                                                << 619    else
620   // FOM                                       << 620    {
621                                                << 621       out << "VOV is NOT monotonically decrease " << G4endl;
622   for(i = 0; i < N; ++i)                       << 622    }
623   {                                            << 623 
624     first_ally[i]  = history_grid[N + i];      << 624 // FOM
625     second_ally[i] = fom_history[N + i];       << 625 
626   }                                            << 626    for ( i = 0 ; i < N ; i++ ) 
627                                                << 627    {
628   pearson_r = calc_Pearson_r(G4int(N), std::mo << 628       first_ally [ i ] = history_grid [ N + i ];
629   t         = pearson_r * std::sqrt((N - 2) /  << 629       second_ally [ i ] = fom_history [ N + i ];
630                                                << 630    }
631   if(t < 0.429318)                             << 631 
632   {                                            << 632    pearson_r = calc_Pearson_r ( N , first_ally , second_ally );
633     out << "FOM distribution is RANDOM" << G4e << 633    t = pearson_r * std::sqrt ( ( N - 2 ) / ( 1 - pearson_r * pearson_r ) );
634     noPass++;                                  << 634 
635   }                                            << 635    if ( t < 0.429318 )
636   else                                         << 636    {    
637   {                                            << 637       out << "FOM distribution is RANDOM" << G4endl; 
638     out << "FOM distribution is not RANDOM" << << 638       noPass++;
639   }                                            << 639    }
640 }                                              << 640    else
641                                                << 641    {
642 G4double G4ConvergenceTester::calc_Pearson_r(G << 642       out << "FOM distribution is not RANDOM" << G4endl; 
643                                              s << 643    }
644                                              s << 
645 {                                              << 
646   G4double first_mean  = 0.0;                  << 
647   G4double second_mean = 0.0;                  << 
648                                                << 
649   G4int i;                                     << 
650   for(i = 0; i < N; i++)                       << 
651   {                                            << 
652     first_mean += first_ally[i];               << 
653     second_mean += second_ally[i];             << 
654   }                                            << 
655   first_mean  = first_mean / N;                << 
656   second_mean = second_mean / N;               << 
657                                                << 
658   G4double a = 0.0;                            << 
659   for(i = 0; i < N; ++i)                       << 
660   {                                            << 
661     a += (first_ally[i] - first_mean) * (secon << 
662   }                                            << 
663                                                << 
664   G4double b1 = 0.0;                           << 
665   G4double b2 = 0.0;                           << 
666   for(i = 0; i < N; ++i)                       << 
667   {                                            << 
668     b1 += (first_ally[i] - first_mean) * (firs << 
669     b2 += (second_ally[i] - second_mean) * (se << 
670   }                                            << 
671                                                << 
672   G4double rds = a / std::sqrt(b1 * b2);       << 
673                                                << 
674   return rds;                                  << 
675 }                                              << 
676                                                << 
677 G4bool G4ConvergenceTester::is_monotonically_d << 
678   const std::vector<G4double>& ally)           << 
679 {                                              << 
680   for(auto it = ally.cbegin(); it != ally.cend << 
681   {                                            << 
682     if(*it < *(it + 1))                        << 
683     {                                          << 
684       return FALSE;                            << 
685     }                                          << 
686   }                                            << 
687                                                   644 
688   ++noPass;                                    << 
689   return TRUE;                                 << 
690 }                                                 645 }
691                                                   646 
692 void G4ConvergenceTester::calc_slope_fit(const << 647 
693 {                                              << 648 
694   // create PDF bins                           << 649 G4double G4ConvergenceTester::calc_Pearson_r ( G4int N , std::vector<G4double> first_ally , std::vector<G4double> second_ally )
695   G4double max = largest_scores.front();       << 650 {
696   auto last   = G4int(largest_scores.size());  << 651    G4double first_mean = 0.0;  
697   G4double min = 0.0;                          << 652    G4double second_mean = 0.0;
698   if(largest_scores.back() != 0)               << 653 
699   {                                            << 654    G4int i;
700     min = largest_scores.back();               << 655    for ( i = 0 ; i < N ; i++ )
701   }                                            << 656    {
702   else                                         << 657       first_mean += first_ally [ i ]; 
703   {                                            << 658       second_mean += second_ally [ i ]; 
704     min  = largest_scores[last - 1];           << 659    }
705     last = last - 1;                           << 660    first_mean = first_mean / N;
706   }                                            << 661    second_mean = second_mean / N;
707                                                << 662    
708   if(max * 0.99 < min)                         << 663    G4double a = 0.0; 
709   {                                            << 664    for ( i = 0 ; i < N ; i++ )
710     // upper limit is assumed to have been rea << 665    {
711     slope = 10.0;                              << 666       a += ( first_ally [ i ] - first_mean ) * ( second_ally [ i ] - second_mean );
712     return;                                    << 667    }
713   }                                            << 668 
714                                                << 669    G4double b1 = 0.0; 
715   std::vector<G4double> pdf_grid;              << 670    G4double b2 = 0.0;
716                                                << 671    for ( i = 0 ; i < N ; i++ )
717   pdf_grid.resize(noBinOfPDF + 1);  // no grid << 672    {
718   pdf_grid[0]          = max;                  << 673       b1 += ( first_ally [ i ] - first_mean ) * ( first_ally [ i ] - first_mean );
719   pdf_grid[noBinOfPDF] = min;                  << 674       b2 += ( second_ally [ i ] - second_mean ) * ( second_ally [ i ] - second_mean );
720   G4double log10_max   = std::log10(max);      << 675    }
721   G4double log10_min   = std::log10(min);      << 676    
722   G4double log10_delta = log10_max - log10_min << 677    G4double rds = a / std::sqrt ( b1 * b2 );  
723   for(G4int i = 1; i < noBinOfPDF; ++i)        << 678 
724   {                                            << 679    return rds; 
725     pdf_grid[i] = std::pow(10.0, log10_max - l << 680 }
726   }                                            << 681 
727                                                << 682 
728   std::vector<G4double> pdf;                   << 683 
729   pdf.resize(noBinOfPDF);                      << 684 G4bool G4ConvergenceTester::is_monotonically_decrease ( std::vector<G4double> ally )
730                                                << 685 {
731   for(G4int j = 0; j < last; ++j)              << 686 
732   {                                            << 687    std::vector<G4double>::iterator it;
733     for(G4int i = 0; i < 11; ++i)              << 688    for ( it = ally.begin() ; it != ally.end() - 1 ; it++ )
734     {                                          << 689    {
735       if(largest_scores[j] >= pdf_grid[i + 1]) << 690       if ( *it < *(it+1) ) return FALSE;
                                                   >> 691    }
                                                   >> 692 
                                                   >> 693    noPass++;
                                                   >> 694    return TRUE;
                                                   >> 695 }
                                                   >> 696 
                                                   >> 697 
                                                   >> 698 
                                                   >> 699 //void G4ConvergenceTester::calc_slope_fit ( std::vector<G4double> largest_socres )
                                                   >> 700 void G4ConvergenceTester::calc_slope_fit ( std::vector<G4double> )
                                                   >> 701 {
                                                   >> 702 
                                                   >> 703    // create PDF bins 
                                                   >> 704    G4double max = largest_scores.front();
                                                   >> 705    G4int last = int ( largest_scores.size() );
                                                   >> 706    G4double min = 0.0;
                                                   >> 707    if (  largest_scores.back() !=  0 ) 
                                                   >> 708    {
                                                   >> 709       min = largest_scores.back();
                                                   >> 710    }
                                                   >> 711    else
                                                   >> 712    {
                                                   >> 713       min = largest_scores[ last-1 ];
                                                   >> 714       last = last - 1;
                                                   >> 715    }
                                                   >> 716     
                                                   >> 717    //G4cout << "largest " << max << G4endl;
                                                   >> 718    //G4cout << "last  " << min << G4endl;
                                                   >> 719 
                                                   >> 720    if ( max*0.99 < min )  
                                                   >> 721    {
                                                   >> 722       // upper limit is assumed to have been reached
                                                   >> 723       slope = 10.0;
                                                   >> 724       return;
                                                   >> 725    }
                                                   >> 726 
                                                   >> 727    std::vector < G4double >  pdf_grid;
                                                   >> 728 
                                                   >> 729    pdf_grid.resize( noBinOfPDF+1 );   // no grid  = no bins + 1
                                                   >> 730    pdf_grid[ 0 ] = max; 
                                                   >> 731    pdf_grid[ noBinOfPDF ] = min; 
                                                   >> 732    G4double log10_max = std::log10( max );
                                                   >> 733    G4double log10_min = std::log10( min );
                                                   >> 734    G4double log10_delta = log10_max - log10_min;
                                                   >> 735    for ( G4int i = 1 ; i < noBinOfPDF ; i++ )
                                                   >> 736    {
                                                   >> 737       pdf_grid[i] = std::pow ( 10.0 , log10_max - log10_delta/10.0*(i) );    
                                                   >> 738       //G4cout << "pdf i " << i << " " << pdf_grid[i] << G4endl;
                                                   >> 739    }
                                                   >> 740    
                                                   >> 741    std::vector < G4double >  pdf;
                                                   >> 742    pdf.resize( noBinOfPDF ); 
                                                   >> 743 
                                                   >> 744    for ( G4int j=0 ; j < last ; j ++ )
                                                   >> 745    {
                                                   >> 746       for ( G4int i = 0 ; i < 11 ; i++ )
736       {                                           747       {
737         pdf[i] += 1.0 / (pdf_grid[i] - pdf_gri << 748          if ( largest_scores[j] >= pdf_grid[i+1] )  
738         break;                                 << 749          {
                                                   >> 750             pdf[i] += 1.0 / ( pdf_grid[i] - pdf_grid[i+1] ) / n;
                                                   >> 751             //G4cout << "pdf " << j << " " << i << " " <<  largest_scores[j]  << " " << G4endl;
                                                   >> 752             break;
                                                   >> 753          }
739       }                                           754       }
740     }                                          << 755    }
741   }                                            << 
742                                                   756 
743   f_xi.resize(noBinOfPDF);                     << 757    f_xi.resize( noBinOfPDF );
744   f_yi.resize(noBinOfPDF);                     << 758    f_yi.resize( noBinOfPDF );
745   for(G4int i = 0; i < noBinOfPDF; ++i)        << 759    for ( G4int i = 0 ; i < noBinOfPDF ; i++ )
746   {                                            << 760    {
747     f_xi[i] = (pdf_grid[i] + pdf_grid[i + 1])  << 761       //G4cout << "pdf i " << i << " " <<  (pdf_grid[i]+pdf_grid[i+1])/2 << " " << pdf[i] << G4endl;
748     f_yi[i] = pdf[i];                          << 762       f_xi[i] = (pdf_grid[i]+pdf_grid[i+1])/2;
749   }                                            << 763       f_yi[i] = pdf[i];
750                                                << 764    }
751   // number of variables ( a and k )           << 765 
752   minimizer = new G4SimplexDownhill<G4Converge << 766    //                                                  number of variables ( a and k )  
753   // G4double minimum =  minimizer->GetMinimum << 767    minimizer = new G4SimplexDownhill<G4ConvergenceTester> ( this , 2 ); 
754   std::vector<G4double> mp = minimizer->GetMin << 768    //G4double minimum =  minimizer->GetMinimum();
755   G4double k               = mp[1];            << 769    std::vector<G4double> mp = minimizer->GetMinimumPoint();
756                                                << 770    G4double k = mp[1];
757   // G4cout << "SLOPE " << 1/mp[1]+1 << G4endl << 771 
758   // G4cout << "SLOPE  a " << mp[0] << G4endl; << 772    //G4cout << "SLOPE " << 1/mp[1]+1 << G4endl;
759   // G4cout << "SLOPE  k " << mp[1] << G4endl; << 773    //G4cout << "SLOPE  a " << mp[0] << G4endl;
760   // G4cout << "SLOPE  minimum " << minimizer- << 774    //G4cout << "SLOPE  k " << mp[1] << G4endl;
761                                                << 775    //G4cout << "SLOPE  minimum " << minimizer->GetMinimum() << G4endl;
762   slope = 1 / mp[1] + 1;                       << 776 
763   if(k < 1.0 / 9)  // Please look Pareto distr << 777    slope = 1/mp[1]+1;
764   {                                            << 778    if ( k < 1.0/9 )  // Please look Pareto distribution with "sigma=a" and "k" 
765     slope = 10;                                << 779    {
766   }                                            << 780       slope = 10;
767   if(slope > 10)                               << 781    } 
768   {                                            << 782    if ( slope > 10 ) 
769     slope = 10;                                << 783    {
770   }                                            << 784       slope = 10; 
771 }                                              << 785    }
772                                                << 786 }
773 G4double G4ConvergenceTester::slope_fitting_fu << 787 
774 {                                              << 788 
775   G4double a = x[0];                           << 789 
776   G4double k = x[1];                           << 790 G4double G4ConvergenceTester::slope_fitting_function ( std::vector< G4double > x )
777                                                << 791 {
778   if(a <= 0)                                   << 792 
779   {                                            << 793    G4double a = x[0];
780     return 3.402823466e+38;  // FLOAT_MAX      << 794    G4double k = x[1];
781   }                                            << 795 
782   if(k == 0)                                   << 796    if ( a <= 0 ) 
783   {                                            << 797    {
784     return 3.402823466e+38;  // FLOAT_MAX      << 798       return 3.402823466e+38;  // FLOAT_MAX
785   }                                            << 799    } 
786                                                << 800    if ( k == 0 ) 
787   // f_xi and f_yi is filled at "calc_slope_fi << 801    {
788                                                << 802       return 3.402823466e+38;  // FLOAT_MAX
789   G4double y = 0.0;                            << 803    }
790   for(G4int i = 0; i < G4int(f_yi.size()); ++i << 804 
791   {                                            << 805 // f_xi and f_yi is filled at "calc_slope_fit"
792     // if ( 1/a * ( 1 + k * f_xi [ i ] / a ) < << 806 
793     if((1 + k * f_xi[i] / a) < 0)              << 807    G4double y = 0.0;
794     {                                          << 808    G4int i;
795       y += 3.402823466e+38;  // FLOAT_MAX      << 809    for ( i = 0 ; i < int ( f_yi.size() ) ; i++ )
796     }                                          << 810    {
797     else                                       << 811       //if ( 1/a * ( 1 + k * f_xi [ i ] / a ) < 0 )
798     {                                          << 812       if ( ( 1 + k * f_xi [ i ] / a ) < 0 )
799       y += (f_yi[i] - 1 / a * std::pow(1 + k * << 813       {
800            (f_yi[i] - 1 / a * std::pow(1 + k * << 814          y +=3.402823466e+38;  // FLOAT_MAX 
801     }                                          << 815       }
802   }                                            << 816       else 
                                                   >> 817       {
                                                   >> 818          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 ) );
                                                   >> 819       }
                                                   >> 820    }
                                                   >> 821 //   G4cout << "y = " << y << G4endl;
803                                                   822 
804   return y;                                    << 823    return y;
805 }                                                 824 }
806                                                   825