contrib/mul/msm/msm_wt_mat_2d.cxx
Go to the documentation of this file.
00001 #include "msm_wt_mat_2d.h"
00002 //:
00003 // \file
00004 // \brief Represents 2x2 symmetric matrix, used as weight matrix
00005 // \author Tim Cootes
00006 
00007 #include <vsl/vsl_indent.h>
00008 #include <vsl/vsl_binary_io.h>
00009 #include <vcl_iostream.h>
00010 #include <vcl_cmath.h>
00011 
00012 //: Sets axis (eigenvector) of matrix and var along each
00013 //  Sets to s1*u*u' + s2*v*v', where u is the unit vector
00014 //  (u1 u2)/|u1,u2|, and v is the unit vector orthogonal to
00015 //  this.  u is then an eigenvector with associated eigenvalue s1,
00016 //  v is the other eigenvector, with eigenvalue s2
00017 void msm_wt_mat_2d::set_axes(double u1, double u2, double s1, double s2)
00018 {
00019   double uu = u1*u1, uv=u1*u2, vv=u2*u2;
00020   double L2=uu+vv;
00021   uu/=L2; uv/=L2; vv/=L2;  // Normalise to unit.
00022   // uu' = {uu uv; uv vv},  vv'={vv -uv; -uv uu}
00023   m11_ = s1*uu + s2*vv;
00024   m12_ = (s1-s2)*uv;
00025   m22_ = s1*vv + s2*uu;
00026 }
00027 
00028 //: Returns inverse (or pseudo-inverse)
00029 msm_wt_mat_2d msm_wt_mat_2d::inverse() const
00030 {
00031   double D=det();
00032   if (vcl_fabs(D)>1e-8)
00033     return msm_wt_mat_2d(m22_/D,-m12_/D,m11_/D);
00034 
00035   // Small det implies this = (u v)'*(u v)
00036   // Inverse can be shown to be this/(u^2+v^2) = this/(m11_+m22_)
00037   double s=1.0/(m11_+m22_);
00038   return msm_wt_mat_2d(s*m11_,s*vcl_sqrt(m11_*m22_),s*m22_);
00039 }
00040 
00041 //: Calculate eigenvalues
00042 void msm_wt_mat_2d::eigen_values(double& EV1, double& EV2)
00043 {
00044   double dac=m11_-m22_;
00045   double d=0.5*vcl_sqrt(dac*dac+4*m12_*m12_);
00046   double hac = 0.5*(m11_+m22_);
00047   EV1=hac+d;
00048   EV2=hac-d;
00049 }
00050 
00051 //: Calculates W2=T'WT where T is 2x2 matrix (a,-b;b,a)
00052 msm_wt_mat_2d msm_wt_mat_2d::transform_by(double a, double b) const
00053 {
00054   double a2=a*a,ab=a*b,b2=b*b;
00055   return msm_wt_mat_2d(a2*m11_+2*ab*m12_+b2*m22_,
00056                        (a2-b2)*m12_+ab*(m22_-m11_),
00057                        a2*m22_-2*ab*m12_+b2*m11_);
00058 }
00059 
00060 //: Post multiply by W
00061 msm_wt_mat_2d msm_wt_mat_2d::operator*(msm_wt_mat_2d& W) const
00062 {
00063   return msm_wt_mat_2d(m11_*W.m11()+m12_*W.m21(),
00064                        m11_*W.m21()+m12_*W.m22(),
00065                        m12_*W.m21()+m22_*W.m22());
00066 }
00067 
00068 //: Multiply this by scalar
00069 msm_wt_mat_2d& msm_wt_mat_2d::operator*=(double s)
00070 {
00071   m11_*=s;
00072   m12_*=s;
00073   m22_*=s;
00074   return *this;
00075 }
00076 
00077 //: Add W to this
00078 msm_wt_mat_2d& msm_wt_mat_2d::operator+=(const msm_wt_mat_2d& W)
00079 {
00080   m11_+=W.m11_;
00081   m12_+=W.m12_;
00082   m22_+=W.m22_;
00083   return *this;
00084 }
00085 
00086 //: Equality test
00087 bool msm_wt_mat_2d::operator==(const msm_wt_mat_2d& W)
00088 {
00089   return (vcl_fabs(m11_-W.m11_)<1e-8) &&
00090          (vcl_fabs(m12_-W.m12_)<1e-8) &&
00091          (vcl_fabs(m22_-W.m22_)<1e-8);
00092 }
00093 
00094 
00095 //=======================================================================
00096 // Method: print
00097 //=======================================================================
00098 
00099 void msm_wt_mat_2d::print_summary(vcl_ostream& os) const
00100 {
00101   os << "{ "<<m11_<<' '<<m12_<<" ; "<<m12_<<' '<<m22_<<" } ";
00102 }
00103 
00104 //=======================================================================
00105 // Method: save
00106 //=======================================================================
00107 void msm_wt_mat_2d::b_write(vsl_b_ostream& bfs) const
00108 {
00109   vsl_b_write(bfs,m11_);
00110   vsl_b_write(bfs,m12_);
00111   vsl_b_write(bfs,m22_);
00112 }
00113 
00114 //=======================================================================
00115 // Method: load
00116 //=======================================================================
00117 void msm_wt_mat_2d::b_read(vsl_b_istream& bfs)
00118 {
00119   vsl_b_read(bfs,m11_);
00120   vsl_b_read(bfs,m12_);
00121   vsl_b_read(bfs,m22_);
00122 }
00123 
00124 
00125 //=======================================================================
00126 // Associated function: operator<<
00127 //=======================================================================
00128 
00129 void vsl_b_write(vsl_b_ostream& bfs, const msm_wt_mat_2d& b)
00130 {
00131   b.b_write(bfs);
00132 }
00133 
00134 //=======================================================================
00135 // Associated function: operator>>
00136 //=======================================================================
00137 
00138 void vsl_b_read(vsl_b_istream& bfs, msm_wt_mat_2d& b)
00139 {
00140   b.b_read(bfs);
00141 }
00142 
00143 //=======================================================================
00144 // Associated function: operator<<
00145 //=======================================================================
00146 
00147 vcl_ostream& operator<<(vcl_ostream& os,const msm_wt_mat_2d& b)
00148 {
00149   b.print_summary(os);
00150   return os;
00151 }
00152 
00153 //: Stream output operator for class reference
00154 void vsl_print_summary(vcl_ostream& os,const msm_wt_mat_2d& b)
00155 {
00156  os << b;
00157 }