contrib/mul/mbl/mbl_stats_nd.cxx
Go to the documentation of this file.
00001 // This is mul/mbl/mbl_stats_nd.cxx
00002 #include "mbl_stats_nd.h"
00003 //:
00004 // \file
00005 // \brief Simple statistics (mean, variance) on vectors.
00006 // \author Tim Cootes
00007 
00008 #include <vcl_cmath.h>
00009 #include <vcl_cassert.h>
00010 #include <vcl_iostream.h>
00011 #include <vnl/io/vnl_io_vector.h>
00012 
00013 mbl_stats_nd::mbl_stats_nd()
00014 {
00015   clear();
00016 }
00017 
00018 void mbl_stats_nd::clear()
00019 {
00020   n_obs_ = 0;
00021   sum_.set_size(0);
00022   sum_sq_.set_size(0);
00023 }
00024 
00025 void mbl_stats_nd::obs(const vnl_vector<double>& v)
00026 {
00027   unsigned n=v.size();
00028   if (n_obs_ == 0)
00029   {
00030     sum_ = v;
00031     sum_sq_.set_size(n);
00032     for (unsigned i=0;i<n;++i) sum_sq_[i]=v[i]*v[i];
00033     n_obs_++;
00034     return;
00035   }
00036 
00037   assert(v.size()==n);
00038   sum_ += v;
00039   for (unsigned i=0;i<n;++i) sum_sq_[i]+=v[i]*v[i];
00040   n_obs_++;
00041 }
00042 
00043 vnl_vector<double> mbl_stats_nd::mean() const
00044 {
00045   if (n_obs_==0) return vnl_vector<double>();
00046   else return sum_/n_obs_;
00047 }
00048 
00049 vnl_vector<double> mbl_stats_nd::variance() const
00050 {
00051   if (n_obs_==0) return vnl_vector<double>();
00052 
00053   unsigned n=sum_.size();
00054   vnl_vector<double> var(n);
00055   if (n_obs_==1) { var.fill(0.0); return var; }
00056 
00057   for (unsigned i=0;i<n;++i)
00058   {
00059     var[i] = (sum_sq_[i]-(sum_[i]*sum_[i]/n_obs_))/(n_obs_-1);
00060   }
00061   return var;
00062 }
00063 
00064 
00065 vnl_vector<double> mbl_stats_nd::sd() const
00066 {
00067   if (n_obs_==0) return vnl_vector<double>();
00068 
00069   unsigned n=sum_.size();
00070   vnl_vector<double> sd(n);
00071   if (n_obs_==1) { sd.fill(0.0); return sd; }
00072 
00073   for (unsigned i=0;i<n;++i)
00074   {
00075     double var = (sum_sq_[i]-(sum_[i]*sum_[i]/n_obs_))/(n_obs_-1);
00076     if (var<=0) sd[i]=0.0;
00077     else        sd[i]=vcl_sqrt(var);
00078   }
00079   return sd;
00080 }
00081 
00082 vnl_vector<double> mbl_stats_nd::stdError() const
00083 {
00084   if (n_obs_==0) return vnl_vector<double>();
00085 
00086   unsigned n=sum_.size();
00087   vnl_vector<double> se(n);
00088   if (n_obs_==1) { se.fill(0.0); return se; }
00089 
00090   for (unsigned i=0;i<n;++i)
00091   {
00092     double var = (sum_sq_[i]-(sum_[i]*sum_[i]/n_obs_))/(n_obs_-1);
00093     if (var<=0) se[i]=0.0;
00094     else        se[i]=vcl_sqrt(var/n_obs_);
00095   }
00096   return se;
00097 }
00098 
00099 
00100 mbl_stats_nd& mbl_stats_nd::operator+=(const mbl_stats_nd& s1)
00101 {
00102   sum_ += s1.sum();
00103   sum_sq_ += s1.sumSq();
00104   n_obs_ += s1.n_obs();
00105   return *this ;
00106 }
00107 
00108 const double MAX_ERROR = 1.0e-8;
00109 
00110 //: Test for equality
00111 bool mbl_stats_nd::operator==(const mbl_stats_nd& s) const
00112 {
00113   if (n_obs_==0 && s.n_obs()==0) return true;
00114   return n_obs_==s.n_obs() &&
00115          vnl_vector_ssd(sum_,s.sum())/n_obs_<MAX_ERROR &&
00116          vnl_vector_ssd(sum_sq_,s.sumSq())/n_obs_<MAX_ERROR;
00117 }
00118 
00119 //: Version number for I/O
00120 short mbl_stats_nd::version_no() const
00121 {
00122   return 1;
00123 }
00124 
00125 void mbl_stats_nd::b_write(vsl_b_ostream& bfs) const
00126 {
00127   vsl_b_write(bfs,version_no());
00128   vsl_b_write(bfs,n_obs_);
00129   if (n_obs_==0) return;
00130   vsl_b_write(bfs,sum_);
00131   vsl_b_write(bfs,sum_sq_);
00132 }
00133 
00134 void mbl_stats_nd::b_read(vsl_b_istream& bfs)
00135 {
00136   if (!bfs) return;
00137 
00138   short file_version_no;
00139   vsl_b_read(bfs,file_version_no);
00140 
00141   switch (file_version_no)
00142   {
00143    case 1:
00144     vsl_b_read(bfs,n_obs_);
00145     if (n_obs_<=0) clear();
00146     else
00147     {
00148       vsl_b_read(bfs,sum_);
00149       vsl_b_read(bfs,sum_sq_);
00150     }
00151     break;
00152    default:
00153     vcl_cerr << "I/O ERROR: mbl_stats_nd::b_read(vsl_b_istream&)\n"
00154              << "           Unknown version number "<< file_version_no << '\n';
00155     bfs.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00156     return;
00157   }
00158 }
00159 
00160 void mbl_stats_nd::print_summary(vcl_ostream& os) const
00161 {
00162   os << "mbl_stats_nd: ";
00163   if (n_obs_==0)
00164     os << "No samples.";
00165   else
00166   {
00167     os << "mean: "<< mean();
00168   }
00169 }
00170 
00171 vcl_ostream& operator<<(vcl_ostream& os, const mbl_stats_nd& stats)
00172 {
00173   stats.print_summary(os);
00174   return os;
00175 }
00176 
00177   //: Stream output operator for class reference
00178 void vsl_print_summary(vcl_ostream& os,const mbl_stats_nd& stats)
00179 {
00180   stats.print_summary(os);
00181 }
00182 
00183 mbl_stats_nd operator+(const mbl_stats_nd& s1, const mbl_stats_nd& s2)
00184 {
00185   mbl_stats_nd r = s1;
00186   r+=s2;
00187 
00188   return r;
00189 }
00190 
00191   //: Binary file stream output operator for class reference
00192 void vsl_b_write(vsl_b_ostream& bfs, const mbl_stats_nd& b)
00193 {
00194   b.b_write(bfs);
00195 }
00196 
00197   //: Binary file stream input operator for class reference
00198 void vsl_b_read(vsl_b_istream& bfs, mbl_stats_nd& b)
00199 {
00200   b.b_read(bfs);
00201 }