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 <BetaRV.h>
00035 #include <GammaRV.h>
00036 #include <math.h>
00037 #include <string.h>
00038 #include <classTags.h>
00039 #include <OPS_Globals.h>
00040
00041 BetaRV::BetaRV(int passedTag,
00042 double passedParameter1,
00043 double passedParameter2,
00044 double passedParameter3,
00045 double passedParameter4,
00046 double passedStartValue)
00047 :RandomVariable(passedTag, RANDOM_VARIABLE_beta)
00048 {
00049 tag = passedTag ;
00050 a = passedParameter1;
00051 b = passedParameter2;
00052 q = passedParameter3;
00053 r = passedParameter4;
00054 startValue = passedStartValue;
00055 }
00056 BetaRV::BetaRV(int passedTag,
00057 double passedParameter1,
00058 double passedParameter2,
00059 double passedParameter3,
00060 double passedParameter4)
00061 :RandomVariable(passedTag, RANDOM_VARIABLE_beta)
00062 {
00063 tag = passedTag ;
00064 a = passedParameter1;
00065 b = passedParameter2;
00066 q = passedParameter3;
00067 r = passedParameter4;
00068 startValue = getMean();
00069 }
00070
00071
00072 BetaRV::~BetaRV()
00073 {
00074 }
00075
00076
00077 void
00078 BetaRV::Print(OPS_Stream &s, int flag)
00079 {
00080 }
00081
00082
00083 double
00084 BetaRV::getPDFvalue(double rvValue)
00085 {
00086 double result;
00087 if ( a <= rvValue && rvValue <= b ) {
00088 double par1 = pow(rvValue-a,q-1.0);
00089 double par2 = pow(b-rvValue,r-1.0);
00090 double par3 = betaFunction(q,r);
00091 double par4 = pow(b-a,q+r-1.0);
00092 result = par1*par2/(par3*par4);
00093 }
00094 else {
00095 result = 0.0;
00096 }
00097 return result;
00098 }
00099
00100
00101 double
00102 BetaRV::getCDFvalue(double rvValue)
00103 {
00104
00105 double result = 0.0;
00106
00107 if ( a < rvValue && rvValue < b ) {
00108
00109
00110
00111
00112 int n_2 = 100;
00113 double h = rvValue-a;
00114 double fa = getPDFvalue(a);
00115 double fb = getPDFvalue(rvValue);
00116 double sum_fx2j = 0.0;
00117 double sum_fx2j_1 = 0.0;
00118 for (int j=1; j<=n_2; j++) {
00119 sum_fx2j = sum_fx2j + getPDFvalue( (double) (a+(j*2)*h/(2*n_2)) );
00120 sum_fx2j_1 = sum_fx2j_1 + getPDFvalue( (double)(a+(j*2-1)*h/(2*n_2)) );
00121 }
00122 sum_fx2j = sum_fx2j - getPDFvalue((double)(rvValue));
00123 result = h/(2*n_2)/3.0*(fa + 2.0*sum_fx2j + 4.0*sum_fx2j_1 + fb);
00124 }
00125 else if (rvValue<=a) {
00126 result = 0.0;
00127 }
00128 else {
00129 result = 1.0;
00130 }
00131
00132 return result;
00133 }
00134
00135
00136 double
00137 BetaRV::getInverseCDFvalue(double probValue)
00138 {
00139 double result = 0.0;
00140
00141
00142
00143
00144
00145
00146
00147
00148 double tol = 0.000001;
00149 double x_old = getMean();
00150 double x_new;
00151 double f;
00152 double df;
00153 double h;
00154 double perturbed_f;
00155 for (int i=1; i<=100; i++ ) {
00156
00157
00158 f = probValue - getCDFvalue(x_old);
00159
00160 h = getStdv()/200.0;
00161 perturbed_f = probValue - getCDFvalue(x_old+h);
00162
00163
00164 df = ( perturbed_f - f ) / h;
00165
00166 if ( fabs(df) < 1.0e-15) {
00167 opserr << "WARNING: BetaRV::getInverseCDFvalue() -- zero derivative " << endln
00168 << " in Newton algorithm. " << endln;
00169 }
00170 else {
00171
00172
00173 x_new = x_old - f/df;
00174
00175
00176 if (fabs(1.0-fabs(x_old/x_new)) < tol) {
00177 return x_new;
00178 }
00179 else {
00180 if (i==100) {
00181 opserr << "WARNING: Did not converge to find inverse CDF!" << endln;
00182 return 0.0;
00183 }
00184 else {
00185 x_old = x_new;
00186 }
00187
00188 }
00189 }
00190 }
00191
00192 return result;
00193 }
00194
00195
00196 const char *
00197 BetaRV::getType()
00198 {
00199 return "BETA";
00200 }
00201
00202
00203 double
00204 BetaRV::getMean()
00205 {
00206 return (a*r+b*q)/(q+r);
00207 }
00208
00209
00210
00211 double
00212 BetaRV::getStdv()
00213 {
00214 return ((b-a)/(q+r)) * sqrt(q*r/(q+r+1));
00215 }
00216
00217
00218 double
00219 BetaRV::getStartValue()
00220 {
00221 return startValue;
00222 }
00223
00224 double BetaRV::getParameter1() {return a;}
00225 double BetaRV::getParameter2() {return b;}
00226 double BetaRV::getParameter3() {return q;}
00227 double BetaRV::getParameter4() {return r;}
00228
00229
00230
00231 double
00232 BetaRV::betaFunction(double q, double r)
00233 {
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 GammaRV *aGammaRV = new GammaRV(1, 0.0, 1.0, 0.0);
00249 double gammaq,gammar,gammaqpr;
00250 gammaq = aGammaRV->gammaFunction(q);
00251 gammar = aGammaRV->gammaFunction(r);
00252 gammaqpr = aGammaRV->gammaFunction(q+r);
00253 delete aGammaRV;
00254 double loggammaq,loggammar,loggammaqpr;
00255 loggammaq = log(gammaq);
00256 loggammar = log(gammar);
00257 loggammaqpr = log(gammaqpr);
00258 return exp(loggammaq+loggammar-loggammaqpr);
00259 }