00001 // This is mul/pdf1d/pdf1d_compare_to_pdf_ks.cxx 00002 00003 //: 00004 // \file 00005 // \author Tim Cootes 00006 // \brief Test if data from a given distribution using Kolmogorov-Smirnov 00007 00008 #include "pdf1d_compare_to_pdf_ks.h" 00009 00010 #include <vcl_string.h> 00011 #include <vcl_cmath.h> 00012 #include <vbl/vbl_qsort.h> 00013 #include <vnl/vnl_vector.h> 00014 00015 #include <pdf1d/pdf1d_prob_ks.h> 00016 00017 //======================================================================= 00018 // Dflt ctor 00019 //======================================================================= 00020 00021 pdf1d_compare_to_pdf_ks::pdf1d_compare_to_pdf_ks() 00022 { 00023 } 00024 00025 //======================================================================= 00026 // Destructor 00027 //======================================================================= 00028 00029 pdf1d_compare_to_pdf_ks::~pdf1d_compare_to_pdf_ks() 00030 { 00031 } 00032 00033 //======================================================================= 00034 00035 //: Test whether data came from the given distribution 00036 double pdf1d_compare_to_pdf_ks::compare(const double* data, int n, 00037 const pdf1d_pdf& pdf) 00038 { 00039 if (!pdf.cdf_is_analytic()) 00040 { 00041 vcl_cerr<<"Warning: pdf1d_compare_to_pdf_ks::compare() " 00042 <<"Incorrectly assuming an analytic form for CDF.\n"; 00043 // Should use slightly different implementation when estimating CDF using samples 00044 // Not yet implemented though. 00045 } 00046 00047 // Sort the data 00048 vnl_vector<double> sorted_data(data,n); 00049 double *s = sorted_data.data_block(); 00050 00051 vbl_qsort_ascending(s,n); 00052 00053 double d_max=0.0; 00054 double cdf_last = 0; 00055 00056 for (int i=0;i<n;++i) 00057 { 00058 double cdf = pdf.cdf(s[i]); 00059 double data_cdf = (1.0+i)/n; 00060 double d = vcl_fabs(cdf-data_cdf); 00061 if (d>d_max) d_max=d; 00062 d = vcl_fabs(cdf_last-data_cdf); 00063 if (d>d_max) d_max=d; 00064 00065 cdf_last = cdf; 00066 } 00067 00068 double root_n = vcl_sqrt(double(n)); 00069 return pdf1d_prob_ks((root_n+0.12+0.11/root_n)*d_max); 00070 } 00071 00072 00073 //======================================================================= 00074 // Method: is_a 00075 //======================================================================= 00076 00077 vcl_string pdf1d_compare_to_pdf_ks::is_a() const 00078 { 00079 return vcl_string("pdf1d_compare_to_pdf_ks"); 00080 } 00081 00082 //======================================================================= 00083 // Method: is_class 00084 //======================================================================= 00085 00086 bool pdf1d_compare_to_pdf_ks::is_class(vcl_string const& s) const 00087 { 00088 return pdf1d_compare_to_pdf::is_class(s) || s==pdf1d_compare_to_pdf_ks::is_a(); 00089 } 00090 00091 //======================================================================= 00092 // Method: version_no 00093 //======================================================================= 00094 00095 short pdf1d_compare_to_pdf_ks::version_no() const 00096 { 00097 return 1; 00098 } 00099 00100 //======================================================================= 00101 // Method: clone 00102 //======================================================================= 00103 00104 pdf1d_compare_to_pdf* pdf1d_compare_to_pdf_ks::clone() const 00105 { 00106 return new pdf1d_compare_to_pdf_ks(*this); 00107 } 00108 00109 //======================================================================= 00110 // Method: print 00111 //======================================================================= 00112 00113 void pdf1d_compare_to_pdf_ks::print_summary(vcl_ostream& /*os*/) const 00114 { 00115 vcl_cerr << "pdf1d_compare_to_pdf_ks::print_summary() NYI\n"; 00116 } 00117 00118 //======================================================================= 00119 // Method: save 00120 //======================================================================= 00121 00122 void pdf1d_compare_to_pdf_ks::b_write(vsl_b_ostream& bfs) const 00123 { 00124 vsl_b_write(bfs,version_no()); 00125 } 00126 00127 //======================================================================= 00128 // Method: load 00129 //======================================================================= 00130 00131 void pdf1d_compare_to_pdf_ks::b_read(vsl_b_istream& bfs) 00132 { 00133 if (!bfs) return; 00134 00135 short version; 00136 vsl_b_read(bfs,version); 00137 switch (version) 00138 { 00139 case 1: 00140 break; 00141 default: 00142 vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&, pdf1d_compare_to_pdf_ks &)\n" 00143 << " Unknown version number "<< version << '\n'; 00144 bfs.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream 00145 return; 00146 } 00147 } 00148