ublasTools.h

Go to the documentation of this file.
00001 // ----------------------------------------------------------------------------
00002 //
00003 // $Id$
00004 //
00005 // Copyright 2008, 2009, 2010, 2011, 2012  Antonio Franchi and Paolo Stegagno
00006 //
00007 // This file is part of MIP.
00008 //
00009 // MIP is free software: you can redistribute it and/or modify
00010 // it under the terms of the GNU General Public License as published by
00011 // the Free Software Foundation, either version 3 of the License, or
00012 // (at your option) any later version.
00013 //
00014 // MIP is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU General Public License
00020 // along with MIP. If not, see <http://www.gnu.org/licenses/>.
00021 //
00022 // Contact info: antonio.franchi@tuebingen.mpg.de stegagno@diag.uniroma1.it
00023 //
00024 // ----------------------------------------------------------------------------
00025  
00026 #ifndef __UBLAS_TOOLS_H__
00027 #define __UBLAS_TOOLS_H__
00028  
00029  
00030  // The following code inverts the matrix input using LU-decomposition
00031  // with backsubstitution of unit vectors.
00032  // Reference: Numerical Recipies in C, 2nd ed., by Press, Teukolsky, Vetterling & Flannery.
00033  //
00034  // http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?action=browse&diff=1&id=LU_Matrix_Inversion
00035  // Hope someone finds this useful. Regards, Fredrik Orderud.
00036 
00037  #include <boost/numeric/ublas/vector.hpp>
00038  #include <boost/numeric/ublas/vector_proxy.hpp>
00039  #include <boost/numeric/ublas/matrix.hpp>
00040  #include <boost/numeric/ublas/triangular.hpp>
00041  #include <boost/numeric/ublas/lu.hpp>
00042  #include <boost/numeric/ublas/io.hpp>
00043  namespace ublas = boost::numeric::ublas;
00044  
00045  // Matrix inversion routine.
00046  // Uses lu_factorize and lu_substitute in uBLAS to invert a matrix
00047  template<class T>
00048  bool invert (const ublas::matrix<T>& input, ublas::matrix<T>& inverse) {
00049    using namespace boost::numeric::ublas;
00050    typedef permutation_matrix<std::size_t> pmatrix;
00051    // create a working copy of the input
00052    matrix<T> A(input);
00053    // create a permutation matrix for the LU-factorization
00054    pmatrix pm(A.size1());
00055   
00056    // perform LU-factorization
00057    int res = lu_factorize(A,pm);
00058    if( res != 0 ) return false;
00059  
00060    // create identity matrix of "inverse"
00061    inverse.assign(ublas::identity_matrix<T>(A.size1()));
00062  
00063    // backsubstitute to get the inverse
00064    lu_substitute(A, pm, inverse);
00065  
00066    return true;
00067  }
00068  
00069  template<class T>
00070  boost::numeric::ublas::matrix<T>
00071  invert(const boost::numeric::ublas::matrix<T> &m, bool &is_singular)
00072  { 
00073     ublas::matrix<T> inv_m (m.size1(), m.size2());
00074     is_singular = ! invert (m, inv_m);
00075     return inv_m;
00076  }
00077  // http://archives.free.net.ph/message/20080909.064313.59c122c4.fr.html 
00078  template<class matrix_T>
00079  double determinant(ublas::matrix_expression<matrix_T> const& mat_r) {
00080    double det = 1.0;
00081    matrix_T mLu(mat_r());
00082    ublas::permutation_matrix<std::size_t> pivots(mat_r().size1() );
00083    bool is_singular = lu_factorize(mLu, pivots);
00084    if (!is_singular) {
00085      for (std::size_t i = 0; i < pivots.size(); ++i) {
00086        if (pivots(i) != i) {
00087          det *= -1.0;
00088        }
00089        det *= mLu(i,i);
00090      }
00091    } else {
00092      det = 0.0;
00093    }
00094    return det;
00095  } 
00096  
00097 #endif
00098 

Generated on Mon Feb 20 07:01:07 2017 for MIP by  doxygen 1.5.6