Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4ConvergenceTester.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 //
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 //
42 
43 #include "G4ConvergenceTester.hh"
44 
46  : n(0), sum(0.), mean(0.), var(0.), sd(0.), r(0.), efficiency(0.),
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), statsAreUpdated(true)
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 );
72 }
73 
74 
75 
77 {
78  delete timer;
79 }
80 
81 
82 
84 {
85 
86  //G4cout << x << G4endl;
87 
88  timer->Stop();
89  cpu_time.push_back( timer->GetSystemElapsed() + timer->GetUserElapsed() );
90 
91  if ( x == 0.0 )
92  {
93  }
94  else
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  // Data has been added so statistics have not been updated to new values
120  statsAreUpdated = false;
121  n++;
122  return;
123 }
124 
125 
126 
127 void G4ConvergenceTester::calStat()
128 {
129 
130 
131  efficiency = double( nonzero_histories.size() ) / n;
132 
133  mean = sum / n;
134 
135  G4double sum_x2 = 0.0;
136  var = 0.0;
137  shift = 0.0;
138  vov = 0.0;
139 
140  G4double xi;
141  std::map< G4int , G4double >::iterator it;
142  for ( it = nonzero_histories.begin() ; it != nonzero_histories.end() ; it++ )
143  {
144  xi = it->second;
145  sum_x2 += xi * xi;
146  var += ( xi - mean ) * ( xi - mean );
147  shift += ( xi - mean ) * ( xi - mean ) * ( xi - mean );
148  vov += ( xi - mean ) * ( xi - mean ) * ( xi - mean ) * ( xi - mean );
149  }
150 
151  var += ( n - nonzero_histories.size() ) * mean * mean;
152  shift += ( n - nonzero_histories.size() ) * mean * mean * mean * ( -1 );
153  vov += ( n - nonzero_histories.size() ) * mean * mean * mean * mean;
154 
155  vov = vov / ( var * var ) - 1.0 / n;
156 
157  var = var/(n-1);
158 
159  sd = std::sqrt ( var );
160 
161  r = sd / mean / std::sqrt ( G4double(n) );
162 
163  r2eff = ( 1 - efficiency ) / ( efficiency * n );
164  r2int = sum_x2 / ( sum * sum ) - 1 / ( efficiency * n );
165 
166  shift = shift / ( 2 * var * n );
167 
168  fom = 1 / (r*r) / cpu_time.back();
169 
170 // Find Largest History
171  //G4double largest = 0.0;
172  largest = 0.0;
173  largest_score_happened = 0;
174  G4double spend_time_of_largest = 0.0;
175  for ( it = nonzero_histories.begin() ; it != nonzero_histories.end() ; it++ )
176  {
177  if ( std::abs ( it->second ) > largest )
178  {
179  largest = it->second;
180  largest_score_happened = it->first;
181  spend_time_of_largest = cpu_time [ it->first+1 ] - cpu_time [ it->first ];
182  }
183  }
184 
185  mean_1 = 0.0;
186  var_1 = 0.0;
187  shift_1 = 0.0;
188  vov_1 = 0.0;
189  sd_1 = 0.0;
190  r_1 = 0.0;
191  vov_1 = 0.0;
192 
193 // G4cout << "The largest history = " << largest << G4endl;
194 
195  mean_1 = ( sum + largest ) / ( n + 1 );
196 
197  for ( it = nonzero_histories.begin() ; it != nonzero_histories.end() ; it++ )
198  {
199  xi = it->second;
200  var_1 += ( xi - mean_1 ) * ( xi - mean_1 );
201  shift_1 += ( xi - mean_1 ) * ( xi - mean_1 ) * ( xi - mean_1 );
202  vov_1 += ( xi - mean_1 ) * ( xi - mean_1 ) * ( xi - mean_1 ) * ( xi - mean_1 );
203  }
204  xi = largest;
205  var_1 += ( xi - mean_1 ) * ( xi - mean_1 );
206  shift_1 += ( xi - mean_1 ) * ( xi - mean_1 ) * ( xi - mean_1 );
207  vov_1 += ( xi - mean_1 ) * ( xi - mean_1 ) * ( xi - mean_1 ) * ( xi - mean_1 );
208 
209  var_1 += ( n - nonzero_histories.size() ) * mean_1 * mean_1;
210  shift_1 += ( n - nonzero_histories.size() ) * mean_1 * mean_1 * mean_1 * ( -1 );
211  vov_1 += ( n - nonzero_histories.size() ) * mean_1 * mean_1 * mean_1 * mean_1;
212 
213  vov_1 = vov_1 / ( var_1 * var_1 ) - 1.0 / ( n + 1 );
214 
215  var_1 = var_1 / n ;
216 
217  sd_1 = std::sqrt ( var_1 );
218 
219  r_1 = sd_1 / mean_1 / std::sqrt ( G4double(n + 1) );
220 
221  shift_1 = shift_1 / ( 2 * var_1 * ( n + 1 ) );
222 
223  fom_1 = 1 / ( r * r ) / ( cpu_time.back() + spend_time_of_largest );
224 
225  if ( nonzero_histories.size() < 500 )
226  {
227  G4cout << "Number of non zero history too small to calculate SLOPE" << G4endl;
228  }
229  else
230  {
231  G4int i = int ( nonzero_histories.size() );
232 
233  // 5% criterion
234  G4int j = int ( i * 0.05 );
235  while ( int( largest_scores.size() ) > j )
236  {
237  largest_scores.pop_back();
238  }
239  calc_slope_fit( largest_scores );
240  }
241 
242  calc_grid_point_of_history();
243  calc_stat_history();
244 
245  // statistics have been calculated and this function does not need
246  // to be called again until data has been added
247  statsAreUpdated = true;
248 }
249 
250 
251 
252 void G4ConvergenceTester::calc_grid_point_of_history()
253 {
254 
255 // histroy_grid [ 0,,,15 ]
256 // history_grid [0] 1/16 ,,, history_grid [15] 16/16
257 // if number of event is x then history_grid [15] become x-1.
258 // 16 -> noBinOfHisotry
259 
260  G4int i;
261  for ( i = 1 ; i <= noBinOfHistory ; i++ )
262  {
263  history_grid [ i-1 ] = int ( n / ( double( noBinOfHistory ) ) * i - 0.1 );
264  //G4cout << "history_grid " << i-1 << " " << history_grid [ i-1 ] << G4endl;
265  }
266 
267 }
268 
269 
270 
271 void G4ConvergenceTester::calc_stat_history()
272 {
273 // G4cout << "i/16 till_ith mean var sd r vov fom shift e r2eff r2int" << G4endl;
274 
275  G4int i;
276  for ( i = 1 ; i <= noBinOfHistory ; i++ )
277  {
278 
279  G4int ith = history_grid [ i-1 ];
280 
281  G4int nonzero_till_ith = 0;
282  G4double xi;
283  G4double mean_till_ith = 0.0;
284  std::map< G4int , G4double >::iterator it;
285 
286  for ( it = nonzero_histories.begin() ; it !=nonzero_histories.end() ; it++ )
287  {
288  if ( it->first <= ith )
289  {
290  xi = it->second;
291  mean_till_ith += xi;
292  nonzero_till_ith++;
293  }
294  }
295 
296  mean_till_ith = mean_till_ith / ( ith+1 );
297  mean_history [ i-1 ] = mean_till_ith;
298 
299  G4double sum_x2_till_ith = 0.0;
300  G4double var_till_ith = 0.0;
301  G4double vov_till_ith = 0.0;
302  G4double shift_till_ith = 0.0;
303 
304  for ( it = nonzero_histories.begin() ; it !=nonzero_histories.end() ; it++ )
305  {
306  if ( it->first <= ith )
307  {
308  xi = it->second;
309  sum_x2_till_ith += xi * xi;
310  var_till_ith += ( xi - mean_till_ith ) * ( xi - mean_till_ith );
311  shift_till_ith += ( xi - mean_till_ith ) * ( xi - mean_till_ith ) * ( xi - mean_till_ith );
312  vov_till_ith += ( xi - mean_till_ith ) * ( xi - mean_till_ith ) * ( xi - mean_till_ith ) * ( xi - mean_till_ith );
313  }
314  }
315 
316  var_till_ith += ( (ith+1) - nonzero_till_ith ) * mean_till_ith * mean_till_ith;
317 
318  vov_till_ith += ( (ith+1) - nonzero_till_ith ) * mean_till_ith * mean_till_ith * mean_till_ith * mean_till_ith ;
319  vov_till_ith = vov_till_ith / ( var_till_ith * var_till_ith ) - 1.0 / (ith+1);
320  vov_history [ i-1 ] = vov_till_ith;
321 
322  var_till_ith = var_till_ith / ( ith+1 - 1 );
323  var_history [ i-1 ] = var_till_ith;
324  sd_history [ i-1 ] = std::sqrt( var_till_ith );
325  r_history [ i-1 ] = std::sqrt( var_till_ith ) / mean_till_ith / std::sqrt ( 1.0*(ith+1) );
326 
327  fom_history [ i-1 ] = 1 / ( r_history [ i-1 ] * r_history [ i-1 ] ) / cpu_time [ ith ];
328 
329  shift_till_ith += ( (ith+1) - nonzero_till_ith ) * mean_till_ith * mean_till_ith * mean_till_ith * ( -1 );
330  shift_till_ith = shift_till_ith / ( 2 * var_till_ith * (ith+1) );
331  shift_history [ i-1 ] = shift_till_ith;
332 
333  e_history [ i-1 ] = 1.0*nonzero_till_ith / (ith+1);
334  r2eff_history [ i-1 ] = ( 1 - e_history [ i-1 ] ) / ( e_history [ i-1 ] * (ith+1) );
335 
336  G4double sum_till_ith = mean_till_ith * (ith+1);
337  r2int_history [ i-1 ] = ( sum_x2_till_ith ) / ( sum_till_ith * sum_till_ith ) - 1 / ( e_history [ i-1 ] * (ith+1) );
338 
339  }
340 
341 }
342 
343 
344 
345 void G4ConvergenceTester::ShowResult(std::ostream& out)
346 {
347  // if data has been added since the last computation of the statistical values (not statsAreUpdated)
348  // call calStat to recompute the statistical values
349  if(!statsAreUpdated) { calStat(); }
350 
351  out << "EFFICIENCY = " << efficiency << G4endl;
352  out << "MEAN = " << mean << G4endl;
353  out << "VAR = " << var << G4endl;
354  out << "SD = " << sd << G4endl;
355  out << "R = "<< r << G4endl;
356  out << "SHIFT = "<< shift << G4endl;
357  out << "VOV = "<< vov << G4endl;
358  out << "FOM = "<< fom << G4endl;
359 
360  out << "THE LARGEST SCORE = " << largest << " and it happend at " << largest_score_happened << "th event" << G4endl;
361  out << "Affected Mean = " << mean_1 << " and its ratio to orignal is " << mean_1/mean << G4endl;
362  out << "Affected VAR = " << var_1 << " and its ratio to orignal is " << var_1/var << G4endl;
363  out << "Affected R = " << r_1 << " and its ratio to orignal is " << r_1/r << G4endl;
364  out << "Affected SHIFT = " << shift_1 << " and its ratio to orignal is " << shift_1/shift << G4endl;
365  out << "Affected FOM = " << fom_1 << " and its ratio to orignal is " << fom_1/fom << G4endl;
366 
367  check_stat_history(out);
368 
369 // check SLOPE and output result
370  if ( slope >= 3 )
371  {
372  noPass++;
373  out << "SLOPE is large enough" << G4endl;
374  }
375  else
376  {
377  out << "SLOPE is not large enough" << G4endl;
378  }
379 
380  out << "This result passes " << noPass << " / "<< noTotal << " Convergence Test." << G4endl;
381  out << G4endl;
382 
383 }
384 
385 void G4ConvergenceTester::ShowHistory(std::ostream& out)
386 {
387  out << "i/" << noBinOfHistory << " till_ith mean var sd r vov fom shift e r2eff r2int" << G4endl;
388  for ( G4int i = 1 ; i <= noBinOfHistory ; i++ )
389  {
390  out << i << " "
391  << history_grid [ i-1 ] << " "
392  << mean_history [ i-1 ] << " "
393  << var_history [ i-1 ] << " "
394  << sd_history [ i-1 ] << " "
395  << r_history [ i-1 ] << " "
396  << vov_history [ i-1 ] << " "
397  << fom_history [ i-1 ] << " "
398  << shift_history [ i-1 ] << " "
399  << e_history [ i-1 ] << " "
400  << r2eff_history [ i-1 ] << " "
401  << r2int_history [ i-1 ] << " "
402  << G4endl;
403  }
404 }
405 
406 void G4ConvergenceTester::check_stat_history(std::ostream& out)
407 {
408 
409 // 1 sigma rejection for null hypothesis
410 
411  std::vector<G4double> first_ally;
412  std::vector<G4double> second_ally;
413 
414 // use 2nd half of hisories
415  G4int N = mean_history.size() / 2;
416  G4int i;
417 
418  G4double pearson_r;
419  G4double t;
420 
421  first_ally.resize( N );
422  second_ally.resize( N );
423 
424 // Mean
425 
426  for ( i = 0 ; i < N ; i++ )
427  {
428  first_ally [ i ] = history_grid [ N + i ];
429  second_ally [ i ] = mean_history [ N + i ];
430  }
431 
432  pearson_r = calc_Pearson_r ( N , first_ally , second_ally );
433  t = pearson_r * std::sqrt ( ( N - 2 ) / ( 1 - pearson_r * pearson_r ) );
434 
435  if ( t < 0.429318 ) // Student t of (Degree of freedom = N-2 )
436  {
437  out << "MEAN distribution is RANDOM" << G4endl;
438  noPass++;
439  }
440  else
441  {
442  out << "MEAN distribution is not RANDOM" << G4endl;
443  }
444 
445 
446 // R
447 
448  for ( i = 0 ; i < N ; i++ )
449  {
450  first_ally [ i ] = 1.0 / std::sqrt ( G4double(history_grid [ N + i ]) );
451  second_ally [ i ] = r_history [ N + i ];
452  }
453 
454  pearson_r = calc_Pearson_r ( N , first_ally , second_ally );
455  t = pearson_r * std::sqrt ( ( N - 2 ) / ( 1 - pearson_r * pearson_r ) );
456 
457  if ( t > 1.090546 )
458  {
459  out << "r follows 1/std::sqrt(N)" << G4endl;
460  noPass++;
461  }
462  else
463  {
464  out << "r does not follow 1/std::sqrt(N)" << G4endl;
465  }
466 
467  if ( is_monotonically_decrease( second_ally ) == true )
468  {
469  out << "r is monotonically decrease " << G4endl;
470  }
471  else
472  {
473  out << "r is NOT monotonically decrease " << G4endl;
474  }
475 
476  if ( r_history.back() < 0.1 )
477  {
478  out << "r is less than 0.1. r = " << r_history.back() << G4endl;
479  noPass++;
480  }
481  else
482  {
483  out << "r is NOT less than 0.1. r = " << r_history.back() << G4endl;
484  }
485 
486 
487 // VOV
488  for ( i = 0 ; i < N ; i++ )
489  {
490  first_ally [ i ] = 1.0 / history_grid [ N + i ];
491  second_ally [ i ] = vov_history [ N + i ];
492  }
493 
494  pearson_r = calc_Pearson_r ( N , first_ally , second_ally );
495  t = pearson_r * std::sqrt ( ( N - 2 ) / ( 1 - pearson_r * pearson_r ) );
496 
497  if ( t > 1.090546 )
498  {
499  out << "VOV follows 1/std::sqrt(N)" << G4endl;
500  noPass++;
501  }
502  else
503  {
504  out << "VOV does not follow 1/std::sqrt(N)" << G4endl;
505  }
506 
507  if ( is_monotonically_decrease( second_ally ) == true )
508  {
509  out << "VOV is monotonically decrease " << G4endl;
510  }
511  else
512  {
513  out << "VOV is NOT monotonically decrease " << G4endl;
514  }
515 
516 // FOM
517 
518  for ( i = 0 ; i < N ; i++ )
519  {
520  first_ally [ i ] = history_grid [ N + i ];
521  second_ally [ i ] = fom_history [ N + i ];
522  }
523 
524  pearson_r = calc_Pearson_r ( N , first_ally , second_ally );
525  t = pearson_r * std::sqrt ( ( N - 2 ) / ( 1 - pearson_r * pearson_r ) );
526 
527  if ( t < 0.429318 )
528  {
529  out << "FOM distribution is RANDOM" << G4endl;
530  noPass++;
531  }
532  else
533  {
534  out << "FOM distribution is not RANDOM" << G4endl;
535  }
536 
537 }
538 
539 
540 
541 G4double G4ConvergenceTester::calc_Pearson_r ( G4int N , std::vector<G4double> first_ally , std::vector<G4double> second_ally )
542 {
543  G4double first_mean = 0.0;
544  G4double second_mean = 0.0;
545 
546  G4int i;
547  for ( i = 0 ; i < N ; i++ )
548  {
549  first_mean += first_ally [ i ];
550  second_mean += second_ally [ i ];
551  }
552  first_mean = first_mean / N;
553  second_mean = second_mean / N;
554 
555  G4double a = 0.0;
556  for ( i = 0 ; i < N ; i++ )
557  {
558  a += ( first_ally [ i ] - first_mean ) * ( second_ally [ i ] - second_mean );
559  }
560 
561  G4double b1 = 0.0;
562  G4double b2 = 0.0;
563  for ( i = 0 ; i < N ; i++ )
564  {
565  b1 += ( first_ally [ i ] - first_mean ) * ( first_ally [ i ] - first_mean );
566  b2 += ( second_ally [ i ] - second_mean ) * ( second_ally [ i ] - second_mean );
567  }
568 
569  G4double rds = a / std::sqrt ( b1 * b2 );
570 
571  return rds;
572 }
573 
574 
575 
576 G4bool G4ConvergenceTester::is_monotonically_decrease ( std::vector<G4double> ally )
577 {
578 
579  std::vector<G4double>::iterator it;
580  for ( it = ally.begin() ; it != ally.end() - 1 ; it++ )
581  {
582  if ( *it < *(it+1) ) return FALSE;
583  }
584 
585  noPass++;
586  return TRUE;
587 }
588 
589 
590 
591 //void G4ConvergenceTester::calc_slope_fit ( std::vector<G4double> largest_socres )
592 void G4ConvergenceTester::calc_slope_fit ( std::vector<G4double> )
593 {
594 
595  // create PDF bins
596  G4double max = largest_scores.front();
597  G4int last = int ( largest_scores.size() );
598  G4double min = 0.0;
599  if ( largest_scores.back() != 0 )
600  {
601  min = largest_scores.back();
602  }
603  else
604  {
605  min = largest_scores[ last-1 ];
606  last = last - 1;
607  }
608 
609  //G4cout << "largest " << max << G4endl;
610  //G4cout << "last " << min << G4endl;
611 
612  if ( max*0.99 < min )
613  {
614  // upper limit is assumed to have been reached
615  slope = 10.0;
616  return;
617  }
618 
619  std::vector < G4double > pdf_grid;
620 
621  pdf_grid.resize( noBinOfPDF+1 ); // no grid = no bins + 1
622  pdf_grid[ 0 ] = max;
623  pdf_grid[ noBinOfPDF ] = min;
624  G4double log10_max = std::log10( max );
625  G4double log10_min = std::log10( min );
626  G4double log10_delta = log10_max - log10_min;
627  for ( G4int i = 1 ; i < noBinOfPDF ; i++ )
628  {
629  pdf_grid[i] = std::pow ( 10.0 , log10_max - log10_delta/10.0*(i) );
630  //G4cout << "pdf i " << i << " " << pdf_grid[i] << G4endl;
631  }
632 
633  std::vector < G4double > pdf;
634  pdf.resize( noBinOfPDF );
635 
636  for ( G4int j=0 ; j < last ; j ++ )
637  {
638  for ( G4int i = 0 ; i < 11 ; i++ )
639  {
640  if ( largest_scores[j] >= pdf_grid[i+1] )
641  {
642  pdf[i] += 1.0 / ( pdf_grid[i] - pdf_grid[i+1] ) / n;
643  //G4cout << "pdf " << j << " " << i << " " << largest_scores[j] << " " << G4endl;
644  break;
645  }
646  }
647  }
648 
649  f_xi.resize( noBinOfPDF );
650  f_yi.resize( noBinOfPDF );
651  for ( G4int i = 0 ; i < noBinOfPDF ; i++ )
652  {
653  //G4cout << "pdf i " << i << " " << (pdf_grid[i]+pdf_grid[i+1])/2 << " " << pdf[i] << G4endl;
654  f_xi[i] = (pdf_grid[i]+pdf_grid[i+1])/2;
655  f_yi[i] = pdf[i];
656  }
657 
658  // number of variables ( a and k )
659  minimizer = new G4SimplexDownhill<G4ConvergenceTester> ( this , 2 );
660  //G4double minimum = minimizer->GetMinimum();
661  std::vector<G4double> mp = minimizer->GetMinimumPoint();
662  G4double k = mp[1];
663 
664  //G4cout << "SLOPE " << 1/mp[1]+1 << G4endl;
665  //G4cout << "SLOPE a " << mp[0] << G4endl;
666  //G4cout << "SLOPE k " << mp[1] << G4endl;
667  //G4cout << "SLOPE minimum " << minimizer->GetMinimum() << G4endl;
668 
669  slope = 1/mp[1]+1;
670  if ( k < 1.0/9 ) // Please look Pareto distribution with "sigma=a" and "k"
671  {
672  slope = 10;
673  }
674  if ( slope > 10 )
675  {
676  slope = 10;
677  }
678 }
679 
680 
681 
682 G4double G4ConvergenceTester::slope_fitting_function ( std::vector< G4double > x )
683 {
684 
685  G4double a = x[0];
686  G4double k = x[1];
687 
688  if ( a <= 0 )
689  {
690  return 3.402823466e+38; // FLOAT_MAX
691  }
692  if ( k == 0 )
693  {
694  return 3.402823466e+38; // FLOAT_MAX
695  }
696 
697 // f_xi and f_yi is filled at "calc_slope_fit"
698 
699  G4double y = 0.0;
700  G4int i;
701  for ( i = 0 ; i < int ( f_yi.size() ) ; i++ )
702  {
703  //if ( 1/a * ( 1 + k * f_xi [ i ] / a ) < 0 )
704  if ( ( 1 + k * f_xi [ i ] / a ) < 0 )
705  {
706  y +=3.402823466e+38; // FLOAT_MAX
707  }
708  else
709  {
710  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 ) );
711  }
712  }
713 // G4cout << "y = " << y << G4endl;
714 
715  return y;
716 }