Chris@49: // Copyright (C) 2008-2012 NICTA (www.nicta.com.au) Chris@49: // Copyright (C) 2008-2012 Conrad Sanderson Chris@49: // Copyright (C) 2012 Ryan Curtin Chris@49: // Chris@49: // This Source Code Form is subject to the terms of the Mozilla Public Chris@49: // License, v. 2.0. If a copy of the MPL was not distributed with this Chris@49: // file, You can obtain one at http://mozilla.org/MPL/2.0/. Chris@49: Chris@49: Chris@49: //! \addtogroup fn_trace Chris@49: //! @{ Chris@49: Chris@49: Chris@49: //! Immediate trace (sum of diagonal elements) of a square dense matrix Chris@49: template Chris@49: arma_hot Chris@49: arma_warn_unused Chris@49: inline Chris@49: typename enable_if2::value, typename T1::elem_type>::result Chris@49: trace(const T1& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: typedef typename T1::elem_type eT; Chris@49: Chris@49: const Proxy A(X); Chris@49: Chris@49: arma_debug_check( (A.get_n_rows() != A.get_n_cols()), "trace(): matrix must be square sized" ); Chris@49: Chris@49: const uword N = A.get_n_rows(); Chris@49: Chris@49: eT val1 = eT(0); Chris@49: eT val2 = eT(0); Chris@49: Chris@49: uword i,j; Chris@49: for(i=0, j=1; j Chris@49: arma_hot Chris@49: arma_warn_unused Chris@49: inline Chris@49: typename T1::elem_type Chris@49: trace(const Op& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: typedef typename T1::elem_type eT; Chris@49: Chris@49: const diagmat_proxy A(X.m); Chris@49: Chris@49: const uword N = A.n_elem; Chris@49: Chris@49: eT val = eT(0); Chris@49: Chris@49: for(uword i=0; i Chris@49: arma_hot Chris@49: inline Chris@49: typename T1::elem_type Chris@49: trace_mul_unwrap(const T1& XA, const T2& XB) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: typedef typename T1::elem_type eT; Chris@49: Chris@49: const Proxy PA(XA); Chris@49: const unwrap tmpB(XB); Chris@49: Chris@49: const Mat& B = tmpB.M; Chris@49: Chris@49: arma_debug_assert_mul_size(PA.get_n_rows(), PA.get_n_cols(), B.n_rows, B.n_cols, "matrix multiplication"); Chris@49: Chris@49: arma_debug_check( (PA.get_n_rows() != B.n_cols), "trace(): matrix must be square sized" ); Chris@49: Chris@49: const uword N1 = PA.get_n_rows(); // equivalent to B.n_cols, due to square size requirements Chris@49: const uword N2 = PA.get_n_cols(); // equivalent to B.n_rows, due to matrix multiplication requirements Chris@49: Chris@49: eT val = eT(0); Chris@49: Chris@49: for(uword i=0; i Chris@49: arma_hot Chris@49: inline Chris@49: typename T1::elem_type Chris@49: trace_mul_proxy(const T1& XA, const T2& XB) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: typedef typename T1::elem_type eT; Chris@49: Chris@49: const Proxy PA(XA); Chris@49: const Proxy PB(XB); Chris@49: Chris@49: if(is_Mat::stored_type>::value == true) Chris@49: { Chris@49: return trace_mul_unwrap(PA.Q, PB.Q); Chris@49: } Chris@49: Chris@49: arma_debug_assert_mul_size(PA.get_n_rows(), PA.get_n_cols(), PB.get_n_rows(), PB.get_n_cols(), "matrix multiplication"); Chris@49: Chris@49: arma_debug_check( (PA.get_n_rows() != PB.get_n_cols()), "trace(): matrix must be square sized" ); Chris@49: Chris@49: const uword N1 = PA.get_n_rows(); // equivalent to PB.get_n_cols(), due to square size requirements Chris@49: const uword N2 = PA.get_n_cols(); // equivalent to PB.get_n_rows(), due to matrix multiplication requirements Chris@49: Chris@49: eT val = eT(0); Chris@49: Chris@49: for(uword i=0; i Chris@49: arma_hot Chris@49: arma_warn_unused Chris@49: inline Chris@49: typename T1::elem_type Chris@49: trace(const Glue& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return (is_Mat::value) ? trace_mul_unwrap(X.A, X.B) : trace_mul_proxy(X.A, X.B); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! trace of sparse object Chris@49: template Chris@49: arma_hot Chris@49: arma_warn_unused Chris@49: inline Chris@49: typename enable_if2::value, typename T1::elem_type>::result Chris@49: trace(const T1& x) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const SpProxy p(x); Chris@49: Chris@49: arma_debug_check( (p.get_n_rows() != p.get_n_cols()), "trace(): matrix must be square sized" ); Chris@49: Chris@49: typedef typename T1::elem_type eT; Chris@49: Chris@49: eT result = eT(0); Chris@49: Chris@49: typename SpProxy::const_iterator_type it = p.begin(); Chris@49: typename SpProxy::const_iterator_type it_end = p.end(); Chris@49: Chris@49: while(it != it_end) Chris@49: { Chris@49: if(it.row() == it.col()) Chris@49: { Chris@49: result += (*it); Chris@49: } Chris@49: Chris@49: ++it; Chris@49: } Chris@49: Chris@49: return result; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! @}