contrib/mul/mbl/mbl_mod_gram_schmidt.cxx
Go to the documentation of this file.
00001 // This is mul/mbl/mbl_mod_gram_schmidt.cxx
00002 #include "mbl_mod_gram_schmidt.h"
00003 //:
00004 // \file
00005 // \brief Orthogonalise a basis using modified Gram-Schmidt (and normalise)
00006 // \author Martin Roberts
00007 
00008 #include <vcl_vector.h>
00009 #include <vnl/vnl_vector.h>
00010 
00011 //=======================================================================
00012 //: Orthogonalise a basis using modified Gram-Schmidt
00013 // Transform basis {vk} to orthonormal basis {ek} with k in range 1..N
00014 // for j = 1 to N
00015 //     ej = vj
00016 //     for k = 1 to j-1
00017 //         ej = ej - <ej,ek>ek   //NB Classical GS has vj in inner product
00018 //     end
00019 //     ej = ej/|ej|
00020 //  end
00021 
00022 //: Convert input basis {v} to orthonormal basis {e}
00023 // Each basis vector is a column of v, and likewise the orthonormal bases are returned as columns of e
00024 void mbl_mod_gram_schmidt(const vnl_matrix<double>& v,
00025                           vnl_matrix<double>& e)
00026 {
00027     unsigned N=v.cols();
00028 
00029     //Note internally it is easier to deal with the basis as a vector of vnl_vectors
00030     //As matrices are stored row-wise
00031     vcl_vector<vnl_vector<double > > vbasis(N);
00032     vcl_vector<vnl_vector<double > > evecs(N);
00033 
00034     //Copy into more convenient holding storage as vector of vectors
00035     //And also initialise output basis to input
00036     for (unsigned jcol=0;jcol<N;++jcol)
00037     {
00038         evecs[jcol] = vbasis[jcol] = v.get_column(jcol);
00039     }
00040     evecs[0].normalize();
00041 
00042     for (unsigned j=1;j<N;++j)
00043     {
00044         //Loop over previously created bases and subtract off partial projections
00045         //Thus producing orthogonality
00046 
00047         unsigned n2 = j-1;
00048         for (unsigned k=0;k<=n2;++k)
00049         {
00050             evecs[j] -= dot_product(evecs[j],evecs[k]) * evecs[k];
00051         }
00052         evecs[j].normalize(); 
00053     }
00054 
00055     //And copy into column-wise matrix (kth base is the kth column)
00056     e.set_size(v.rows(),N);
00057     for (unsigned jcol=0;jcol<N;++jcol)
00058     {
00059         e.set_column(jcol,evecs[jcol]);
00060     }
00061 }