00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <NormalRV.h>
00035 #include <math.h>
00036 #include <string.h>
00037 #include <classTags.h>
00038 #include <OPS_Globals.h>
00039
00040 NormalRV::NormalRV(int passedTag,
00041 double passedMean,
00042 double passedStdv,
00043 double passedStartValue)
00044 :RandomVariable(passedTag, RANDOM_VARIABLE_normal)
00045 {
00046 tag = passedTag ;
00047 mju = passedMean;
00048 sigma = passedStdv;
00049 startValue = passedStartValue;
00050 }
00051 NormalRV::NormalRV(int passedTag,
00052 double passedParameter1,
00053 double passedParameter2,
00054 double passedParameter3,
00055 double passedParameter4,
00056 double passedStartValue)
00057 :RandomVariable(passedTag, RANDOM_VARIABLE_normal)
00058 {
00059 tag = passedTag ;
00060 mju = passedParameter1;
00061 sigma = passedParameter2;
00062 startValue = passedStartValue;
00063 }
00064 NormalRV::NormalRV(int passedTag,
00065 double passedMean,
00066 double passedStdv)
00067 :RandomVariable(passedTag, RANDOM_VARIABLE_normal)
00068 {
00069 tag = passedTag ;
00070 mju = passedMean;
00071 sigma = passedStdv;
00072 startValue = getMean();
00073 }
00074 NormalRV::NormalRV(int passedTag,
00075 double passedParameter1,
00076 double passedParameter2,
00077 double passedParameter3,
00078 double passedParameter4)
00079 :RandomVariable(passedTag, RANDOM_VARIABLE_normal)
00080 {
00081 tag = passedTag ;
00082 mju = passedParameter1;
00083 sigma = passedParameter2;
00084 startValue = getMean();
00085 }
00086
00087
00088 NormalRV::~NormalRV()
00089 {
00090 }
00091
00092
00093 void
00094 NormalRV::Print(OPS_Stream &s, int flag)
00095 {
00096 }
00097
00098
00099 double
00100 NormalRV::getPDFvalue(double rvValue)
00101 {
00102 double pi = 3.14159265358979;
00103 return 1 / sqrt ( 2.0 * pi ) * exp ( - 0.5 * pow ( ( ( rvValue - mju ) / sigma ), 2.0 ) );
00104 }
00105
00106
00107 double
00108 NormalRV::getCDFvalue(double rvValue)
00109 {
00110 double result = 0.5 + errorFunction( ((rvValue-mju)/sigma)/sqrt(2.0) )/2.0;
00111 return result;
00112 }
00113
00114
00115 double
00116 NormalRV::getInverseCDFvalue(double probValue)
00117 {
00118 if (probValue < 0.0 || probValue > 1.0) {
00119 opserr << "WARNING: Illegal probability value input to NormalRV::getInverseCDFvalue()" << endln;
00120 }
00121 double result = getMean() + getStdv() * sqrt(2.0) * inverseErrorFunction(2*probValue-1.0);
00122 return result;
00123 }
00124
00125
00126 const char *
00127 NormalRV::getType()
00128 {
00129 return "NORMAL";
00130 }
00131
00132
00133 double
00134 NormalRV::getMean()
00135 {
00136 return mju;
00137 }
00138
00139
00140
00141 double
00142 NormalRV::getStdv()
00143 {
00144 return sigma;
00145 }
00146
00147
00148 double
00149 NormalRV::getStartValue()
00150 {
00151 return startValue;
00152 }
00153
00154 double NormalRV::getParameter1() {return mju;}
00155 double NormalRV::getParameter2() {return sigma;}
00156 double NormalRV::getParameter3() {opserr<<"No such parameter in r.v. #"<<tag<<endln; return 0.0;}
00157 double NormalRV::getParameter4() {opserr<<"No such parameter in r.v. #"<<tag<<endln; return 0.0;}
00158
00159
00160 double
00161 NormalRV::errorFunction(double x)
00162 {
00163
00164
00165
00166 double a1,a2,a3,a4,a5;
00167 double b1,b2,b3,b4;
00168 double c1,c2,c3,c4,c5,c6,c7,c8,c9;
00169 double d1,d2,d3,d4,d5,d6,d7,d8;
00170 double p1,p2,p3,p4,p5,p6;
00171 double q1,q2,q3,q4,q5;
00172 double y,z,xnum,xden,del,result;
00173 double pi = 3.14159265358979;
00174
00175
00176
00177 if ( fabs(x) <= 0.46875 )
00178 {
00179 a1 = 3.16112374387056560e00;
00180 a2 = 1.13864154151050156e02;
00181 a3 = 3.77485237685302021e02;
00182 a4 = 3.20937758913846947e03;
00183 a5 = 1.85777706184603153e-1;
00184 b1 = 2.36012909523441209e01;
00185 b2 = 2.44024637934444173e02;
00186 b3 = 1.28261652607737228e03;
00187 b4 = 2.84423683343917062e03;
00188 y = fabs(x);
00189 z = y * y;
00190 xnum = a5 * z;
00191 xden = z;
00192 xnum = (xnum + a1) * z;
00193 xden = (xden + b1) * z;
00194 xnum = (xnum + a2) * z;
00195 xden = (xden + b2) * z;
00196 xnum = (xnum + a3) * z;
00197 xden = (xden + b3) * z;
00198 result = x * (xnum + a4) / (xden + b4);
00199 }
00200
00201
00202
00203 else if ( fabs(x) > 0.46875 && fabs(x) <= 4.0 )
00204 {
00205 c1 = 5.64188496988670089e-1;
00206 c2 = 8.88314979438837594e00;
00207 c3 = 6.61191906371416295e01;
00208 c4 = 2.98635138197400131e02;
00209 c5 = 8.81952221241769090e02;
00210 c6 = 1.71204761263407058e03;
00211 c7 = 2.05107837782607147e03;
00212 c8 = 1.23033935479799725e03;
00213 c9 = 2.15311535474403846e-8;
00214 d1 = 1.57449261107098347e01;
00215 d2 = 1.17693950891312499e02;
00216 d3 = 5.37181101862009858e02;
00217 d4 = 1.62138957456669019e03;
00218 d5 = 3.29079923573345963e03;
00219 d6 = 4.36261909014324716e03;
00220 d7 = 3.43936767414372164e03;
00221 d8 = 1.23033935480374942e03;
00222 y = fabs(x);
00223 xnum = c9 * y;
00224 xden = y;
00225 xnum = (xnum + c1) * y;
00226 xden = (xden + d1) * y;
00227 xnum = (xnum + c2) * y;
00228 xden = (xden + d2) * y;
00229 xnum = (xnum + c3) * y;
00230 xden = (xden + d3) * y;
00231 xnum = (xnum + c4) * y;
00232 xden = (xden + d4) * y;
00233 xnum = (xnum + c5) * y;
00234 xden = (xden + d5) * y;
00235 xnum = (xnum + c6) * y;
00236 xden = (xden + d6) * y;
00237 xnum = (xnum + c7) * y;
00238 xden = (xden + d7) * y;
00239 result = (xnum + c8) / (xden + d8);
00240 z = floor(y*16)/16;
00241 del = (y-z) * (y+z);
00242 result = exp(-z * z) * exp(-del) * result;
00243 }
00244
00245
00246
00247 else if ( fabs(x) > 4.0 )
00248 {
00249 p1 = 3.05326634961232344e-1;
00250 p2 = 3.60344899949804439e-1;
00251 p3 = 1.25781726111229246e-1;
00252 p4 = 1.60837851487422766e-2;
00253 p5 = 6.58749161529837803e-4;
00254 p6 = 1.63153871373020978e-2;
00255 q1 = 2.56852019228982242e00;
00256 q2 = 1.87295284992346047e00;
00257 q3 = 5.27905102951428412e-1;
00258 q4 = 6.05183413124413191e-2;
00259 q5 = 2.33520497626869185e-3;
00260 y = fabs(x);
00261 z = 1 / (y * y);
00262 xnum = p6 * z;
00263 xden = z;
00264 xnum = (xnum + p1) * z;
00265 xden = (xden + q1) * z;
00266 xnum = (xnum + p2) * z;
00267 xden = (xden + q2) * z;
00268 xnum = (xnum + p3) * z;
00269 xden = (xden + q3) * z;
00270 xnum = (xnum + p4) * z;
00271 xden = (xden + q4) * z;
00272 result = z * (xnum + p5) / (xden + q5);
00273 result = (1/sqrt(pi) - result) / y;
00274 z = floor(y*16)/16;
00275 del = (y-z) * (y+z);
00276 result = exp(-z * z) * exp(-del) * result;
00277 }
00278
00279
00280
00281 if ( x > 0.46875 )
00282 result = (0.5 - result) + 0.5;
00283 if ( x < -0.46875 )
00284 result = (-0.5 + result) - 0.5;
00285
00286 return result;
00287 }
00288
00289 double
00290 NormalRV::inverseErrorFunction(double y)
00291 {
00292 double a1,a2,a3,a4;
00293 double b1,b2,b3,b4;
00294 double c1,c2,c3,c4;
00295 double d1,d2;
00296 double x,z;
00297 double pi = 3.14159265358979;
00298
00299
00300 a1 = 0.886226899;
00301 a2 = -1.645349621;
00302 a3 = 0.914624893;
00303 a4 = 0.140543331;
00304 b1 = -2.118377725;
00305 b2 = 1.442710462;
00306 b3 = -0.329097515;
00307 b4 = 0.012229801;
00308 c1 = -1.970840454;
00309 c2 = -1.624906493;
00310 c3 = 3.429567803;
00311 c4 = 1.641345311;
00312 d1 = 3.543889200;
00313 d2 = 1.637067800;
00314
00315
00316 if ( fabs(y) <= 0.7 )
00317 {
00318 z = y * y;
00319 x = y * (((a4*z+a3)*z+a2)*z+a1) / ((((b4*z+b3)*z+b2)*z+b1)*z+1);
00320 }
00321
00322
00323 if ( y > 0.7 && y < 1 )
00324 {
00325 z = sqrt(-log((1-y)/2));
00326 x = (((c4*z+c3)*z+c2)*z+c1) / ((d2*z+d1)*z+1);
00327 }
00328
00329 if ( y < -0.7 && y > -1 )
00330 {
00331 z = sqrt(-log((1+y)/2));
00332 x = -(((c4*z+c3)*z+c2)*z+c1) / ((d2*z+d1)*z+1);
00333 }
00334
00335
00336
00337
00338
00339 x = x - (errorFunction(x) - y) / (2.0/sqrt(pi) * exp(-pow(x,2.0)));
00340 x = x - (errorFunction(x) - y) / (2.0/sqrt(pi) * exp(-pow(x,2.0)));
00341
00342
00343
00344
00345
00346
00347
00348
00349 return x;
00350
00351 }
00352
00353
00354
00355
00356
00357
00358
00359