$search
00001 // Copyright (C) 2008-2011 NICTA (www.nicta.com.au) 00002 // Copyright (C) 2008-2011 Conrad Sanderson 00003 // 00004 // This file is part of the Armadillo C++ library. 00005 // It is provided without any warranty of fitness 00006 // for any purpose. You can redistribute this file 00007 // and/or modify it under the terms of the GNU 00008 // Lesser General Public License (LGPL) as published 00009 // by the Free Software Foundation, either version 3 00010 // of the License or (at your option) any later version. 00011 // (see http://www.opensource.org/licenses for more info) 00012 00013 00016 00017 00019 template<typename eT> 00020 inline 00021 void 00022 op_inv::apply(Mat<eT>& out, const Mat<eT>& A, const bool slow) 00023 { 00024 arma_extra_debug_sigprint(); 00025 00026 // no need to check for aliasing, due to: 00027 // - auxlib::inv() copies A to out before inversion 00028 // - for 2x2 and 3x3 matrices the code is alias safe 00029 00030 bool status = auxlib::inv(out, A, slow); 00031 00032 if(status == false) 00033 { 00034 out.reset(); 00035 arma_bad("inv(): matrix appears to be singular"); 00036 } 00037 } 00038 00039 00040 00042 template<typename T1> 00043 inline 00044 void 00045 op_inv::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_inv>& X) 00046 { 00047 arma_extra_debug_sigprint(); 00048 00049 typedef typename T1::elem_type eT; 00050 00051 const strip_diagmat<T1> strip(X.m); 00052 00053 if(strip.do_diagmat == true) 00054 { 00055 op_inv::apply_diag(out, strip.M); 00056 } 00057 else 00058 { 00059 const uword mode = X.aux_uword_a; 00060 00061 const bool status = (mode == 0) ? auxlib::inv(out, X.m) : auxlib::inv(out, X.m, true); 00062 00063 if(status == false) 00064 { 00065 out.reset(); 00066 arma_bad("inv(): matrix appears to be singular"); 00067 } 00068 } 00069 } 00070 00071 00072 00073 template<typename T1> 00074 inline 00075 void 00076 op_inv::apply_diag(Mat<typename T1::elem_type>& out, const Base<typename T1::elem_type, T1>& X) 00077 { 00078 arma_extra_debug_sigprint(); 00079 00080 typedef typename T1::elem_type eT; 00081 00082 const diagmat_proxy_check<T1> A(X.get_ref(), out); 00083 00084 const uword N = A.n_elem; 00085 00086 out.set_size(N,N); 00087 00088 for(uword col=0; col<N; ++col) 00089 { 00090 for(uword row=0; row<col; ++row) { out.at(row,col) = eT(0); } 00091 00092 out.at(col,col) = eT(1) / A[col]; 00093 00094 for(uword row=col+1; row<N; ++row) { out.at(row,col) = eT(0); } 00095 } 00096 00097 } 00098 00099 00100 00102 template<typename T1> 00103 inline 00104 void 00105 op_inv_tr::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_inv_tr>& X) 00106 { 00107 arma_extra_debug_sigprint(); 00108 00109 const bool status = auxlib::inv_tr(out, X.m, X.aux_uword_a); 00110 00111 if(status == false) 00112 { 00113 out.reset(); 00114 arma_bad("inv(): matrix appears to be singular"); 00115 } 00116 } 00117 00118 00119 00121 template<typename T1> 00122 inline 00123 void 00124 op_inv_sympd::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_inv_sympd>& X) 00125 { 00126 arma_extra_debug_sigprint(); 00127 00128 const bool status = auxlib::inv_sympd(out, X.m, X.aux_uword_a); 00129 00130 if(status == false) 00131 { 00132 out.reset(); 00133 arma_bad("inv(): matrix appears to be singular"); 00134 } 00135 } 00136 00137 00138