LinearAlgebra.H

Go to the documentation of this file.
00001 /*!@file Image/LinearAlgebra.H */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00005 // by the University of Southern California (USC) and the iLab at USC.  //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Rob Peters <rjpeters@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Image/LinearAlgebra.H $
00035 // $Id: LinearAlgebra.H 5744 2005-10-18 23:30:18Z rjpeters $
00036 //
00037 
00038 #ifndef IMAGE_LINEARALGEBRA_H_DEFINED
00039 #define IMAGE_LINEARALGEBRA_H_DEFINED
00040 
00041 #include "Image/LinearAlgebraFlags.H"
00042 #include "Util/Promotions.H"
00043 
00044 template <class T> class Image;
00045 
00046 //! Compute the singular decomposition of M: M = U * S * V^T
00047 /*! The U, S, V matrices have special properties:
00048 
00049     - U is column-orthogonal, such that (U^T * U) = I
00050     - S is square, diagonal, so that S is easily invertible
00051     - V is square and orthogonal, so (V^T * V) = (V * V^T) = I
00052 
00053     Note that these properties mean that the svd can be used to
00054     compute the pseudo-inverse of a general matrix M:
00055 
00056     - M = U*S*V^T
00057     - U^T*M = S*V^T  (since U is column-orthogonal)
00058     - S^-1*U^T*M = V^T  (since S is diagonal and invertible)
00059     - V*S^-1*U^T*M = I  (since V is square and orthogonal)
00060 
00061     by definition, pinv(M)*M = I, therefore
00062 
00063     - V*S^-1*U^T = pinv(M)
00064 
00065     (Note ^T is used to designate the matrix transpose, and ^-1 is
00066     used to designate the matrix inverse).
00067 
00068     You can use the routine svdPseudoInv to compute the pseudo-inverse
00069     using just this method.
00070 */
00071 void svd(const Image<double>& M,
00072          Image<double>& U, Image<double>& S, Image<double>& V,
00073          SvdAlgo algo, const SvdFlag flags = 0);
00074 
00075 //! Single-precision counterpart of svd()
00076 void svdf(const Image<float>& M,
00077           Image<float>& U, Image<float>& S, Image<float>& V,
00078           SvdAlgo algo, const SvdFlag flags = 0);
00079 
00080 //! Compute the pseudo-inverse using the method described in svd()
00081 /*! Optionally throw out small values from the diagonal S matrix --
00082     this helps numerical stability.
00083 
00084     The number of eigenvalues retained is controlled by tolfactor. If
00085     tolfactor is less than 1.0, then it serves as a multiplier of the
00086     largest eigenvalue, below which any smaller eigenvalues are thrown
00087     out. If tolfactor is greater than 1.0, then the integer portion of
00088     tolfactor specifies the number of eigenvalues to be retained.
00089 
00090     If rank is a non-null pointer, then the rank of the diagonal
00091     matrix (after setting small values to zero) will be returned
00092     through that pointer. */
00093 Image<double> svdPseudoInv(const Image<double>& x,
00094                            const SvdAlgo algo,
00095                            int* const rank = 0,
00096                            const double tolfactor = 1.0e-8);
00097 
00098 //! Single-precision counterpart of svdPseudoInv()
00099 Image<float> svdPseudoInvf(const Image<float>& x,
00100                            const SvdAlgo algo,
00101                            int* const rank = 0,
00102                            const float tolfactor = 1.0e-8f);
00103 
00104 //! NOTE that this procedure is called "naive, unstable" for a reason!
00105 /*! This procedure computes the pseudo-inverse using the direct
00106     formula pinv(M) = (M^T * M)^-1 * M^T. The formula is analytically
00107     correct, but in practice it can be numerically unstable. Indeed it
00108     might work just fine for your matrix, but to be safe you'll need
00109     to check the identity pinv(M)*M ~= I -- for example, do
00110     RMSerr(matrixMult(M,pinv(M)), eye<float>(M.getHeight())) and make
00111     sure that it's small (say, less than 0.01 or so). If you do get a
00112     large RMS error, then you can consider using svdPseudoInv()
00113     instead, which offers more numerical stability. */
00114 template <class T>
00115 Image<typename promote_trait<T, float>::TP>
00116 naiveUnstablePseudoInv(const Image<T>& M);
00117 
00118 // ######################################################################
00119 /* So things look consistent in everyone's emacs... */
00120 /* Local Variables: */
00121 /* indent-tabs-mode: nil */
00122 /* End: */
00123 
00124 #endif // IMAGE_LINEARALGEBRA_H_DEFINED
Generated on Sun May 8 08:40:55 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3