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_diagvec Chris@49: //! @{ Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: void Chris@49: op_diagvec::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 uword a = X.aux_uword_a; Chris@49: const uword b = X.aux_uword_b; Chris@49: Chris@49: const uword row_offset = (b > 0) ? a : 0; Chris@49: const uword col_offset = (b == 0) ? a : 0; 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: arma_debug_check Chris@49: ( Chris@49: ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), Chris@49: "diagvec(): requested diagonal is out of bounds" Chris@49: ); Chris@49: Chris@49: const uword len = (std::min)(n_rows - row_offset, n_cols - col_offset); Chris@49: Chris@49: if(is_Mat::stored_type>::value) Chris@49: { Chris@49: op_diagvec::apply_unwrap(out, P.Q, row_offset, col_offset, len); Chris@49: } Chris@49: else Chris@49: { Chris@49: if(P.is_alias(out) == false) Chris@49: { Chris@49: op_diagvec::apply_proxy(out, P, row_offset, col_offset, len); Chris@49: } Chris@49: else Chris@49: { Chris@49: Mat tmp; Chris@49: Chris@49: op_diagvec::apply_proxy(tmp, P, row_offset, col_offset, len); Chris@49: Chris@49: out.steal_mem(tmp); Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: arma_hot Chris@49: inline Chris@49: void Chris@49: op_diagvec::apply_unwrap(Mat& out, const T1& X, const uword row_offset, const uword col_offset, const uword len) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: typedef typename T1::elem_type eT; Chris@49: Chris@49: const unwrap_check tmp_A(X, out); Chris@49: const Mat& A = tmp_A.M; Chris@49: Chris@49: out.set_size(len, 1); Chris@49: Chris@49: eT* out_mem = out.memptr(); Chris@49: Chris@49: uword i,j; Chris@49: for(i=0, j=1; j < len; i+=2, j+=2) Chris@49: { Chris@49: const eT tmp_i = A.at( i + row_offset, i + col_offset ); Chris@49: const eT tmp_j = A.at( j + row_offset, j + col_offset ); Chris@49: Chris@49: out_mem[i] = tmp_i; Chris@49: out_mem[j] = tmp_j; Chris@49: } Chris@49: Chris@49: if(i < len) Chris@49: { Chris@49: out_mem[i] = A.at( i + row_offset, i + col_offset ); Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: arma_hot Chris@49: inline Chris@49: void Chris@49: op_diagvec::apply_proxy(Mat& out, const Proxy& P, const uword row_offset, const uword col_offset, const uword len) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: typedef typename T1::elem_type eT; Chris@49: Chris@49: out.set_size(len, 1); Chris@49: Chris@49: eT* out_mem = out.memptr(); Chris@49: Chris@49: uword i,j; Chris@49: for(i=0, j=1; j < len; i+=2, j+=2) Chris@49: { Chris@49: const eT tmp_i = P.at( i + row_offset, i + col_offset ); Chris@49: const eT tmp_j = P.at( j + row_offset, j + col_offset ); Chris@49: Chris@49: out_mem[i] = tmp_i; Chris@49: out_mem[j] = tmp_j; Chris@49: } Chris@49: Chris@49: if(i < len) Chris@49: { Chris@49: out_mem[i] = P.at( i + row_offset, i + col_offset ); Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! @}