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 <UserDefinedRV.h>
00035 #include <math.h>
00036 #include <string.h>
00037 #include <classTags.h>
00038 #include <OPS_Globals.h>
00039 #include <Vector.h>
00040
00041 UserDefinedRV::UserDefinedRV(int passedTag, Vector pxPoints, Vector pPDFpoints, double pStartValue)
00042 :RandomVariable(passedTag, RANDOM_VARIABLE_userdefined)
00043 {
00044 xPoints = new Vector(pxPoints);
00045 PDFpoints = new Vector(pPDFpoints);
00046 startValue = pStartValue;
00047 }
00048
00049 UserDefinedRV::UserDefinedRV(int passedTag, Vector pxPoints, Vector pPDFpoints)
00050 :RandomVariable(passedTag, RANDOM_VARIABLE_userdefined)
00051 {
00052 xPoints = new Vector(pxPoints);
00053 PDFpoints = new Vector(pPDFpoints);
00054 startValue = getMean();
00055 }
00056
00057
00058 UserDefinedRV::~UserDefinedRV()
00059 {
00060 if (xPoints != 0) {
00061 delete xPoints;
00062 }
00063 if (PDFpoints != 0) {
00064 delete PDFpoints;
00065 }
00066 }
00067
00068
00069 void
00070 UserDefinedRV::Print(OPS_Stream &s, int flag)
00071 {
00072 }
00073
00074
00075 double
00076 UserDefinedRV::getPDFvalue(double x)
00077 {
00078
00079 double ok = -1.0;
00080 if ( x < (*xPoints)(0) ) {
00081 return 0.0;
00082 }
00083 else if ( x > (*xPoints)(xPoints->Size()-1) ) {
00084 return 0.0;
00085 }
00086 else {
00087 for ( int i=1; i<xPoints->Size(); i++ ) {
00088 if ( x <= (*xPoints)(i) ) {
00089 double a = ((*PDFpoints)(i)-(*PDFpoints)(i-1))/((*xPoints)(i)-(*xPoints)(i-1));
00090 ok = ( a * (x-(*xPoints)(i-1)) + (*PDFpoints)(i-1) );
00091 break;
00092 }
00093 }
00094 if (ok<0.0) {
00095 opserr << "ERROR: UserDefinedRV::getPDFvalue() -- distribution function seems to be invalid." << endln;
00096 }
00097 return ok;
00098 }
00099 }
00100
00101
00102 double
00103 UserDefinedRV::getCDFvalue(double x)
00104 {
00105 double ok = -1.0;
00106 if ( x < (*xPoints)(0) ) {
00107 return 0.0;
00108 }
00109 else if ( x > (*xPoints)(xPoints->Size()-1) ) {
00110 return 1.0;
00111 }
00112 else {
00113 double sum = 0.0;
00114 for ( int i=1; i<xPoints->Size(); i++ ) {
00115 if ( x <= (*xPoints)(i) ) {
00116
00117 ok = ( sum + 0.5 * (getPDFvalue(x)+(*PDFpoints)(i-1)) * (x-(*xPoints)(i-1)) );
00118 break;
00119 }
00120 sum += 0.5 * ((*PDFpoints)(i)+(*PDFpoints)(i-1)) * ((*xPoints)(i)-(*xPoints)(i-1));
00121 }
00122 if (ok<0.0) {
00123 opserr << "ERROR: UserDefinedRV::getPDFvalue() -- distribution function seems to be invalid." << endln;
00124 }
00125 return ok;
00126 }
00127 }
00128
00129
00130 double
00131 UserDefinedRV::getInverseCDFvalue(double p)
00132 {
00133 if (p < 0.0 || p > 1.0) {
00134 opserr << "ERROR: Illegal probability value input to UserDefinedRV::getInverseCDFvalue()" << endln;
00135 return 0.0;
00136 }
00137 else if (p == 0.0) {
00138 return ((*xPoints)(0));
00139 }
00140
00141
00142 double ok;
00143 for ( int i=1; i<xPoints->Size(); i++ ) {
00144 if ( getCDFvalue((*xPoints)(i)) > p) {
00145 double a = (getPDFvalue((*xPoints)(i))-getPDFvalue((*xPoints)(i-1)))/((*xPoints)(i)-(*xPoints)(i-1));
00146 if ( a==0.0 && getPDFvalue((*xPoints)(i-1))==0.0 ) {
00147 opserr << "ERROR: An inside region of PDF is constant zero..." << endln;
00148 }
00149 else if (a==0.0) {
00150 ok = (p-getCDFvalue((*xPoints)(i-1))+getPDFvalue((*xPoints)(i-1))*(*xPoints)(i-1))/getPDFvalue((*xPoints)(i-1));
00151 }
00152 else {
00153
00154 double A = 0.5*a;
00155 double B = getPDFvalue((*xPoints)(i-1));
00156 double C = getCDFvalue((*xPoints)(i-1)) - p;
00157 double x_minus_x_i_1 = (-B+sqrt(B*B-4.0*A*C))/(2.0*A);
00158 ok = x_minus_x_i_1 + ((*xPoints)(i-1));
00159 }
00160 break;
00161 }
00162 }
00163 return ok;
00164 }
00165
00166
00167 const char *
00168 UserDefinedRV::getType()
00169 {
00170 return "USERDEFINED";
00171 }
00172
00173
00174 double
00175 UserDefinedRV::getMean()
00176 {
00177 double sum = 0.0;
00178 double a, b;
00179 for ( int i=1; i<xPoints->Size(); i++ ) {
00180 a = ((*PDFpoints)(i)-(*PDFpoints)(i-1))/((*xPoints)(i)-(*xPoints)(i-1));
00181 b = (*PDFpoints)(i-1) - a * (*xPoints)(i-1);
00182 sum += a*((*xPoints)(i))*((*xPoints)(i))*((*xPoints)(i))/3.0
00183 + 0.5*b*((*xPoints)(i))*((*xPoints)(i))
00184 - a*((*xPoints)(i-1))*((*xPoints)(i-1))*((*xPoints)(i-1))/3.0
00185 - 0.5*b*((*xPoints)(i-1))*((*xPoints)(i-1));
00186 }
00187 return sum;
00188 }
00189
00190
00191
00192 double
00193 UserDefinedRV::getStdv()
00194 {
00195 double sum = 0.0;
00196 double a, b;
00197 double mu = getMean();
00198 for ( int i=1; i<xPoints->Size(); i++ ) {
00199 a = ((*PDFpoints)(i)-(*PDFpoints)(i-1))/((*xPoints)(i)-(*xPoints)(i-1));
00200 b = (*PDFpoints)(i-1) - a * (*xPoints)(i-1);
00201 double x1 = (*xPoints)(i-1);
00202 double x2 = (*xPoints)(i);
00203 sum += 0.25*a*x2*x2*x2*x2
00204 - 2.0/3.0*mu*a*x2*x2*x2
00205 + mu*mu*b*x2
00206 - mu*b*x2*x2
00207 + b*x2*x2*x2/3.0
00208 + 0.5*mu*mu*a*x2*x2
00209 - 0.25*a*x1*x1*x1*x1
00210 + 2.0/3.0*mu*a*x1*x1*x1
00211 - mu*mu*b*x1
00212 + mu*b*x1*x1
00213 - b*x1*x1*x1/3.0
00214 - 0.5*mu*mu*a*x1*x1;
00215 }
00216 return sqrt(sum);
00217 }
00218
00219
00220 double
00221 UserDefinedRV::getStartValue()
00222 {
00223 return startValue;
00224 }
00225
00226 double UserDefinedRV::getParameter1() {opserr<<"No such parameter in r.v. #"<<tag<<endln; return 0.0;}
00227 double UserDefinedRV::getParameter2() {opserr<<"No such parameter in r.v. #"<<tag<<endln; return 0.0;}
00228 double UserDefinedRV::getParameter3() {opserr<<"No such parameter in r.v. #"<<tag<<endln; return 0.0;}
00229 double UserDefinedRV::getParameter4() {opserr<<"No such parameter in r.v. #"<<tag<<endln; return 0.0;}
00230