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 11.1)


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