contrib/mul/pdf1d/pdf1d_compare_to_pdf_ks.cxx
Go to the documentation of this file.
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