core/vnl/algo/vnl_scatter_3x3.txx
Go to the documentation of this file.
00001 // This is core/vnl/algo/vnl_scatter_3x3.txx
00002 #ifndef vnl_scatter_3x3_txx_
00003 #define vnl_scatter_3x3_txx_
00004 //:
00005 // \file
00006 // \author Andrew W. Fitzgibbon, Oxford RRG
00007 // Created: 02 Oct 96
00008 //-----------------------------------------------------------------------------
00009 
00010 #include "vnl_scatter_3x3.h"
00011 #include <vcl_iostream.h>
00012 #include <vnl/algo/vnl_symmetric_eigensystem.h>
00013 
00014 template <class T>
00015 vnl_scatter_3x3<T>::vnl_scatter_3x3()
00016   : base(T(0))
00017   , symmetricp(true)
00018   , eigenvectors_currentp(false)
00019 {
00020 }
00021 
00022 template <class T>
00023 void vnl_scatter_3x3<T>::add_outer_product(const vnl_vector_fixed<T,3> & v)
00024 {
00025   vnl_scatter_3x3<T> & S = *this;
00026   for (int i = 0; i < 3; ++i) {
00027     S(i,i) +=  v[i]*v[i];
00028     for (int j = i+1; j < 3; ++j) {
00029       T value = v[i]*v[j];
00030       S(i,j) += value;
00031       S(j,i) = S(i,j);
00032     }
00033   }
00034 }
00035 
00036 template <class T>
00037 void vnl_scatter_3x3<T>::add_outer_product(const vnl_vector_fixed<T,3> & u,
00038                                            const vnl_vector_fixed<T,3> & v)
00039 {
00040   vnl_scatter_3x3<T> & S = *this;
00041   for (int i = 0; i < 3; ++i)
00042     for (int j = 0; j < 3; ++j)
00043       S(i,j) += v[i]*u[j];
00044   symmetricp = false; // conservative assumption -- use add_outer_product(v) to maintain symmetry
00045 }
00046 
00047 template <class T>
00048 void vnl_scatter_3x3<T>::sub_outer_product(const vnl_vector_fixed<T,3> & v)
00049 {
00050   vnl_scatter_3x3<T> & S = *this;
00051   for (int i = 0; i < 3; ++i) {
00052     S(i,i) -=  v[i]*v[i];
00053     for (int j = i+1; j < 3; ++j) {
00054       T value = v[i]*v[j];
00055       S(i,j) -= value;
00056       S(j,i) = S(i,j);
00057     }
00058   }
00059 }
00060 
00061 template <class T>
00062 void vnl_scatter_3x3<T>::sub_outer_product(const vnl_vector_fixed<T,3> & u,
00063                                            const vnl_vector_fixed<T,3> & v)
00064 {
00065   vnl_scatter_3x3<T> & S = *this;
00066   for (int i = 0; i < 3; ++i)
00067     for (int j = 0; j < 3; ++j)
00068       S(i,j) -= v[i]*u[j];
00069   symmetricp = false; // conservative assumption -- use sub_outer_product(v) to maintain symmetry
00070 }
00071 
00072 template <class T>
00073 void vnl_scatter_3x3<T>::force_symmetric()
00074 {
00075   if (symmetricp)
00076     return;
00077   vnl_scatter_3x3<T> & S = *this;
00078   for (int i = 0; i < 3; ++i)
00079     for (int j = i+1; j < 3; ++j) {
00080       T vbar = (S(i,j) + S(j,i)) / 2;
00081       S(i,j) = S(j,i) = vbar;
00082     }
00083   symmetricp = true;
00084 }
00085 
00086 template <class T>
00087 void vnl_scatter_3x3<T>::compute_eigensystem()
00088 {
00089   vnl_scatter_3x3<T> &S = *this;
00090   vnl_matrix<T> M = S.as_matrix();
00091   if (symmetricp) {
00092     vnl_symmetric_eigensystem_compute(M, V_.as_ref().non_const(), D.as_ref().non_const());
00093   }
00094   else {
00095     vcl_cerr << "Asymmetric scatter not handled now\n";
00096   }
00097 
00098   eigenvectors_currentp = true;
00099 }
00100 
00101 //--------------------------------------------------------------------------------
00102 
00103 #define VNL_SCATTER_3X3_INSTANTIATE(T) \
00104 template class vnl_scatter_3x3<T >
00105 
00106 #endif // vnl_scatter_3x3_txx_