00001 #include "mcal_var_basis_cost.h" 00002 //: 00003 // \file 00004 // \author Tim Cootes 00005 // \brief Cost function to promote sparse basis vectors 00006 00007 #include <vcl_cstdlib.h> 00008 #include <vcl_string.h> 00009 #include <vcl_cmath.h> 00010 #include <vcl_sstream.h> 00011 00012 #include <vsl/vsl_binary_io.h> 00013 #include <mbl/mbl_parse_block.h> 00014 #include <mbl/mbl_read_props.h> 00015 #include <mbl/mbl_exception.h> 00016 00017 //======================================================================= 00018 // Constructors 00019 //======================================================================= 00020 00021 mcal_var_basis_cost::mcal_var_basis_cost() 00022 { 00023 } 00024 00025 //======================================================================= 00026 // Destructor 00027 //======================================================================= 00028 00029 mcal_var_basis_cost::~mcal_var_basis_cost() 00030 { 00031 } 00032 00033 //: Returns true since cost can be computed from the variance. 00034 bool mcal_var_basis_cost::can_use_variance() const 00035 { 00036 return true; 00037 } 00038 00039 //: Compute component of the cost function from given basis vector 00040 // \param[in] unit_basis Unit vector defining basis direction 00041 // \param[in] projections Projections of the dataset onto this basis vector 00042 double mcal_var_basis_cost::cost(const vnl_vector<double>& unit_basis, 00043 const vnl_vector<double>& projections) 00044 { 00045 double var = projections.squared_magnitude()/projections.size(); 00046 return cost_from_variance(unit_basis,var); 00047 } 00048 00049 //: Compute component of the cost function from given basis vector 00050 // Cost is log(variance) 00051 double mcal_var_basis_cost::cost_from_variance(const vnl_vector<double>& unit_basis, 00052 double variance) 00053 { 00054 return vcl_log(1e-8+variance); 00055 } 00056 00057 00058 //======================================================================= 00059 // Method: is_a 00060 //======================================================================= 00061 00062 vcl_string mcal_var_basis_cost::is_a() const 00063 { 00064 return vcl_string("mcal_var_basis_cost"); 00065 } 00066 00067 //======================================================================= 00068 // Method: version_no 00069 //======================================================================= 00070 00071 short mcal_var_basis_cost::version_no() const 00072 { 00073 return 1; 00074 } 00075 00076 //======================================================================= 00077 // Method: clone 00078 //======================================================================= 00079 00080 mcal_single_basis_cost* mcal_var_basis_cost::clone() const 00081 { 00082 return new mcal_var_basis_cost(*this); 00083 } 00084 00085 //======================================================================= 00086 // Method: print 00087 //======================================================================= 00088 00089 void mcal_var_basis_cost::print_summary(vcl_ostream& os) const 00090 { 00091 } 00092 00093 //======================================================================= 00094 // Method: save 00095 //======================================================================= 00096 00097 void mcal_var_basis_cost::b_write(vsl_b_ostream& bfs) const 00098 { 00099 vsl_b_write(bfs,version_no()); 00100 } 00101 00102 //======================================================================= 00103 // Method: load 00104 //======================================================================= 00105 00106 void mcal_var_basis_cost::b_read(vsl_b_istream& bfs) 00107 { 00108 short version; 00109 vsl_b_read(bfs,version); 00110 switch (version) 00111 { 00112 case (1): 00113 break; 00114 default: 00115 vcl_cerr << "mcal_var_basis_cost::b_read()\n" 00116 << "Unexpected version number " << version << vcl_endl; 00117 vcl_abort(); 00118 } 00119 } 00120 00121 //======================================================================= 00122 //: Read initialisation settings from a stream. 00123 // Parameters: 00124 // \verbatim 00125 // { 00126 // } 00127 // \endverbatim 00128 // \throw mbl_exception_parse_error if the parse fails. 00129 void mcal_var_basis_cost::config_from_stream(vcl_istream & is) 00130 { 00131 vcl_string s = mbl_parse_block(is); 00132 00133 vcl_istringstream ss(s); 00134 mbl_read_props_type props = mbl_read_props_ws(ss); 00135 00136 try 00137 { 00138 mbl_read_props_look_for_unused_props( 00139 "mcal_var_basis_cost::config_from_stream", props); 00140 } 00141 catch(mbl_exception_unused_props &e) 00142 { 00143 throw mbl_exception_parse_error(e.what()); 00144 } 00145 }