#include <analysis.h>
Public Member Functions | |
Analysis () | |
bool | analyze (const long double &elem) |
int | converged () |
long double | average () |
long double | half_confidence_interval () |
int | number_iterations () |
void | result () |
long double | value_rohat () |
Protected Member Functions | |
void | calculate_averages (int) |
int | calculate_rohat (int, int x=1) |
long double | calculate_ro (int, int, int) |
void | average_from_to (int, int, int) |
int | check_gamma () |
Private Attributes | |
long double | averages [2][NUM_BATCHES] |
long double | rohat |
int | position_batch [2] |
int | size_batch [2] |
int | batch [2] |
long | samples [2] |
int | iter |
int | converge |
long double | total_average |
long double | numerator_sy2 |
long | Max_samples [2] |
Friends | |
istream & | operator>> (istream &ent, Analysis &anls) |
ostream & | operator<< (ostream &sal, Analysis anls) |
A.M. Law, W. Kelton, Simulation Modeling & Analysis, 2nd ed. McGraw-Hill, 1991.
and fully described in:
A.M. Law, J.S. Carson, “A sequential procedure for determining the length of a steady-state simulation”, Operations Research, vol. 27, no. 5, pp. 1011-1025, 1979.
Definition at line 95 of file analysis.h.
Analysis::Analysis | ( | ) |
Definition at line 27 of file analysis.cc.
00028 { 00029 size_batch[EVEN]=3; 00030 size_batch[ODD]=2; 00031 converge=0; 00032 Max_samples[EVEN]=1200; 00033 Max_samples[ODD]=800; 00034 samples[EVEN]=0; 00035 samples[ODD]=0; 00036 position_batch[EVEN]=0; 00037 position_batch[ODD]=0; 00038 averages[EVEN][0]=0; 00039 averages[ODD][0]=0; 00040 batch[EVEN]=batch[ODD]=0; 00041 total_average=0; 00042 numerator_sy2=0; 00043 iter=0; 00044 }
bool Analysis::analyze | ( | const long double & | elem | ) |
Definition at line 48 of file analysis.cc.
00049 { 00050 // elem is the element to analyze. 00051 // We calculate the averages corresponding to 00052 // even and odd iterations 00053 bool finalized_iteration=0; 00054 long double rohatold; 00055 int end; 00056 averages[EVEN][batch[EVEN]]+=elem; 00057 averages[ODD][batch[ODD]]+=elem; 00058 position_batch[EVEN]+=1; 00059 position_batch[ODD]+=1; 00060 // We check whether we have completed any batch. 00061 if(position_batch[EVEN]==size_batch[EVEN]) { 00062 // We divide by the size of the batch: 00063 averages[EVEN][batch[EVEN]]/=size_batch[EVEN]; 00064 // We increase the batch in one unit 00065 batch[EVEN]+=1; 00066 position_batch[EVEN]=0; 00067 if(batch[EVEN]<NUM_BATCHES) averages[EVEN][batch[EVEN]]=0; // We put this element to 0. 00068 } 00069 if(position_batch[ODD]==size_batch[ODD]) { 00070 averages[ODD][batch[ODD]]/=size_batch[ODD]; 00071 batch[ODD]+=1; 00072 position_batch[ODD]=0; 00073 if(batch[ODD]<NUM_BATCHES) averages[ODD][batch[ODD]]=0; 00074 } 00075 samples[EVEN]+=1; 00076 samples[ODD]+=1; 00077 00078 // We check whether we have reached the maximum number of samples 00079 // that made the block that we are analyzing. 00080 if(samples[EVEN]==Max_samples[EVEN]) { 00081 // End of the batch. 00082 iter++; 00083 calculate_rohat(EVEN); 00084 // The number of samples for the next even iteration is 00085 // twice the current number: 00086 Max_samples[EVEN]*=2; 00087 size_batch[EVEN]=Max_samples[EVEN]/NUM_BATCHES; 00088 calculate_averages(EVEN); // Comment 1. /* <1> */ 00089 // We have to divide by 2 the batch where we are 00090 batch[EVEN]/=2; 00091 averages[EVEN][batch[EVEN]]=0; 00092 // We check the calculated value of the correlation. 00093 if(rohat<=0) { 00094 // If we are below the confidence threshold, everything is OK 00095 if(check_gamma()) { 00096 end=1; 00097 } 00098 else end=0; 00099 } 00100 else { 00101 if(0<rohat && rohat<THRESHOLD) { 00102 // We have to reorganized the array with the averages. 00103 // The first half of the array must contain averages of 2*l samples 00104 // Regarding the second half, it does not matter. 00105 /* <1> */ 00106 // But this operation has to be done for the next even block 00107 // and that is why we do it at the beggining of the check 00108 // and we earn time. Comment 1. 00109 // So, we only have to check the correlation 00110 rohatold=rohat; 00111 calculate_rohat(EVEN,HALF); // But only of the first half 00112 // of the averages. 00113 if(rohat<rohatold && check_gamma()) { 00114 // Confidence threshold, we have finished the task. 00115 end=1; 00116 } 00117 else end=0; 00118 } 00119 else end=0; 00120 } 00121 cout << "Iteration: " << iter << "\n"; 00122 cout << " -> Result: "; result(); cout << "\n"; 00123 finalized_iteration=1; 00124 // If end equals to 1, we have finished the task, 00125 // so that we set converge to 1 and return to the calling program. 00126 if(end) { 00127 converge=1; 00128 return finalized_iteration; 00129 } 00130 } 00131 // Now, exactly the same procedure but for the ODD iteration 00132 if(samples[ODD]==Max_samples[ODD]) { 00133 iter++; 00134 calculate_rohat(ODD); 00135 Max_samples[ODD]*=2; 00136 size_batch[ODD]=Max_samples[ODD]/NUM_BATCHES; 00137 calculate_averages(ODD); 00138 batch[ODD]/=2; 00139 averages[ODD][batch[ODD]]=0; 00140 if(rohat<=0) { 00141 if(check_gamma()) { 00142 end=1; 00143 } 00144 else end=0; 00145 } 00146 else { 00147 if(0<rohat && rohat<THRESHOLD) { 00148 rohatold=rohat; 00149 calculate_rohat(ODD,HALF); 00150 if(rohat<rohatold && check_gamma()) { 00151 end=1; 00152 } 00153 else end=0; 00154 } 00155 else end=0; 00156 } 00157 cout << "Iteration: " << iter << "\n"; 00158 cout << " -> Result: "; result(); cout << "\n"; 00159 finalized_iteration=1; 00160 if(end) { 00161 converge=1; 00162 return finalized_iteration; 00163 } 00164 } 00165 return finalized_iteration; 00166 }
long double Analysis::average | ( | ) | [inline] |
Definition at line 114 of file analysis.h.
00114 {return total_average; } // Returns the average of the parameter
void Analysis::average_from_to | ( | int | iteration, | |
int | from, | |||
int | to | |||
) | [protected] |
Definition at line 233 of file analysis.cc.
00234 { 00235 register int i=0; 00236 total_average=0; 00237 for(i=from;i<to;i++) { 00238 total_average+=averages[iteration][i]; 00239 } 00240 total_average/=(to-from); 00241 }
void Analysis::calculate_averages | ( | int | iteration | ) | [protected] |
Definition at line 168 of file analysis.cc.
00169 { 00170 // The iteration parameter indicates whether we are 00171 // in an EVEN or ODD operation. 00172 register int i; 00173 register int k=0; 00174 // Special case 00175 for(i=0;i<NUM_BATCHES/2;i++) { 00176 // As it can be seen, we go from 2 blocks in 2 blocks 00177 averages[iteration][i]=averages[iteration][k]+averages[iteration][k+1]; 00178 averages[iteration][i]/=2; 00179 k+=2; 00180 } 00181 return; 00182 }
long double Analysis::calculate_ro | ( | int | iteration, | |
int | number_batches, | |||
int | indicator | |||
) | [protected] |
Definition at line 197 of file analysis.cc.
00198 { 00199 int from=0; 00200 int to=number_batches; 00201 long double numerator=0; 00202 long double denominator=0; 00203 long double old=0; 00204 long double aux=0; 00205 register int i; 00206 switch (indicator) { 00207 case 1: 00208 to >>= 1; 00209 break; 00210 case 2: 00211 from = number_batches >> 1; 00212 break; 00213 } 00214 // We introduce in total_average the average value of the averages 00215 // by means of the average_from_to function. 00216 average_from_to(iteration,from,to); 00217 denominator=old=averages[iteration][from]-total_average; 00218 denominator*=denominator; 00219 for(i=from+1;i<=to-1;i++) { 00220 aux=averages[iteration][i]-total_average; 00221 numerator+=old*aux; 00222 denominator+=aux*aux; 00223 old=aux; 00224 } 00225 numerator_sy2=denominator; 00226 if(!denominator) { 00227 return 0; 00228 } 00229 numerator/=denominator; 00230 return numerator; 00231 }
int Analysis::calculate_rohat | ( | int | iteration, | |
int | x = 1 | |||
) | [protected] |
Definition at line 184 of file analysis.cc.
00185 { 00186 // The iteration parameter tells us whether we work with even 00187 // or odd iterations. The which_part parameter tells us 00188 // whether we are going to deal with all the batches (NUM_BATCHES) 00189 // or only with half of them 00190 int number_batches=NUM_BATCHES/which_part; 00191 rohat=-0.5*(calculate_ro(iteration,number_batches,1)+calculate_ro(iteration,number_batches,2))+2*calculate_ro(iteration,number_batches,0); 00192 return 1; 00193 // The imposed order is crution in order to keep the correct value 00194 // of parameters such as total_average 00195 }
int Analysis::check_gamma | ( | ) | [protected] |
Definition at line 243 of file analysis.cc.
00244 { 00245 long double delta; 00246 delta=t_STUDENT*sqrt(numerator_sy2/(NUM_BATCHES*(NUM_BATCHES-1))); 00247 if(total_average==0) { 00248 return 0; // If the total average is 0 we say that it has NOT converged. 00249 // (This is required for evaluating, e.g., low blocking probabilities, 00250 // we force the simulation to continue running even if we have 00251 // a long sequence of samples being 0.) 00252 } 00253 delta/=fabs(total_average); 00254 // We compare delta with the gamma threshold. 00255 if(delta>GAMMA) return 0; 00256 // If we get to this point, the gamma threshold has been exceeded. 00257 return 1; 00258 }
int Analysis::converged | ( | ) | [inline] |
Definition at line 113 of file analysis.h.
00113 {return converge;} // Returns 1 if the analysis of the parameter converged, 0 otherwise.
long double Analysis::half_confidence_interval | ( | ) | [inline] |
Definition at line 115 of file analysis.h.
00115 { 00116 // Returns half confidence interval 00117 // Thus, the result should be expressed as: 00118 // average() +- half_confidence_interval() 00119 return t_STUDENT*sqrt(numerator_sy2/(NUM_BATCHES*(NUM_BATCHES-1))); 00120 }
int Analysis::number_iterations | ( | ) | [inline] |
Definition at line 121 of file analysis.h.
00121 { return iter; } // Returns the number of iterations
void Analysis::result | ( | ) |
Definition at line 260 of file analysis.cc.
00261 { 00262 cout << total_average << "+-" << t_STUDENT*sqrt(numerator_sy2/(NUM_BATCHES*(NUM_BATCHES-1))); 00263 }
long double Analysis::value_rohat | ( | ) | [inline] |
ostream& operator<< | ( | ostream & | sal, | |
Analysis | anls | |||
) | [friend] |
istream& operator>> | ( | istream & | ent, | |
Analysis & | anls | |||
) | [friend] |
long double Analysis::averages[2][NUM_BATCHES] [private] |
Definition at line 97 of file analysis.h.
int Analysis::batch[2] [private] |
Definition at line 102 of file analysis.h.
int Analysis::converge [private] |
Definition at line 105 of file analysis.h.
int Analysis::iter [private] |
Definition at line 104 of file analysis.h.
long Analysis::Max_samples[2] [private] |
Definition at line 108 of file analysis.h.
long double Analysis::numerator_sy2 [private] |
Definition at line 107 of file analysis.h.
int Analysis::position_batch[2] [private] |
Definition at line 100 of file analysis.h.
long double Analysis::rohat [private] |
Definition at line 99 of file analysis.h.
long Analysis::samples[2] [private] |
Definition at line 103 of file analysis.h.
int Analysis::size_batch[2] [private] |
Definition at line 101 of file analysis.h.
long double Analysis::total_average [private] |
Definition at line 106 of file analysis.h.