Lapack_Cholesky.h

00001 // -*- c++ -*-
00002 
00003 //     Copyright (C) 2009 Tom Drummond (twd20@cam.ac.uk)
00004 //
00005 // This file is part of the TooN Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 2, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // You should have received a copy of the GNU General Public License along
00017 // with this library; see the file COPYING.  If not, write to the Free
00018 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00019 // USA.
00020 
00021 // As a special exception, you may use this file as part of a free software
00022 // library without restriction.  Specifically, if other files instantiate
00023 // templates or use macros or inline functions from this file, or you compile
00024 // this file and link it with other files to produce an executable, this
00025 // file does not by itself cause the resulting executable to be covered by
00026 // the GNU General Public License.  This exception does not however
00027 // invalidate any other reasons why the executable file might be covered by
00028 // the GNU General Public License.
00029 
00030 
00031 #ifndef TOON_INCLUDE_CHOLESKY_H
00032 #define TOON_INCLUDE_CHOLESKY_H
00033 
00034 #include <TooN/TooN.h>
00035 
00036 namespace TooN {
00037 
00038 
00067 template <int Size, tyepname Precision>
00068 class Lapack_Cholesky {
00069 public:
00070 
00071     Lapack_Cholesky(){}
00072     
00073     template<class P2, class B2>
00074     Lapack_Cholesky(const Matrix<Size, Size, P2, B2>& m) {
00075         : my_cholesky(m) {
00076         SizeMismatch<Size,Size>::test(m.num_rows(), m.num_cols());
00077         do_compute();
00078     }
00079 
00081     Lapack_Cholesky(int size) : my_cholesky(size,size) {}
00082 
00083     template<class P2, class B2> void compute(const Matrix<Size, Size, P2, B2>& m){
00084         SizeMismatch<Size,Size>::test(m.num_rows(), m.num_cols());
00085         SizeMismatch<Size,Size>::test(m.num_rows(), my_cholesky.num_rows());
00086         my_cholesky=m;
00087         do_compute();
00088     }
00089 
00090 
00091 
00092     void do_compute(){
00093         int N = my_cholesky.num_rows();
00094         int info;
00095         dpotrf_("L", &N, L.get_data_ptr(), &N, &info);
00096         assert(info >= 0);
00097         if (info > 0) {
00098             my_rank = info-1;
00099         }
00100     }
00101 
00102     int rank() const { return my_rank; }
00103 
00104     template <int Size2, typename P2, typename B2>
00105         Vector<Size, Precision> backsub (const Vector<Size2, P2, B2>& v) {
00106         SizeMismatch<Size,Size2>::test(my_cholesky.num_cols(), v.size());
00107 
00108         Vector<Size> result(v);
00109         int N=L.num_rows();
00110         int NRHS=1;
00111         int info;
00112         dpotrs_("L", &N, &NRHS, my_cholesky.my_data, &N, result.my_data, &N, &info);     
00113         assert(info==0);
00114         return result;
00115     }
00116 
00117     template <int Size2, int Cols2, typename P2, typename B2>
00118         Matrix<Size, Cols2, Precision, ColMajor> backsub (const Matrix<Size2, Cols2, P2, B2>& m) {
00119         SizeMismatch<Size,Size2>::test(my_cholesky.num_cols(), m.num_rows());
00120 
00121         Matrix<Size, Cols2, Precision, ColMajor> result(m);
00122         int N=my_cholesky.num_rows();
00123         int NRHS=m.num_cols();
00124         int info;
00125         dpotrs_("L", &N, &NRHS, my_cholesky.my_data, &N, result.my_data, &N, &info);     
00126         assert(info==0);
00127         return result;
00128     }
00129 
00130 
00131 
00132 
00133 
00134     template <int Size2, typename P2, typename B2>
00135         Precision mahalanobis(const Vector<Size2, P2, B2>& v) const {
00136         return v * backsub(v);
00137     }
00138 
00139     const Matrix<>& get_L() const {
00140         return my_cholesky;
00141     }
00142 
00143     Precision determinant() const {
00144         Precision det = L[0][0];
00145         for (int i=1; i<my_cholesky.num_rows(); i++)
00146             det *= L[i][i];
00147         return det*det;
00148     }
00149 
00150     Matrix<> get_inverse() const {
00151         Matrix<Size> M(my_cholesky);
00152         int N = my_cholesky.num_rows();
00153         int info;
00154         dpotri_("L", &N, M.my_data, &N, &info);
00155         assert(info == 0);
00156         TooN::Symmetrize(M);
00157         return M;
00158     }
00159 
00160 private:
00161     Matrix<Size,Size,Precision> my_cholesky;     
00162     int rank;
00163 };
00164 
00165 
00166 }
00167 
00168 #endif

Generated on Thu May 7 20:28:40 2009 for TooN by  doxygen 1.5.3