00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "freAsymmetricVariateGenerator.h"
00021 #include "vnl/vnl_sample.h"
00022 #include "vnl/vnl_math.h"
00023
00024 namespace itk {
00025 namespace Statistics {
00026
00027 void
00028 AsymmetricVariateGenerator::
00029 PrintSelf(std::ostream& os, Indent indent) const
00030 {
00031 Superclass::PrintSelf(os, indent) ;
00032
00033
00034 os << indent << "Variance: " << m_Variance << std::endl;
00035 os << indent << "Skewness: " << m_Skewness << std::endl;
00036 os << indent << "Gamma: " << m_Gamma << std::endl;
00037 }
00038
00039 AsymmetricVariateGenerator::
00040 AsymmetricVariateGenerator()
00041 {
00042 Initialize();
00043 };
00044
00045 void
00046 AsymmetricVariateGenerator::
00047 Initialize( const int randomSeed )
00048 {
00049 vnl_sample_reseed(randomSeed);
00050 };
00051
00052 void
00053 AsymmetricVariateGenerator::
00054 Initialize()
00055 {
00056 vnl_sample_reseed();
00057 };
00058
00059 double
00060 AsymmetricVariateGenerator::
00061 GetVariate()
00062 {
00063
00064
00065 double g = vnl_sample_uniform(0,1.0);
00066 double t = pow(1+m_Skewness , m_Gamma/2);
00067 double gTreshold = 1/(1+t);
00068
00069 double result = 0.0;
00070
00071 if (g<gTreshold)
00072 {
00073 result = sqrt(2*pow(m_Variance,m_Gamma)) * Erf((t*g)+g-1);
00074 }
00075 else
00076 {
00077 double h = pow(1+m_Skewness,-1*(m_Gamma/2));
00078 result = sqrt(2*pow((1+m_Skewness)*m_Variance , m_Gamma)) * Erf((h*g)-h+g);
00079 };
00080 return result;
00081 };
00082
00083 double
00084 AsymmetricVariateGenerator::
00085 operator()()
00086 {
00087 return this->GetVariate();
00088 };
00089
00090 double
00091 AsymmetricVariateGenerator::
00092 Erf(double x)
00093 {
00094 double result = (1/sqrt(2.0)) * INorm((x+1)/2);
00095 return result;
00096 };
00097
00098 double
00099 AsymmetricVariateGenerator::
00100 Freq(double x)
00101 {
00102 double v = abs(x);
00103 if (v<0.5)
00104 {
00105 double h = (3.6767877*v - 0.097970465*pow(v,3))/(3.2584593 + pow(v,2));
00106 if (x>0) return 0.5*h + 0.5;
00107 else return 0.5 - 0.5*h;
00108 }
00109 else if (v<4.0)
00110 {
00111
00112 double v_2 = v*v;
00113 double v_3 = v_2*v;
00114 double v_4 = v_3*v;
00115
00116 double ap = 7.37389 + 6.86502*v + 3.0318*v_2 + 0.56317*v_3 + 0.0000431878*v_4;
00117 double aq = 7.37396 + 15.1849*v + 12.7955*v_2 + 5.35422*v_3 + v_4;
00118 double h = 1 - exp(-1*v*v) * (ap/aq);
00119 if (x>0) return 0.5*h + 0.5;
00120 else return 0.5 - 0.5*h;
00121 }
00122 else
00123 {
00124 double h = 1 - exp(-1*v*v) * ((-0.96821 + 0.439821*pow(v,2) + 0.248761*pow(v,4)) / (pow(v,3) + 0.440917*pow(v,5)));
00125 if (x>0) return 0.5*h + 0.5;
00126 else return 0.5 - 0.5*h;
00127 }
00128 };
00129
00130 double
00131 AsymmetricVariateGenerator::
00132 INorm(double z)
00133 {
00134 if ((z<=0) || (z>=1)) itkExceptionMacro(<<"Invalid input value z. Value must be in interval (0, 1). z = "<<z);
00135
00136 if (z==0.5) return 0;
00137
00138 double x = z;
00139
00140 if (z>0.5) x = 1-z;
00141
00142 x = sqrt(-2*log(x));
00143
00144
00145 x = x - ((1271.06 + 450.636*x + 7.45551*pow(x,2)) / (500.756 + 750.365*x + 110.421*pow(x,2) + pow(x,3)));
00146
00147 if (z<0,5) x = -1 * x;
00148
00149 return x + 2.50662827*(z-Freq(x))*exp(0.5*x*x);
00150 }
00151 ;
00152 }
00153
00154 }