fn_det.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2009 NICTA
00002 // 
00003 // Authors:
00004 // - Conrad Sanderson (conradsand at ieee dot org)
00005 // 
00006 // This file is part of the Armadillo C++ library.
00007 // It is provided without any warranty of fitness
00008 // for any purpose. You can redistribute this file
00009 // and/or modify it under the terms of the GNU
00010 // Lesser General Public License (LGPL) as published
00011 // by the Free Software Foundation, either version 3
00012 // of the License or (at your option) any later version.
00013 // (see http://www.opensource.org/licenses for more info)
00014 
00015 
00016 //! \addtogroup fn_det
00017 //! @{
00018 
00019 template<typename T1> inline typename T1::elem_type det(const Base<typename T1::elem_type,T1>& X);
00020 template<typename T1> inline typename T1::elem_type det(const Op<T1, op_diagmat>& X);
00021 
00022 template<typename eT> inline eT det(const Op<Mat<eT>, op_diagmat_vec>& X);
00023 
00024 template<typename T1, typename T2> inline typename T1::elem_type det(const Glue<T1, T2, glue_times>& X);
00025 
00026 template<typename T1> inline typename T1::elem_type det(const Op<T1,op_inv>& in);
00027 template<typename T1> inline typename T1::elem_type det(const Op<T1,op_trans>& in);
00028 
00029 
00030 
00031 //! determinant of mat
00032 template<typename T1>
00033 inline
00034 typename T1::elem_type
00035 det(const Base<typename T1::elem_type,T1>& X)
00036   {
00037   arma_extra_debug_sigprint();
00038   
00039   typedef typename T1::elem_type eT;
00040   
00041   const unwrap<T1> A_tmp(X.get_ref());
00042   const Mat<eT>& A = A_tmp.M;
00043   
00044   arma_debug_check( !A.is_square(), "det(): matrix must be square" );
00045   
00046   return auxlib::det(A);
00047   }
00048 
00049 
00050 
00051 //! determinant of diagmat(mat)
00052 template<typename T1>
00053 inline
00054 typename T1::elem_type
00055 det(const Op<T1, op_diagmat>& X)
00056   {
00057   arma_extra_debug_sigprint();
00058 
00059   const unwrap<T1> A_tmp(X.m);
00060 
00061   typedef typename T1::elem_type eT;
00062   const Mat<eT>& A = A_tmp.M;
00063 
00064   arma_debug_check( (A.n_elem == 0), "det(): empty matrix");
00065   arma_debug_check( !A.is_square(), "det(): incompatible dimensions for diagmat operation" );
00066 
00067   eT val = A.at(0,0);
00068   
00069   for(u32 i=1; i<A.n_rows; ++i)
00070     {
00071     val *= A.at(i,i);
00072     }
00073   
00074   return val;
00075   }
00076 
00077 
00078 
00079 //! determinant of diagmat(colvec or rowvec)
00080 template<typename eT>
00081 inline
00082 eT
00083 det(const Op<Mat<eT>, op_diagmat_vec>& X)
00084   {
00085   arma_extra_debug_sigprint();
00086   
00087   const Mat<eT>& A = X.m;
00088   
00089   arma_debug_check( (A.n_elem == 0), "det(): empty matrix");
00090   arma_debug_check( !A.is_vec(), "det_diagvec(): internal error: can't interpret as a vector" );
00091 
00092   eT val = A.mem[0];
00093   
00094   for(u32 i=1; i<A.n_elem; ++i)
00095     {
00096     val *= A.mem[i];
00097     }
00098   
00099   return val;
00100   }
00101 
00102 
00103 
00104 //! determinant of A*B, avoiding the times operation if A and B are square matrices with the same dimensions
00105 template<typename T1, typename T2>
00106 inline
00107 typename T1::elem_type
00108 det(const Glue<T1,T2,glue_times>& X)
00109   {
00110   arma_extra_debug_sigprint();
00111   
00112   typedef typename T1::elem_type eT;
00113   
00114   const unwrap<T1> tmp1(X.A);
00115   const unwrap<T2> tmp2(X.B);
00116   
00117   const Mat<eT>& A = tmp1.M;
00118   const Mat<eT>& B = tmp2.M;
00119   
00120   if( (A.n_rows == A.n_cols) && (A.n_rows == B.n_rows) && (A.n_cols == B.n_cols) )
00121     {
00122     return det(A) * det(B);
00123     }
00124   else
00125     {
00126     return det(Mat<eT>(X));
00127     }
00128   
00129   }
00130 
00131 
00132 
00133 //! determinant of inv(A), without doing the inverse operation
00134 template<typename T1>
00135 inline
00136 typename T1::elem_type
00137 det(const Op<T1,op_inv>& in)
00138   {
00139   arma_extra_debug_sigprint();
00140   
00141   typedef typename T1::elem_type eT;
00142   isnt_fltpt<eT>::check();
00143   
00144   eT tmp = det(in.m);
00145   arma_debug_warn( (tmp == eT(0)), "det(): warning: determinant is zero" );
00146   
00147   return eT(1) / tmp;
00148   }
00149 
00150 
00151 
00152 //! determinant of trans(A)
00153 template<typename T1>
00154 inline
00155 typename T1::elem_type
00156 det(const Op<T1,op_trans>& in)
00157   {
00158   arma_extra_debug_sigprint();
00159   
00160   typedef typename T1::elem_type eT;
00161   
00162   const unwrap<T1> tmp(in.m);
00163   const Mat<eT>& X = tmp.M;
00164 
00165   return det(X);
00166   }
00167 
00168 
00169 
00170 //! @}