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 }