contrib/mul/vpdfl/vpdfl_calc_mean_var.cxx
Go to the documentation of this file.
00001 // This is mul/vpdfl/vpdfl_calc_mean_var.cxx
00002 #include "vpdfl_calc_mean_var.h"
00003 //:
00004 // \file
00005 // \author Tim Cootes
00006 // \brief Calculate mean and variance of multivariate data.
00007 
00008 #include <mbl/mbl_data_array_wrapper.h>
00009 
00010 //: Compute mean and variance of data
00011 void vpdfl_calc_mean_var(vnl_vector<double>& mean,
00012                          vnl_vector<double>& var,
00013                          const vnl_vector<double>* data, int n)
00014 {
00015   if (n==0) return;
00016   int n_dims = data[0].size();
00017   vnl_vector<double> sum_sq(n_dims);
00018   mean.set_size(n_dims);
00019   var.set_size(n_dims);
00020 
00021   double* var_data = var.data_block();
00022   double* mean_data = mean.data_block();
00023   double* sum_sq_data = sum_sq.data_block();
00024   mean.fill(0.0);
00025   sum_sq.fill(0.0);
00026 
00027   for (int i=0;i<n;i++)
00028   {
00029     const double *v = data[i].data_block();
00030     for (int j=0;j<n_dims;j++)
00031     {
00032       mean_data[j] += v[j];
00033       sum_sq_data[j] += v[j]*v[j];
00034     }
00035   }
00036   mean/=n;
00037 
00038   var.set_size(n_dims);
00039   for (int j=0;j<n_dims;j++)
00040   {
00041     var_data[j] = sum_sq_data[j]/n - mean_data[j]*mean_data[j];
00042   }
00043 }
00044 
00045 //: Compute mean and variance of data
00046 void vpdfl_calc_mean_var(vnl_vector<double>& mean,
00047                          vnl_vector<double>& var,
00048                          mbl_data_wrapper<vnl_vector<double> >& data)
00049 {
00050   if (data.is_class("mbl_data_array_wrapper<T>"))
00051   {
00052     // Use more efficient algorithm
00053     mbl_data_array_wrapper<vnl_vector<double> > array_data
00054                  = static_cast<mbl_data_array_wrapper<vnl_vector<double> >&>( data);
00055     vpdfl_calc_mean_var(mean,var,array_data.data(),array_data.size());
00056     return;
00057   }
00058 
00059   unsigned long n = data.size();
00060   if (n==0L) return;
00061   data.reset();
00062   int n_dims = data.current().size();
00063   vnl_vector<double> sum_sq(n_dims);
00064   mean.set_size(n_dims);
00065   var.set_size(n_dims);
00066 
00067   double* var_data = var.data_block();
00068   double* mean_data = mean.data_block();
00069   double* sum_sq_data = sum_sq.data_block();
00070   mean.fill(0.0);
00071   sum_sq.fill(0.0);
00072 
00073   for (unsigned long i=0;i<n;i++)
00074   {
00075     const double *v = data.current().data_block();
00076     for (int j=0;j<n_dims;j++)
00077     {
00078       mean_data[j] += v[j];
00079       sum_sq_data[j] += v[j]*v[j];
00080     }
00081     data.next();
00082   }
00083   mean/=n;
00084 
00085   var.set_size(n_dims);
00086   for (int j=0;j<n_dims;j++)
00087   {
00088     var_data[j] = sum_sq_data[j]/n - mean_data[j]*mean_data[j];
00089   }
00090 }