Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #include "mcal_extract_mode.h"
00007 #include <vnl/algo/vnl_symmetric_eigensystem.h>
00008 #include <vcl_algorithm.h>
00009 #include <vcl_iostream.h>
00010 #include <mbl/mbl_data_array_wrapper.h>
00011 #include <mcal/mcal_pca.h>
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 void mcal_extract_mode(vcl_vector<vnl_vector<double> >& dv,
00023 const vcl_vector<unsigned>& used,
00024 vnl_vector<double>& mode,
00025 double& var)
00026 {
00027 if (used.size()==0)
00028 {
00029
00030 mcal_extract_mode(dv,mode,var);
00031 return;
00032 }
00033
00034 unsigned ns=dv.size();
00035 unsigned nd=dv[0].size();
00036
00037
00038 vcl_vector<vnl_vector<double> > v(ns);
00039 for (unsigned i=0;i<ns;++i)
00040 {
00041 v[i].set_size(used.size());
00042 for (unsigned j=0;j<used.size();++j)
00043 v[i][j]=dv[i][used[j]];
00044 }
00045
00046
00047
00048 vnl_vector<double> zero_mean(v[0].size(),0.0),mode_var0;
00049 vnl_matrix<double> modes0;
00050 mcal_pca pca;
00051 pca.set_mode_choice(1,1,1.0);
00052 mbl_data_array_wrapper<vnl_vector<double> > data(v);
00053 pca.build_about_mean(data,zero_mean,modes0,mode_var0);
00054
00055
00056 var = mode_var0[0];
00057 mode.set_size(nd);
00058 mode.fill(0.0);
00059 vnl_vector<double> sub_mode = modes0.get_column(0);
00060 for (unsigned j=0;j<used.size();++j)
00061 mode[used[j]] = sub_mode[j];
00062
00063
00064 for (unsigned i=0;i<ns;++i)
00065 {
00066 double b = dot_product(sub_mode,v[i]);
00067 dv[i] -= b*mode;
00068 }
00069 }
00070
00071
00072
00073
00074
00075
00076 void mcal_extract_mode(vcl_vector<vnl_vector<double> >& dv,
00077 vnl_vector<double>& mode,
00078 double& var)
00079 {
00080 unsigned ns=dv.size();
00081
00082
00083
00084 vnl_vector<double> zero_mean(dv[0].size(),0.0),mode_var0;
00085 vnl_matrix<double> modes0;
00086 mcal_pca pca;
00087 pca.set_mode_choice(1,1,1.0);
00088 mbl_data_array_wrapper<vnl_vector<double> > data(dv);
00089 pca.build_about_mean(data,zero_mean,modes0,mode_var0);
00090
00091
00092 var = mode_var0[0];
00093 mode = modes0.get_column(0);
00094
00095
00096 for (unsigned i=0;i<ns;++i)
00097 {
00098 double b = dot_product(mode,dv[i]);
00099 dv[i] -= b*mode;
00100 }
00101 }
00102
00103
00104
00105
00106
00107 void mcal_extract_modes(vcl_vector<vnl_vector<double> >& dv,
00108 const vcl_vector<vcl_vector<unsigned> >& used,
00109 unsigned max_modes, double var_prop,
00110 vnl_matrix<double>& modes,
00111 vnl_vector<double>& mode_var)
00112 {
00113 unsigned ns=dv.size();
00114
00115
00116 double total_var=0;
00117 for (unsigned i=0;i<ns;++i)
00118 total_var += dv[i].squared_magnitude();
00119
00120 total_var/=ns;
00121 double var_thresh = var_prop*total_var;
00122
00123 vcl_vector<vnl_vector<double> > mode_set(used.size());
00124 vcl_vector<double> var_set(used.size());
00125
00126 double var_sum=0.0;
00127
00128
00129 for (unsigned i=0;i<used.size();++i)
00130 {
00131 mcal_extract_mode(dv,used[i],mode_set[i],var_set[i]);
00132 var_sum+=var_set[i];
00133 }
00134
00135
00136
00137
00138 if (var_sum<var_thresh && used.size()<max_modes)
00139 {
00140
00141
00142 vnl_vector<double> mean0(dv[0].size()),mode_var0;
00143 mean0.fill(0.0);
00144 vnl_matrix<double> modes0;
00145 mcal_pca pca;
00146 pca.set_mode_choice(1,max_modes-used.size(),1.0);
00147 mbl_data_array_wrapper<vnl_vector<double> > data(dv);
00148 pca.build_about_mean(data,mean0,modes0,mode_var0);
00149
00150
00151 unsigned m=0;
00152 while (mode_set.size()<max_modes &&
00153 var_sum<var_thresh && m<mode_var0.size())
00154 {
00155
00156 vnl_vector<double> mode=modes0.get_column(m);
00157 mode_set.push_back(mode);
00158 var_set.push_back(mode_var0[m]);
00159 var_sum += mode_var0[m];
00160 m++;
00161 }
00162 }
00163
00164 unsigned nd = dv[0].size();
00165 unsigned n_modes = mode_set.size();
00166
00167
00168 modes.set_size(nd,n_modes);
00169 mode_var.set_size(n_modes);
00170 for (unsigned i=0;i<n_modes;++i)
00171 {
00172 modes.set_column(i,mode_set[i]);
00173 mode_var[i]=var_set[i];
00174 }
00175 }
00176