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