max@0: // Copyright (C) 2008-2011 NICTA (www.nicta.com.au) max@0: // Copyright (C) 2008-2011 Conrad Sanderson max@0: // max@0: // This file is part of the Armadillo C++ library. max@0: // It is provided without any warranty of fitness max@0: // for any purpose. You can redistribute this file max@0: // and/or modify it under the terms of the GNU max@0: // Lesser General Public License (LGPL) as published max@0: // by the Free Software Foundation, either version 3 max@0: // of the License or (at your option) any later version. max@0: // (see http://www.opensource.org/licenses for more info) max@0: max@0: max@0: //! \addtogroup diagmat_proxy max@0: //! @{ max@0: max@0: max@0: max@0: template max@0: class diagmat_proxy max@0: { max@0: public: max@0: max@0: typedef typename T1::elem_type elem_type; max@0: typedef typename get_pod_type::result pod_type; max@0: max@0: inline diagmat_proxy(const Base& X) max@0: : P ( X.get_ref() ) max@0: , P_is_vec( (P.get_n_rows() == 1) || (P.get_n_cols() == 1) ) max@0: , n_elem ( P_is_vec ? P.get_n_elem() : (std::min)(P.get_n_elem(), P.get_n_rows()) ) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_check max@0: ( max@0: (P_is_vec == false) && (P.get_n_rows() != P.get_n_cols()), max@0: "diagmat(): only vectors and square matrices are accepted" max@0: ); max@0: } max@0: max@0: max@0: arma_inline max@0: elem_type max@0: operator[](const uword i) const max@0: { max@0: if( (Proxy::prefer_at_accessor == true) || (P_is_vec == false) ) max@0: { max@0: return P.at(i,i); max@0: } max@0: else max@0: { max@0: return P[i]; max@0: } max@0: } max@0: max@0: max@0: arma_inline max@0: elem_type max@0: at(const uword row, const uword col) const max@0: { max@0: if(row == col) max@0: { max@0: if( (Proxy::prefer_at_accessor == true) || (P_is_vec == false) ) max@0: { max@0: return P.at(row,row); max@0: } max@0: else max@0: { max@0: return P[row]; max@0: } max@0: } max@0: else max@0: { max@0: return elem_type(0); max@0: } max@0: } max@0: max@0: max@0: const Proxy P; max@0: const bool P_is_vec; max@0: const uword n_elem; max@0: }; max@0: max@0: max@0: max@0: template max@0: class diagmat_proxy< Mat > max@0: { max@0: public: max@0: max@0: typedef eT elem_type; max@0: typedef typename get_pod_type::result pod_type; max@0: max@0: max@0: inline diagmat_proxy(const Mat& X) max@0: : P(X) max@0: , P_is_vec( (P.n_rows == 1) || (P.n_cols == 1) ) max@0: , n_elem( P_is_vec ? P.n_elem : (std::min)(P.n_elem, P.n_rows) ) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_check max@0: ( max@0: (P_is_vec == false) && (P.n_rows != P.n_cols), max@0: "diagmat(): only vectors and square matrices are accepted" max@0: ); max@0: } max@0: max@0: max@0: arma_inline elem_type operator[] (const uword i) const { return P_is_vec ? P[i] : P.at(i,i); } max@0: arma_inline elem_type at (const uword row, const uword col) const { return (row == col) ? ( P_is_vec ? P[row] : P.at(row,row) ) : elem_type(0); } max@0: max@0: const Mat& P; max@0: const bool P_is_vec; max@0: const uword n_elem; max@0: }; max@0: max@0: max@0: max@0: template max@0: class diagmat_proxy< Row > max@0: { max@0: public: max@0: max@0: typedef eT elem_type; max@0: typedef typename get_pod_type::result pod_type; max@0: max@0: max@0: inline diagmat_proxy(const Row& X) max@0: : P(X) max@0: , P_is_vec(true) max@0: , n_elem(P.n_elem) max@0: { max@0: arma_extra_debug_sigprint(); max@0: } max@0: max@0: max@0: arma_inline elem_type operator[] (const uword i) const { return P[i]; } max@0: arma_inline elem_type at (const uword row, const uword col) const { return (row == col) ? P[row] : elem_type(0); } max@0: max@0: max@0: const Row& P; max@0: const bool P_is_vec; max@0: const uword n_elem; max@0: }; max@0: max@0: max@0: max@0: template max@0: class diagmat_proxy< Col > max@0: { max@0: public: max@0: max@0: typedef eT elem_type; max@0: typedef typename get_pod_type::result pod_type; max@0: max@0: max@0: inline diagmat_proxy(const Col& X) max@0: : P(X) max@0: , P_is_vec(true) max@0: , n_elem(P.n_elem) max@0: { max@0: arma_extra_debug_sigprint(); max@0: } max@0: max@0: max@0: arma_inline elem_type operator[] (const uword i) const { return P[i]; } max@0: arma_inline elem_type at (const uword row, const uword col) const { return (row == col) ? P[row] : elem_type(0); } max@0: max@0: max@0: const Col& P; max@0: const bool P_is_vec; max@0: const uword n_elem; max@0: }; max@0: max@0: max@0: max@0: template max@0: class diagmat_proxy_check max@0: { max@0: public: max@0: max@0: typedef typename T1::elem_type elem_type; max@0: typedef typename get_pod_type::result pod_type; max@0: max@0: inline diagmat_proxy_check(const Base& X, const Mat& out) max@0: : P(X.get_ref()) max@0: , P_is_vec( (P.n_rows == 1) || (P.n_cols == 1) ) max@0: , n_elem( P_is_vec ? P.n_elem : (std::min)(P.n_elem, P.n_rows) ) max@0: { max@0: arma_extra_debug_sigprint(); max@0: arma_ignore(out); max@0: max@0: arma_debug_check max@0: ( max@0: (P_is_vec == false) && (P.n_rows != P.n_cols), max@0: "diagmat(): only vectors and square matrices are accepted" max@0: ); max@0: } max@0: max@0: max@0: arma_inline elem_type operator[] (const uword i) const { return P_is_vec ? P[i] : P.at(i,i); } max@0: arma_inline elem_type at (const uword row, const uword col) const { return (row == col) ? ( P_is_vec ? P[row] : P.at(row,row) ) : elem_type(0); } max@0: max@0: max@0: const Mat P; max@0: const bool P_is_vec; max@0: const uword n_elem; max@0: }; max@0: max@0: max@0: max@0: template max@0: class diagmat_proxy_check< Mat > max@0: { max@0: public: max@0: max@0: typedef eT elem_type; max@0: typedef typename get_pod_type::result pod_type; max@0: max@0: max@0: inline diagmat_proxy_check(const Mat& X, const Mat& out) max@0: : P_local ( (&X == &out) ? new Mat(X) : 0 ) max@0: , P ( (&X == &out) ? (*P_local) : X ) max@0: , P_is_vec( (P.n_rows == 1) || (P.n_cols == 1) ) max@0: , n_elem ( P_is_vec ? P.n_elem : (std::min)(P.n_elem, P.n_rows) ) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_check max@0: ( max@0: (P_is_vec == false) && (P.n_rows != P.n_cols), max@0: "diagmat(): only vectors and square matrices are accepted" max@0: ); max@0: } max@0: max@0: inline ~diagmat_proxy_check() max@0: { max@0: if(P_local) max@0: { max@0: delete P_local; max@0: } max@0: } max@0: max@0: max@0: arma_inline elem_type operator[] (const uword i) const { return P_is_vec ? P[i] : P.at(i,i); } max@0: arma_inline elem_type at (const uword row, const uword col) const { return (row == col) ? ( P_is_vec ? P[row] : P.at(row,row) ) : elem_type(0); } max@0: max@0: max@0: const Mat* P_local; max@0: const Mat& P; max@0: const bool P_is_vec; max@0: const uword n_elem; max@0: }; max@0: max@0: max@0: max@0: template max@0: class diagmat_proxy_check< Row > max@0: { max@0: public: max@0: max@0: typedef eT elem_type; max@0: typedef typename get_pod_type::result pod_type; max@0: max@0: inline diagmat_proxy_check(const Row& X, const Mat& out) max@0: : P_local ( (&X == reinterpret_cast*>(&out)) ? new Row(X) : 0 ) max@0: , P ( (&X == reinterpret_cast*>(&out)) ? (*P_local) : X ) max@0: , P_is_vec(true) max@0: , n_elem (P.n_elem) max@0: { max@0: arma_extra_debug_sigprint(); max@0: } max@0: max@0: max@0: inline ~diagmat_proxy_check() max@0: { max@0: if(P_local) max@0: { max@0: delete P_local; max@0: } max@0: } max@0: max@0: max@0: arma_inline elem_type operator[] (const uword i) const { return P[i]; } max@0: arma_inline elem_type at (const uword row, const uword col) const { return (row == col) ? P[row] : elem_type(0); } max@0: max@0: max@0: const Row* P_local; max@0: const Row& P; max@0: const bool P_is_vec; max@0: const uword n_elem; max@0: }; max@0: max@0: max@0: max@0: max@0: max@0: max@0: template max@0: class diagmat_proxy_check< Col > max@0: { max@0: public: max@0: max@0: typedef eT elem_type; max@0: typedef typename get_pod_type::result pod_type; max@0: max@0: inline diagmat_proxy_check(const Col& X, const Mat& out) max@0: : P_local ( (&X == reinterpret_cast*>(&out)) ? new Col(X) : 0 ) max@0: , P ( (&X == reinterpret_cast*>(&out)) ? (*P_local) : X ) max@0: , P_is_vec(true) max@0: , n_elem (P.n_elem) max@0: { max@0: arma_extra_debug_sigprint(); max@0: } max@0: max@0: max@0: inline ~diagmat_proxy_check() max@0: { max@0: if(P_local) max@0: { max@0: delete P_local; max@0: } max@0: } max@0: max@0: max@0: arma_inline elem_type operator[] (const uword i) const { return P[i]; } max@0: arma_inline elem_type at (const uword row, const uword col) const { return (row == col) ? P[row] : elem_type(0); } max@0: max@0: max@0: const Col* P_local; max@0: const Col& P; max@0: const bool P_is_vec; max@0: const uword n_elem; max@0: }; max@0: max@0: max@0: max@0: //! @}