00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "DistributionInverter.h"
00014
00015 void DistributionInverter::operator=( const DistributionInverter & rhs )
00016 {
00017 F_inverse=rhs.F_inverse;
00018 }
00019
00020
00021 void DistributionInverter::initialize(Array1D<double> &x_input,
00022 Array1D<double> &y_input)
00023 {
00024
00025 for(int i=0;i<x_input.size();i++)
00026 {
00027 if(y_input(i)<0.0)
00028 {
00029 cout << "We can not use DistributionInverter class for a distribution"
00030 << endl;
00031 cout << "which is negative. This makes no sense so we will quit."
00032 << endl;
00033 cout << "exit(1) in DistributionInverter::initializeWithFunctionValues()"
00034 << endl;
00035 cout << "i:\t" << i << "\tx_input():\t" << x_input(i)
00036 << "\ty_input():\t" << y_input(i) << endl;
00037 exit(1);
00038 }
00039 }
00040
00041 make_F_and_F_inverse(x_input,y_input);
00042 }
00043
00044 void DistributionInverter::make_F_and_F_inverse(Array1D<double> &x_input,
00045 Array1D<double> &y_input)
00046 {
00047 int n=x_input.dim1();
00048 Array1D<double> X_INP;
00049 Array1D<double> Y_INP;
00050 X_INP.allocate(n);
00051 Y_INP.allocate(n);
00052
00053 double total_integral=0.0;
00054 double L,R,A,B,int_AB;
00055
00056 X_INP(0)=x_input(0);
00057 Y_INP(0)=total_integral;
00058
00059 for(int i=0;i<(n-1);i++)
00060 {
00061 L=x_input(i);
00062 R=x_input(i+1);
00063
00064 A = y_input(i);
00065
00066 B = y_input(i+1);
00067
00068
00069 int_AB = (B+A)/2.0*(R-L);
00070
00071 total_integral=total_integral+int_AB;
00072
00073 X_INP(i+1)=R;
00074 Y_INP(i+1)=total_integral;
00075 }
00076
00077
00078 for(int i=0;i<n;i++)
00079 {
00080 Y_INP(i)=Y_INP(i)/total_integral;
00081 }
00082
00083
00084 for(int i=0;i<(n-1);i++)
00085 {
00086 if(TINY>(Y_INP(i+1)-Y_INP(i)))
00087 {
00088 Y_INP(i+1)=Y_INP(i)+TINY;
00089 }
00090 }
00091
00092
00093
00094 for(int i=0;i<n;i++)
00095 {
00096 Y_INP(i)=Y_INP(i)/Y_INP(n-1);
00097 }
00098
00099 F_inverse.initializeWithFunctionValues(Y_INP,X_INP);
00100 }
00101
00102
00103 double DistributionInverter::random()
00104 {
00105 F_inverse.evaluate(ran.unidev());
00106 return F_inverse.getFunctionValue();
00107 }
00108
00109
00110
00111
00112
00113
00114
00115