Chris@49: // Copyright (C) 2008-2012 NICTA (www.nicta.com.au) Chris@49: // Copyright (C) 2008-2012 Conrad Sanderson 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 op_diagmat Chris@49: //! @{ Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: void Chris@49: op_diagmat::apply(Mat& out, 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 Proxy P(X.m); Chris@49: Chris@49: const uword n_rows = P.get_n_rows(); Chris@49: const uword n_cols = P.get_n_cols(); Chris@49: Chris@49: const bool P_is_vec = (n_rows == 1) || (n_cols == 1); Chris@49: Chris@49: Chris@49: if(P.is_alias(out) == false) Chris@49: { Chris@49: if(P_is_vec) // generate a diagonal matrix out of a vector Chris@49: { Chris@49: const uword N = (n_rows == 1) ? n_cols : n_rows; Chris@49: Chris@49: out.zeros(N, N); Chris@49: Chris@49: if(Proxy::prefer_at_accessor == false) Chris@49: { Chris@49: typename Proxy::ea_type P_ea = P.get_ea(); Chris@49: Chris@49: for(uword i=0; i < N; ++i) { out.at(i,i) = P_ea[i]; } Chris@49: } Chris@49: else Chris@49: { Chris@49: if(n_rows == 1) Chris@49: { Chris@49: for(uword i=0; i < N; ++i) { out.at(i,i) = P.at(0,i); } Chris@49: } Chris@49: else Chris@49: { Chris@49: for(uword i=0; i < N; ++i) { out.at(i,i) = P.at(i,0); } Chris@49: } Chris@49: } Chris@49: } Chris@49: else // generate a diagonal matrix out of a matrix Chris@49: { Chris@49: arma_debug_check( (n_rows != n_cols), "diagmat(): given matrix is not square" ); Chris@49: Chris@49: out.zeros(n_rows, n_rows); Chris@49: Chris@49: for(uword i=0; i < n_rows; ++i) { out.at(i,i) = P.at(i,i); } Chris@49: } Chris@49: } Chris@49: else // we have aliasing Chris@49: { Chris@49: if(P_is_vec) // generate a diagonal matrix out of a vector Chris@49: { Chris@49: const uword N = (n_rows == 1) ? n_cols : n_rows; Chris@49: Chris@49: podarray tmp(N); Chris@49: eT* tmp_mem = tmp.memptr(); Chris@49: Chris@49: if(Proxy::prefer_at_accessor == false) Chris@49: { Chris@49: typename Proxy::ea_type P_ea = P.get_ea(); Chris@49: Chris@49: for(uword i=0; i < N; ++i) { tmp_mem[i] = P_ea[i]; } Chris@49: } Chris@49: else Chris@49: { Chris@49: if(n_rows == 1) Chris@49: { Chris@49: for(uword i=0; i < N; ++i) { tmp_mem[i] = P.at(0,i); } Chris@49: } Chris@49: else Chris@49: { Chris@49: for(uword i=0; i < N; ++i) { tmp_mem[i] = P.at(i,0); } Chris@49: } Chris@49: } Chris@49: Chris@49: out.zeros(N, N); Chris@49: Chris@49: for(uword i=0; i < N; ++i) { out.at(i,i) = tmp_mem[i]; } Chris@49: } Chris@49: else // generate a diagonal matrix out of a matrix Chris@49: { Chris@49: arma_debug_check( (n_rows != n_cols), "diagmat(): given matrix is not square" ); Chris@49: Chris@49: if( (Proxy::has_subview == false) && (Proxy::fake_mat == false) ) Chris@49: { Chris@49: // NOTE: we have aliasing and it's not due to a subview, hence we're assuming that the output matrix already has the correct size Chris@49: Chris@49: for(uword i=0; i < n_rows; ++i) Chris@49: { Chris@49: const eT val = P.at(i,i); Chris@49: Chris@49: arrayops::inplace_set(out.colptr(i), eT(0), n_rows); Chris@49: Chris@49: out.at(i,i) = val; Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: podarray tmp(n_rows); Chris@49: eT* tmp_mem = tmp.memptr(); Chris@49: Chris@49: for(uword i=0; i < n_rows; ++i) { tmp_mem[i] = P.at(i,i); } Chris@49: Chris@49: out.zeros(n_rows, n_rows); Chris@49: Chris@49: for(uword i=0; i < n_rows; ++i) { out.at(i,i) = tmp_mem[i]; } Chris@49: } Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! @}