Chris@49: // Copyright (C) 2008-2013 NICTA (www.nicta.com.au) Chris@49: // Copyright (C) 2008-2013 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 Mat Chris@49: //! @{ Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: Mat::~Mat() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: if(mem_state == 0) Chris@49: { Chris@49: if(n_elem > arma_config::mat_prealloc) Chris@49: { Chris@49: memory::release( access::rw(mem) ); Chris@49: } Chris@49: } Chris@49: Chris@49: if(arma_config::debug == true) Chris@49: { Chris@49: // try to expose buggy user code that accesses deleted objects Chris@49: access::rw(mem) = 0; Chris@49: } Chris@49: Chris@49: arma_type_check(( is_supported_elem_type::value == false )); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: Mat::Mat() Chris@49: : n_rows(0) Chris@49: , n_cols(0) Chris@49: , n_elem(0) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! construct the matrix to have user specified dimensions Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const uword in_n_rows, const uword in_n_cols) Chris@49: : n_rows(in_n_rows) Chris@49: , n_cols(in_n_cols) Chris@49: , n_elem(in_n_rows*in_n_cols) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: init_cold(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! constructor used by Row and Col classes Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const arma_vec_indicator&, const uhword in_vec_state) Chris@49: : n_rows( (in_vec_state == 2) ? 1 : 0 ) Chris@49: , n_cols( (in_vec_state == 1) ? 1 : 0 ) Chris@49: , n_elem(0) Chris@49: , vec_state(in_vec_state) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! constructor used by Row and Col classes Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const arma_vec_indicator&, const uword in_n_rows, const uword in_n_cols, const uhword in_vec_state) Chris@49: : n_rows(in_n_rows) Chris@49: , n_cols(in_n_cols) Chris@49: , n_elem(in_n_rows*in_n_cols) Chris@49: , vec_state(in_vec_state) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: init_cold(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const arma_fixed_indicator&, const uword in_n_rows, const uword in_n_cols, const uhword in_vec_state, const eT* in_mem) Chris@49: : n_rows (in_n_rows) Chris@49: , n_cols (in_n_cols) Chris@49: , n_elem (in_n_rows*in_n_cols) Chris@49: , vec_state (in_vec_state) Chris@49: , mem_state (3) Chris@49: , mem (in_mem) Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::init_cold() Chris@49: { Chris@49: arma_extra_debug_sigprint( arma_boost::format("n_rows = %d, n_cols = %d") % n_rows % n_cols ); Chris@49: Chris@49: // ensure that n_elem can hold the result of (n_rows * n_cols) Chris@49: Chris@49: arma_debug_check Chris@49: ( Chris@49: ( Chris@49: ( (n_rows > ARMA_MAX_UHWORD) || (n_cols > ARMA_MAX_UHWORD) ) Chris@49: ? ( (float(n_rows) * float(n_cols)) > float(ARMA_MAX_UWORD) ) Chris@49: : false Chris@49: ), Chris@49: "Mat::init(): requested size is too large" Chris@49: ); Chris@49: Chris@49: if(n_elem <= arma_config::mat_prealloc) Chris@49: { Chris@49: access::rw(mem) = mem_local; Chris@49: } Chris@49: else Chris@49: { Chris@49: arma_extra_debug_print("Mat::init(): allocating memory"); Chris@49: Chris@49: access::rw(mem) = memory::acquire(n_elem); Chris@49: Chris@49: arma_check_bad_alloc( (mem == 0), "Mat::init(): out of memory" ); Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! internal matrix construction; if the requested size is small enough, memory from the stack is used. otherwise memory is allocated via 'new' Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::init_warm(uword in_n_rows, uword in_n_cols) Chris@49: { Chris@49: arma_extra_debug_sigprint( arma_boost::format("in_n_rows = %d, in_n_cols = %d") % in_n_rows % in_n_cols ); Chris@49: Chris@49: if( (n_rows == in_n_rows) && (n_cols == in_n_cols) ) Chris@49: { Chris@49: return; Chris@49: } Chris@49: Chris@49: bool err_state = false; Chris@49: char* err_msg = 0; Chris@49: Chris@49: const uhword t_vec_state = vec_state; Chris@49: const uhword t_mem_state = mem_state; Chris@49: Chris@49: arma_debug_set_error Chris@49: ( Chris@49: err_state, Chris@49: err_msg, Chris@49: (t_mem_state == 3), Chris@49: "Mat::init(): size is fixed and hence cannot be changed" Chris@49: ); Chris@49: Chris@49: if(t_vec_state > 0) Chris@49: { Chris@49: if( (in_n_rows == 0) && (in_n_cols == 0) ) Chris@49: { Chris@49: if(t_vec_state == 1) Chris@49: { Chris@49: in_n_cols = 1; Chris@49: } Chris@49: else Chris@49: if(t_vec_state == 2) Chris@49: { Chris@49: in_n_rows = 1; Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: arma_debug_set_error Chris@49: ( Chris@49: err_state, Chris@49: err_msg, Chris@49: ( ((t_vec_state == 1) && (in_n_cols != 1)) || ((t_vec_state == 2) && (in_n_rows != 1)) ), Chris@49: "Mat::init(): object is a row or column vector; requested size is not compatible" Chris@49: ); Chris@49: } Chris@49: } Chris@49: Chris@49: // ensure that n_elem can hold the result of (n_rows * n_cols) Chris@49: Chris@49: arma_debug_set_error Chris@49: ( Chris@49: err_state, Chris@49: err_msg, Chris@49: ( Chris@49: ( (in_n_rows > ARMA_MAX_UHWORD) || (in_n_cols > ARMA_MAX_UHWORD) ) Chris@49: ? ( (float(in_n_rows) * float(in_n_cols)) > float(ARMA_MAX_UWORD) ) Chris@49: : false Chris@49: ), Chris@49: "Mat::init(): requested size is too large" Chris@49: ); Chris@49: Chris@49: arma_debug_check(err_state, err_msg); Chris@49: Chris@49: const uword old_n_elem = n_elem; Chris@49: const uword new_n_elem = in_n_rows * in_n_cols; Chris@49: Chris@49: if(old_n_elem == new_n_elem) Chris@49: { Chris@49: arma_extra_debug_print("Mat::init(): reusing memory"); Chris@49: Chris@49: access::rw(n_rows) = in_n_rows; Chris@49: access::rw(n_cols) = in_n_cols; Chris@49: } Chris@49: else Chris@49: { Chris@49: arma_debug_check Chris@49: ( Chris@49: (t_mem_state == 2), Chris@49: "Mat::init(): mismatch between size of auxiliary memory and requested size" Chris@49: ); Chris@49: Chris@49: if(t_mem_state == 0) Chris@49: { Chris@49: if(old_n_elem > arma_config::mat_prealloc) Chris@49: { Chris@49: arma_extra_debug_print("Mat::init(): freeing memory"); Chris@49: Chris@49: memory::release( access::rw(mem) ); Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: if(new_n_elem <= arma_config::mat_prealloc) Chris@49: { Chris@49: access::rw(mem) = mem_local; Chris@49: } Chris@49: else Chris@49: { Chris@49: arma_extra_debug_print("Mat::init(): allocating memory"); Chris@49: Chris@49: access::rw(mem) = memory::acquire(new_n_elem); Chris@49: Chris@49: arma_check_bad_alloc( (mem == 0), "Mat::init(): out of memory" ); Chris@49: } Chris@49: Chris@49: access::rw(n_rows) = in_n_rows; Chris@49: access::rw(n_cols) = in_n_cols; Chris@49: access::rw(n_elem) = new_n_elem; Chris@49: access::rw(mem_state) = 0; Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! create the matrix from a textual description Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const char* text) Chris@49: : n_rows(0) Chris@49: , n_cols(0) Chris@49: , n_elem(0) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: init( std::string(text) ); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! create the matrix from a textual description Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator=(const char* text) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: init( std::string(text) ); Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! create the matrix from a textual description Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const std::string& text) Chris@49: : n_rows(0) Chris@49: , n_cols(0) Chris@49: , n_elem(0) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: init(text); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! create the matrix from a textual description Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator=(const std::string& text) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: init(text); Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! internal function to create the matrix from a textual description Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::init(const std::string& text) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: // Chris@49: // work out the size Chris@49: Chris@49: uword t_n_rows = 0; Chris@49: uword t_n_cols = 0; Chris@49: Chris@49: bool t_n_cols_found = false; Chris@49: Chris@49: std::string token; Chris@49: Chris@49: std::string::size_type line_start = 0; Chris@49: std::string::size_type line_end = 0; Chris@49: Chris@49: while( line_start < text.length() ) Chris@49: { Chris@49: Chris@49: line_end = text.find(';', line_start); Chris@49: Chris@49: if(line_end == std::string::npos) Chris@49: line_end = text.length()-1; Chris@49: Chris@49: std::string::size_type line_len = line_end - line_start + 1; Chris@49: std::stringstream line_stream( text.substr(line_start,line_len) ); Chris@49: Chris@49: Chris@49: uword line_n_cols = 0; Chris@49: while(line_stream >> token) Chris@49: { Chris@49: ++line_n_cols; Chris@49: } Chris@49: Chris@49: Chris@49: if(line_n_cols > 0) Chris@49: { Chris@49: if(t_n_cols_found == false) Chris@49: { Chris@49: t_n_cols = line_n_cols; Chris@49: t_n_cols_found = true; Chris@49: } Chris@49: else Chris@49: arma_check( (line_n_cols != t_n_cols), "Mat::init(): inconsistent number of columns in given string"); Chris@49: Chris@49: ++t_n_rows; Chris@49: } Chris@49: line_start = line_end+1; Chris@49: Chris@49: } Chris@49: Chris@49: Mat& x = *this; Chris@49: x.set_size(t_n_rows, t_n_cols); Chris@49: Chris@49: line_start = 0; Chris@49: line_end = 0; Chris@49: Chris@49: uword urow = 0; Chris@49: Chris@49: while( line_start < text.length() ) Chris@49: { Chris@49: Chris@49: line_end = text.find(';', line_start); Chris@49: Chris@49: if(line_end == std::string::npos) Chris@49: line_end = text.length()-1; Chris@49: Chris@49: std::string::size_type line_len = line_end - line_start + 1; Chris@49: std::stringstream line_stream( text.substr(line_start,line_len) ); Chris@49: Chris@49: // uword ucol = 0; Chris@49: // while(line_stream >> token) Chris@49: // { Chris@49: // x.at(urow,ucol) = strtod(token.c_str(), 0); Chris@49: // ++ucol; Chris@49: // } Chris@49: Chris@49: uword ucol = 0; Chris@49: eT val; Chris@49: while(line_stream >> val) Chris@49: { Chris@49: x.at(urow,ucol) = val; Chris@49: ++ucol; Chris@49: } Chris@49: Chris@49: ++urow; Chris@49: line_start = line_end+1; Chris@49: } Chris@49: Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! create the matrix from std::vector Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const std::vector& x) Chris@49: : n_rows(uword(x.size())) Chris@49: , n_cols(1) Chris@49: , n_elem(uword(x.size())) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: init_cold(); Chris@49: Chris@49: if(n_elem > 0) Chris@49: { Chris@49: arrayops::copy( memptr(), &(x[0]), n_elem ); Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! create the matrix from std::vector Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator=(const std::vector& x) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: init_warm(uword(x.size()), 1); Chris@49: Chris@49: if(x.size() > 0) Chris@49: { Chris@49: arrayops::copy( memptr(), &(x[0]), uword(x.size()) ); Chris@49: } Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: #if defined(ARMA_USE_CXX11) Chris@49: Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const std::initializer_list& list) Chris@49: : n_rows(0) Chris@49: , n_cols(0) Chris@49: , n_elem(0) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: init(list); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator=(const std::initializer_list& list) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: init(list); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: #endif Chris@49: Chris@49: Chris@49: Chris@49: //! Set the matrix to be equal to the specified scalar. Chris@49: //! NOTE: the size of the matrix will be 1x1 Chris@49: template Chris@49: arma_inline Chris@49: const Mat& Chris@49: Mat::operator=(const eT val) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: init_warm(1,1); Chris@49: access::rw(mem[0]) = val; Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! In-place addition of a scalar to all elements of the matrix Chris@49: template Chris@49: arma_inline Chris@49: const Mat& Chris@49: Mat::operator+=(const eT val) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arrayops::inplace_plus( memptr(), val, n_elem ); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! In-place subtraction of a scalar from all elements of the matrix Chris@49: template Chris@49: arma_inline Chris@49: const Mat& Chris@49: Mat::operator-=(const eT val) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arrayops::inplace_minus( memptr(), val, n_elem ); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! In-place multiplication of all elements of the matrix with a scalar Chris@49: template Chris@49: arma_inline Chris@49: const Mat& Chris@49: Mat::operator*=(const eT val) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arrayops::inplace_mul( memptr(), val, n_elem ); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! In-place division of all elements of the matrix with a scalar Chris@49: template Chris@49: arma_inline Chris@49: const Mat& Chris@49: Mat::operator/=(const eT val) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arrayops::inplace_div( memptr(), val, n_elem ); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! construct a matrix from a given matrix Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const Mat& in_mat) Chris@49: : n_rows(in_mat.n_rows) Chris@49: , n_cols(in_mat.n_cols) Chris@49: , n_elem(in_mat.n_elem) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint(arma_boost::format("this = %x in_mat = %x") % this % &in_mat); Chris@49: Chris@49: init_cold(); Chris@49: Chris@49: arrayops::copy( memptr(), in_mat.mem, in_mat.n_elem ); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! construct a matrix from a given matrix Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator=(const Mat& in_mat) Chris@49: { Chris@49: arma_extra_debug_sigprint(arma_boost::format("this = %x in_mat = %x") % this % &in_mat); Chris@49: Chris@49: if(this != &in_mat) Chris@49: { Chris@49: init_warm(in_mat.n_rows, in_mat.n_cols); Chris@49: Chris@49: arrayops::copy( memptr(), in_mat.mem, in_mat.n_elem ); Chris@49: } Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: #if defined(ARMA_USE_CXX11) Chris@49: Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::init(const std::initializer_list& list) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const uword N = list.size(); Chris@49: Chris@49: set_size(1, N); Chris@49: Chris@49: arrayops::copy( memptr(), list.begin(), N ); Chris@49: } Chris@49: Chris@49: #endif Chris@49: Chris@49: Chris@49: Chris@49: //! for constructing a complex matrix out of two non-complex matrices Chris@49: template Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::init Chris@49: ( Chris@49: const Base::pod_type, T1>& X, Chris@49: const Base::pod_type, T2>& Y Chris@49: ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: typedef typename T1::elem_type T; Chris@49: Chris@49: arma_type_check(( is_complex::value == false )); //!< compile-time abort if eT isn't std::complex Chris@49: arma_type_check(( is_complex< T>::value == true )); //!< compile-time abort if T is std::complex Chris@49: Chris@49: arma_type_check(( is_same_type< std::complex, eT >::value == false )); //!< compile-time abort if types are not compatible Chris@49: Chris@49: const Proxy PX(X.get_ref()); Chris@49: const Proxy PY(Y.get_ref()); Chris@49: Chris@49: arma_debug_assert_same_size(PX, PY, "Mat()"); Chris@49: Chris@49: const uword local_n_rows = PX.get_n_rows(); Chris@49: const uword local_n_cols = PX.get_n_cols(); Chris@49: Chris@49: init_warm(local_n_rows, local_n_cols); Chris@49: Chris@49: eT* out_mem = (*this).memptr(); Chris@49: Chris@49: const bool prefer_at_accessor = ( Proxy::prefer_at_accessor || Proxy::prefer_at_accessor ); Chris@49: Chris@49: if(prefer_at_accessor == false) Chris@49: { Chris@49: typedef typename Proxy::ea_type ea_type1; Chris@49: typedef typename Proxy::ea_type ea_type2; Chris@49: Chris@49: const uword N = n_elem; Chris@49: Chris@49: ea_type1 A = PX.get_ea(); Chris@49: ea_type2 B = PY.get_ea(); Chris@49: Chris@49: for(uword ii=0; ii < N; ++ii) Chris@49: { Chris@49: out_mem[ii] = std::complex(A[ii], B[ii]); Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: for(uword ucol=0; ucol < local_n_cols; ++ucol) Chris@49: for(uword urow=0; urow < local_n_rows; ++urow) Chris@49: { Chris@49: *out_mem = std::complex(PX.at(urow,ucol), PY.at(urow,ucol)); Chris@49: out_mem++; Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! EXPERIMENTAL: swap the contents of this matrix, denoted as matrix A, with given matrix B Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::swap(Mat& B) Chris@49: { Chris@49: Mat& A = (*this); Chris@49: Chris@49: arma_extra_debug_sigprint(arma_boost::format("A = %x B = %x") % &A % &B); Chris@49: Chris@49: arma_debug_check( (A.vec_state != B.vec_state), "Mat::swap(): incompatible object types" ); Chris@49: Chris@49: const uhword A_mem_state = A.mem_state; Chris@49: const uhword B_mem_state = B.mem_state; Chris@49: Chris@49: if( (A_mem_state == 0) && (B_mem_state == 0) ) Chris@49: { Chris@49: const uword A_n_elem = A.n_elem; Chris@49: const uword B_n_elem = B.n_elem; Chris@49: Chris@49: const bool A_use_local_mem = (A_n_elem <= arma_config::mat_prealloc); Chris@49: const bool B_use_local_mem = (B_n_elem <= arma_config::mat_prealloc); Chris@49: Chris@49: if( (A_use_local_mem == false) && (B_use_local_mem == false) ) Chris@49: { Chris@49: std::swap( access::rw(A.mem), access::rw(B.mem) ); Chris@49: } Chris@49: else Chris@49: if( (A_use_local_mem == true) && (B_use_local_mem == true) ) Chris@49: { Chris@49: const uword N = (std::max)(A_n_elem, B_n_elem); Chris@49: Chris@49: eT* A_mem = A.memptr(); Chris@49: eT* B_mem = B.memptr(); Chris@49: Chris@49: for(uword ii=0; ii < N; ++ii) { std::swap( A_mem[ii], B_mem[ii] ); } Chris@49: } Chris@49: else Chris@49: if( (A_use_local_mem == true) && (B_use_local_mem == false) ) Chris@49: { Chris@49: eT* A_mem_local = &(A.mem_local[0]); Chris@49: eT* B_mem_local = &(B.mem_local[0]); Chris@49: Chris@49: arrayops::copy(B_mem_local, A_mem_local, A_n_elem); Chris@49: Chris@49: access::rw(A.mem) = B.mem; Chris@49: access::rw(B.mem) = B_mem_local; Chris@49: } Chris@49: else Chris@49: if( (A_use_local_mem == false) && (B_use_local_mem == true) ) Chris@49: { Chris@49: eT* A_mem_local = &(A.mem_local[0]); Chris@49: eT* B_mem_local = &(B.mem_local[0]); Chris@49: Chris@49: arrayops::copy(A_mem_local, B_mem_local, B_n_elem); Chris@49: Chris@49: access::rw(B.mem) = A.mem; Chris@49: access::rw(A.mem) = A_mem_local; Chris@49: } Chris@49: Chris@49: std::swap( access::rw(A.n_rows), access::rw(B.n_rows) ); Chris@49: std::swap( access::rw(A.n_cols), access::rw(B.n_cols) ); Chris@49: std::swap( access::rw(A.n_elem), access::rw(B.n_elem) ); Chris@49: } Chris@49: else Chris@49: if( (A_mem_state == 3) && (B_mem_state == 3) ) Chris@49: { Chris@49: arma_debug_check( ((A.n_rows != B.n_rows) || (A.n_cols != B.n_cols)), "Mat::swap(): incompatible object types" ); Chris@49: Chris@49: const uword N = A.n_elem; Chris@49: Chris@49: eT* A_mem = A.memptr(); Chris@49: eT* B_mem = B.memptr(); Chris@49: Chris@49: for(uword ii=0; ii < N; ++ii) { std::swap(A_mem[ii], B_mem[ii]); } Chris@49: } Chris@49: else Chris@49: { Chris@49: arma_bad("Mat::swap(): incompatible object types"); Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! try to steal the memory from a given matrix; Chris@49: //! if memory can't be stolen, copy the given matrix Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::steal_mem(Mat& x) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(this != &x) Chris@49: { Chris@49: const uword x_n_rows = x.n_rows; Chris@49: const uword x_n_cols = x.n_cols; Chris@49: const uword x_n_elem = x.n_elem; Chris@49: const uword x_vec_state = x.vec_state; Chris@49: const uword x_mem_state = x.mem_state; Chris@49: Chris@49: const uword t_vec_state = vec_state; Chris@49: Chris@49: bool layout_ok = false; Chris@49: Chris@49: if(t_vec_state == x_vec_state) Chris@49: { Chris@49: layout_ok = true; Chris@49: } Chris@49: else Chris@49: { Chris@49: if( (t_vec_state == 1) && ( x_n_cols == 1) ) Chris@49: { Chris@49: layout_ok = true; Chris@49: } Chris@49: Chris@49: if( (t_vec_state == 2) && ( x_n_rows == 1) ) Chris@49: { Chris@49: layout_ok = true; Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: if( (x_mem_state == 0) && (x_n_elem > arma_config::mat_prealloc) && (layout_ok == true) ) Chris@49: { Chris@49: reset(); Chris@49: // note: calling reset() also prevents fixed size matrices from changing size or using non-local memory Chris@49: Chris@49: access::rw(n_rows) = x_n_rows; Chris@49: access::rw(n_cols) = x_n_cols; Chris@49: access::rw(n_elem) = x_n_elem; Chris@49: access::rw(mem) = x.mem; Chris@49: Chris@49: access::rw(x.n_rows) = 0; Chris@49: access::rw(x.n_cols) = 0; Chris@49: access::rw(x.n_elem) = 0; Chris@49: access::rw(x.mem) = 0; Chris@49: } Chris@49: else Chris@49: { Chris@49: (*this).operator=(x); Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! construct a matrix from a given auxiliary array of eTs. Chris@49: //! if copy_aux_mem is true, new memory is allocated and the array is copied. Chris@49: //! if copy_aux_mem is false, the auxiliary array is used directly (without allocating memory and copying). Chris@49: //! the default is to copy the array. Chris@49: Chris@49: template Chris@49: inline Chris@49: Mat::Mat(eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const bool copy_aux_mem, const bool strict) Chris@49: : n_rows ( aux_n_rows ) Chris@49: , n_cols ( aux_n_cols ) Chris@49: , n_elem ( aux_n_rows*aux_n_cols ) Chris@49: , vec_state( 0 ) Chris@49: , mem_state( copy_aux_mem ? 0 : ( strict ? 2 : 1 ) ) Chris@49: , mem ( copy_aux_mem ? 0 : aux_mem ) Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: if(copy_aux_mem == true) Chris@49: { Chris@49: init_cold(); Chris@49: Chris@49: arrayops::copy( memptr(), aux_mem, n_elem ); Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! construct a matrix from a given auxiliary read-only array of eTs. Chris@49: //! the array is copied. Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols) Chris@49: : n_rows(aux_n_rows) Chris@49: , n_cols(aux_n_cols) Chris@49: , n_elem(aux_n_rows*aux_n_cols) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: init_cold(); Chris@49: Chris@49: arrayops::copy( memptr(), aux_mem, n_elem ); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! DANGEROUS! Construct a temporary matrix, using auxiliary memory. Chris@49: //! This constructor is NOT intended for usage by user code. Chris@49: //! Its sole purpose is to be used by the Cube class. Chris@49: Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const char junk, const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols) Chris@49: : n_rows (aux_n_rows ) Chris@49: , n_cols (aux_n_cols ) Chris@49: , n_elem (aux_n_rows*aux_n_cols) Chris@49: , vec_state(0 ) Chris@49: , mem_state(3 ) Chris@49: , mem (aux_mem ) Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: arma_ignore(junk); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place matrix addition Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator+=(const Mat& m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_assert_same_size(*this, m, "addition"); Chris@49: Chris@49: arrayops::inplace_plus( memptr(), m.memptr(), n_elem ); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place matrix subtraction Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator-=(const Mat& m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_assert_same_size(*this, m, "subtraction"); Chris@49: Chris@49: arrayops::inplace_minus( memptr(), m.memptr(), n_elem ); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place matrix multiplication Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator*=(const Mat& m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: glue_times::apply_inplace(*this, m); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place element-wise matrix multiplication Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator%=(const Mat& m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_assert_same_size(*this, m, "element-wise multiplication"); Chris@49: Chris@49: arrayops::inplace_mul( memptr(), m.memptr(), n_elem ); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place element-wise matrix division Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator/=(const Mat& m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_assert_same_size(*this, m, "element-wise division"); Chris@49: Chris@49: arrayops::inplace_div( memptr(), m.memptr(), n_elem ); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const BaseCube& X) Chris@49: : n_rows(0) Chris@49: , n_cols(0) Chris@49: , n_elem(0) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: (*this).operator=(X); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator=(const BaseCube& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: Mat& out = *this; Chris@49: Chris@49: const unwrap_cube tmp(X.get_ref()); Chris@49: const Cube& in = tmp.M; Chris@49: Chris@49: arma_debug_assert_cube_as_mat(out, in, "copy into matrix", false); Chris@49: Chris@49: const uword in_n_rows = in.n_rows; Chris@49: const uword in_n_cols = in.n_cols; Chris@49: const uword in_n_slices = in.n_slices; Chris@49: Chris@49: const uword out_vec_state = out.vec_state; Chris@49: Chris@49: if(in_n_slices == 1) Chris@49: { Chris@49: out.set_size(in_n_rows, in_n_cols); Chris@49: Chris@49: for(uword ucol=0; ucol < in_n_cols; ++ucol) Chris@49: { Chris@49: arrayops::copy( out.colptr(ucol), in.slice_colptr(0, ucol), in_n_rows ); Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: if(out_vec_state == 0) Chris@49: { Chris@49: if(in_n_cols == 1) Chris@49: { Chris@49: out.set_size(in_n_rows, in_n_slices); Chris@49: Chris@49: for(uword i=0; i < in_n_slices; ++i) Chris@49: { Chris@49: arrayops::copy( out.colptr(i), in.slice_colptr(i, 0), in_n_rows ); Chris@49: } Chris@49: } Chris@49: else Chris@49: if(in_n_rows == 1) Chris@49: { Chris@49: out.set_size(in_n_cols, in_n_slices); Chris@49: Chris@49: for(uword slice=0; slice < in_n_slices; ++slice) Chris@49: { Chris@49: eT* out_colptr = out.colptr(slice); Chris@49: Chris@49: uword i,j; Chris@49: for(i=0, j=1; j < in_n_cols; i+=2, j+=2) Chris@49: { Chris@49: const eT tmp_i = in.at(0, i, slice); Chris@49: const eT tmp_j = in.at(0, j, slice); Chris@49: Chris@49: out_colptr[i] = tmp_i; Chris@49: out_colptr[j] = tmp_j; Chris@49: } Chris@49: Chris@49: if(i < in_n_cols) Chris@49: { Chris@49: out_colptr[i] = in.at(0, i, slice); Chris@49: } Chris@49: } Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: out.set_size(in_n_slices); Chris@49: Chris@49: eT* out_mem = out.memptr(); Chris@49: Chris@49: for(uword i=0; i Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator+=(const BaseCube& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: Mat& out = *this; Chris@49: Chris@49: const unwrap_cube tmp(X.get_ref()); Chris@49: const Cube& in = tmp.M; Chris@49: Chris@49: arma_debug_assert_cube_as_mat(out, in, "addition", true); Chris@49: Chris@49: const uword in_n_rows = in.n_rows; Chris@49: const uword in_n_cols = in.n_cols; Chris@49: const uword in_n_slices = in.n_slices; Chris@49: Chris@49: const uword out_n_rows = out.n_rows; Chris@49: const uword out_n_cols = out.n_cols; Chris@49: const uword out_vec_state = out.vec_state; Chris@49: Chris@49: if(in_n_slices == 1) Chris@49: { Chris@49: for(uword ucol=0; ucol < in_n_cols; ++ucol) Chris@49: { Chris@49: arrayops::inplace_plus( out.colptr(ucol), in.slice_colptr(0, ucol), in_n_rows ); Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: if(out_vec_state == 0) Chris@49: { Chris@49: if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) ) Chris@49: { Chris@49: for(uword i=0; i < in_n_slices; ++i) Chris@49: { Chris@49: arrayops::inplace_plus( out.colptr(i), in.slice_colptr(i, 0), in_n_rows ); Chris@49: } Chris@49: } Chris@49: else Chris@49: if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) ) Chris@49: { Chris@49: for(uword slice=0; slice < in_n_slices; ++slice) Chris@49: { Chris@49: eT* out_colptr = out.colptr(slice); Chris@49: Chris@49: uword i,j; Chris@49: for(i=0, j=1; j < in_n_cols; i+=2, j+=2) Chris@49: { Chris@49: const eT tmp_i = in.at(0, i, slice); Chris@49: const eT tmp_j = in.at(0, j, slice); Chris@49: Chris@49: out_colptr[i] += tmp_i; Chris@49: out_colptr[j] += tmp_j; Chris@49: } Chris@49: Chris@49: if(i < in_n_cols) Chris@49: { Chris@49: out_colptr[i] += in.at(0, i, slice); Chris@49: } Chris@49: } Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: eT* out_mem = out.memptr(); Chris@49: Chris@49: for(uword i=0; i Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator-=(const BaseCube& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: Mat& out = *this; Chris@49: Chris@49: const unwrap_cube tmp(X.get_ref()); Chris@49: const Cube& in = tmp.M; Chris@49: Chris@49: arma_debug_assert_cube_as_mat(out, in, "subtraction", true); Chris@49: Chris@49: const uword in_n_rows = in.n_rows; Chris@49: const uword in_n_cols = in.n_cols; Chris@49: const uword in_n_slices = in.n_slices; Chris@49: Chris@49: const uword out_n_rows = out.n_rows; Chris@49: const uword out_n_cols = out.n_cols; Chris@49: const uword out_vec_state = out.vec_state; Chris@49: Chris@49: if(in_n_slices == 1) Chris@49: { Chris@49: for(uword ucol=0; ucol < in_n_cols; ++ucol) Chris@49: { Chris@49: arrayops::inplace_minus( out.colptr(ucol), in.slice_colptr(0, ucol), in_n_rows ); Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: if(out_vec_state == 0) Chris@49: { Chris@49: if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) ) Chris@49: { Chris@49: for(uword i=0; i < in_n_slices; ++i) Chris@49: { Chris@49: arrayops::inplace_minus( out.colptr(i), in.slice_colptr(i, 0), in_n_rows ); Chris@49: } Chris@49: } Chris@49: else Chris@49: if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) ) Chris@49: { Chris@49: for(uword slice=0; slice < in_n_slices; ++slice) Chris@49: { Chris@49: eT* out_colptr = out.colptr(slice); Chris@49: Chris@49: uword i,j; Chris@49: for(i=0, j=1; j < in_n_cols; i+=2, j+=2) Chris@49: { Chris@49: const eT tmp_i = in.at(0, i, slice); Chris@49: const eT tmp_j = in.at(0, j, slice); Chris@49: Chris@49: out_colptr[i] -= tmp_i; Chris@49: out_colptr[j] -= tmp_j; Chris@49: } Chris@49: Chris@49: if(i < in_n_cols) Chris@49: { Chris@49: out_colptr[i] -= in.at(0, i, slice); Chris@49: } Chris@49: } Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: eT* out_mem = out.memptr(); Chris@49: Chris@49: for(uword i=0; i Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator*=(const BaseCube& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const Mat B(X); Chris@49: Chris@49: (*this).operator*=(B); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator%=(const BaseCube& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: Mat& out = *this; Chris@49: Chris@49: const unwrap_cube tmp(X.get_ref()); Chris@49: const Cube& in = tmp.M; Chris@49: Chris@49: arma_debug_assert_cube_as_mat(out, in, "element-wise multiplication", true); Chris@49: Chris@49: const uword in_n_rows = in.n_rows; Chris@49: const uword in_n_cols = in.n_cols; Chris@49: const uword in_n_slices = in.n_slices; Chris@49: Chris@49: const uword out_n_rows = out.n_rows; Chris@49: const uword out_n_cols = out.n_cols; Chris@49: const uword out_vec_state = out.vec_state; Chris@49: Chris@49: if(in_n_slices == 1) Chris@49: { Chris@49: for(uword ucol=0; ucol < in_n_cols; ++ucol) Chris@49: { Chris@49: arrayops::inplace_mul( out.colptr(ucol), in.slice_colptr(0, ucol), in_n_rows ); Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: if(out_vec_state == 0) Chris@49: { Chris@49: if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) ) Chris@49: { Chris@49: for(uword i=0; i < in_n_slices; ++i) Chris@49: { Chris@49: arrayops::inplace_mul( out.colptr(i), in.slice_colptr(i, 0), in_n_rows ); Chris@49: } Chris@49: } Chris@49: else Chris@49: if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) ) Chris@49: { Chris@49: for(uword slice=0; slice < in_n_slices; ++slice) Chris@49: { Chris@49: eT* out_colptr = out.colptr(slice); Chris@49: Chris@49: uword i,j; Chris@49: for(i=0, j=1; j < in_n_cols; i+=2, j+=2) Chris@49: { Chris@49: const eT tmp_i = in.at(0, i, slice); Chris@49: const eT tmp_j = in.at(0, j, slice); Chris@49: Chris@49: out_colptr[i] *= tmp_i; Chris@49: out_colptr[j] *= tmp_j; Chris@49: } Chris@49: Chris@49: if(i < in_n_cols) Chris@49: { Chris@49: out_colptr[i] *= in.at(0, i, slice); Chris@49: } Chris@49: } Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: eT* out_mem = out.memptr(); Chris@49: Chris@49: for(uword i=0; i Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator/=(const BaseCube& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: Mat& out = *this; Chris@49: Chris@49: const unwrap_cube tmp(X.get_ref()); Chris@49: const Cube& in = tmp.M; Chris@49: Chris@49: arma_debug_assert_cube_as_mat(out, in, "element-wise division", true); Chris@49: Chris@49: const uword in_n_rows = in.n_rows; Chris@49: const uword in_n_cols = in.n_cols; Chris@49: const uword in_n_slices = in.n_slices; Chris@49: Chris@49: const uword out_n_rows = out.n_rows; Chris@49: const uword out_n_cols = out.n_cols; Chris@49: const uword out_vec_state = out.vec_state; Chris@49: Chris@49: if(in_n_slices == 1) Chris@49: { Chris@49: for(uword ucol=0; ucol < in_n_cols; ++ucol) Chris@49: { Chris@49: arrayops::inplace_div( out.colptr(ucol), in.slice_colptr(0, ucol), in_n_rows ); Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: if(out_vec_state == 0) Chris@49: { Chris@49: if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) ) Chris@49: { Chris@49: for(uword i=0; i < in_n_slices; ++i) Chris@49: { Chris@49: arrayops::inplace_div( out.colptr(i), in.slice_colptr(i, 0), in_n_rows ); Chris@49: } Chris@49: } Chris@49: else Chris@49: if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) ) Chris@49: { Chris@49: for(uword slice=0; slice < in_n_slices; ++slice) Chris@49: { Chris@49: eT* out_colptr = out.colptr(slice); Chris@49: Chris@49: uword i,j; Chris@49: for(i=0, j=1; j < in_n_cols; i+=2, j+=2) Chris@49: { Chris@49: const eT tmp_i = in.at(0, i, slice); Chris@49: const eT tmp_j = in.at(0, j, slice); Chris@49: Chris@49: out_colptr[i] /= tmp_i; Chris@49: out_colptr[j] /= tmp_j; Chris@49: } Chris@49: Chris@49: if(i < in_n_cols) Chris@49: { Chris@49: out_colptr[i] /= in.at(0, i, slice); Chris@49: } Chris@49: } Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: eT* out_mem = out.memptr(); Chris@49: Chris@49: for(uword i=0; i Chris@49: template Chris@49: inline Chris@49: Mat::Mat Chris@49: ( Chris@49: const Base::pod_type,T1>& A, Chris@49: const Base::pod_type,T2>& B Chris@49: ) Chris@49: : n_rows(0) Chris@49: , n_cols(0) Chris@49: , n_elem(0) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: init(A,B); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! construct a matrix from subview (e.g. construct a matrix from a delayed submatrix operation) Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const subview& X) Chris@49: : n_rows(X.n_rows) Chris@49: , n_cols(X.n_cols) Chris@49: , n_elem(X.n_elem) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: init_cold(); Chris@49: Chris@49: subview::extract(*this, X); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! construct a matrix from subview (e.g. construct a matrix from a delayed submatrix operation) Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator=(const subview& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const bool alias = (this == &(X.m)); Chris@49: Chris@49: if(alias == false) Chris@49: { Chris@49: init_warm(X.n_rows, X.n_cols); Chris@49: Chris@49: subview::extract(*this, X); Chris@49: } Chris@49: else Chris@49: { Chris@49: Mat tmp(X); Chris@49: Chris@49: steal_mem(tmp); Chris@49: } Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: //! in-place matrix addition (using a submatrix on the right-hand-side) Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator+=(const subview& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: subview::plus_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: //! in-place matrix subtraction (using a submatrix on the right-hand-side) Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator-=(const subview& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: subview::minus_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place matrix mutiplication (using a submatrix on the right-hand-side) Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator*=(const subview& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: glue_times::apply_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place element-wise matrix mutiplication (using a submatrix on the right-hand-side) Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator%=(const subview& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: subview::schur_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place element-wise matrix division (using a submatrix on the right-hand-side) Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator/=(const subview& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: subview::div_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const subview_row_strans& X) Chris@49: : n_rows(X.n_rows) Chris@49: , n_cols(X.n_cols) Chris@49: , n_elem(X.n_elem) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: init_cold(); Chris@49: Chris@49: X.extract(*this); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const subview_row_htrans& X) Chris@49: : n_rows(X.n_rows) Chris@49: , n_cols(X.n_cols) Chris@49: , n_elem(X.n_elem) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: init_cold(); Chris@49: Chris@49: X.extract(*this); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const xvec_htrans& X) Chris@49: : n_rows(X.n_rows) Chris@49: , n_cols(X.n_cols) Chris@49: , n_elem(X.n_elem) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: init_cold(); Chris@49: Chris@49: X.extract(*this); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! construct a matrix from a subview_cube instance Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const subview_cube& x) Chris@49: : n_rows(0) Chris@49: , n_cols(0) Chris@49: , n_elem(0) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: this->operator=(x); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! construct a matrix from a subview_cube instance Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator=(const subview_cube& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: subview_cube::extract(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place matrix addition (using a single-slice subcube on the right-hand-side) Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator+=(const subview_cube& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: subview_cube::plus_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place matrix subtraction (using a single-slice subcube on the right-hand-side) Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator-=(const subview_cube& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: subview_cube::minus_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place matrix mutiplication (using a single-slice subcube on the right-hand-side) Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator*=(const subview_cube& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const Mat tmp(X); Chris@49: glue_times::apply_inplace(*this, tmp); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place element-wise matrix mutiplication (using a single-slice subcube on the right-hand-side) Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator%=(const subview_cube& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: subview_cube::schur_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place element-wise matrix division (using a single-slice subcube on the right-hand-side) Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator/=(const subview_cube& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: subview_cube::div_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! construct a matrix from diagview (e.g. construct a matrix from a delayed diag operation) Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const diagview& X) Chris@49: : n_rows(X.n_rows) Chris@49: , n_cols(X.n_cols) Chris@49: , n_elem(X.n_elem) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: init_cold(); Chris@49: Chris@49: diagview::extract(*this, X); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! construct a matrix from diagview (e.g. construct a matrix from a delayed diag operation) Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator=(const diagview& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const bool alias = (this == &(X.m)); Chris@49: Chris@49: if(alias == false) Chris@49: { Chris@49: init_warm(X.n_rows, X.n_cols); Chris@49: Chris@49: diagview::extract(*this, X); Chris@49: } Chris@49: else Chris@49: { Chris@49: Mat tmp(X); Chris@49: Chris@49: steal_mem(tmp); Chris@49: } Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place matrix addition (using a diagview on the right-hand-side) Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator+=(const diagview& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: diagview::plus_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: //! in-place matrix subtraction (using a diagview on the right-hand-side) Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator-=(const diagview& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: diagview::minus_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place matrix mutiplication (using a diagview on the right-hand-side) Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator*=(const diagview& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: glue_times::apply_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place element-wise matrix mutiplication (using a diagview on the right-hand-side) Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator%=(const diagview& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: diagview::schur_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place element-wise matrix division (using a diagview on the right-hand-side) Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator/=(const diagview& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: diagview::div_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const subview_elem1& X) Chris@49: : n_rows(0) Chris@49: , n_cols(0) Chris@49: , n_elem(0) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: this->operator=(X); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator=(const subview_elem1& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: subview_elem1::extract(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator+=(const subview_elem1& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: subview_elem1::plus_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator-=(const subview_elem1& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: subview_elem1::minus_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator*=(const subview_elem1& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: glue_times::apply_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator%=(const subview_elem1& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: subview_elem1::schur_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator/=(const subview_elem1& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: subview_elem1::div_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const subview_elem2& X) Chris@49: : n_rows(0) Chris@49: , n_cols(0) Chris@49: , n_elem(0) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: this->operator=(X); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator=(const subview_elem2& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: subview_elem2::extract(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator+=(const subview_elem2& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: subview_elem2::plus_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator-=(const subview_elem2& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: subview_elem2::minus_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator*=(const subview_elem2& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: glue_times::apply_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator%=(const subview_elem2& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: subview_elem2::schur_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator/=(const subview_elem2& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: subview_elem2::div_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const SpBase& m) Chris@49: : n_rows(0) Chris@49: , n_cols(0) Chris@49: , n_elem(0) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: const SpProxy p(m.get_ref()); Chris@49: Chris@49: access::rw(n_rows) = p.get_n_rows(); Chris@49: access::rw(n_cols) = p.get_n_cols(); Chris@49: access::rw(n_elem) = p.get_n_elem(); Chris@49: Chris@49: init_cold(); Chris@49: fill(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: at(it.row(), it.col()) = (*it); Chris@49: ++it; Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator=(const SpBase& m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const SpProxy p(m.get_ref()); Chris@49: Chris@49: init_warm(p.get_n_rows(), p.get_n_cols()); Chris@49: Chris@49: fill(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: at(it.row(), it.col()) = (*it); Chris@49: ++it; Chris@49: } Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator+=(const SpBase& m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const SpProxy p(m.get_ref()); Chris@49: Chris@49: arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "addition"); 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: at(it.row(), it.col()) += (*it); Chris@49: ++it; Chris@49: } Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator-=(const SpBase& m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const SpProxy p(m.get_ref()); Chris@49: Chris@49: arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "subtraction"); 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: at(it.row(), it.col()) -= (*it); Chris@49: ++it; Chris@49: } Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator*=(const SpBase& m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: Mat z; Chris@49: z = (*this) * m.get_ref(); Chris@49: steal_mem(z); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator%=(const SpBase& m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const SpProxy p(m.get_ref()); Chris@49: Chris@49: arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "element-wise multiplication"); 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: // We have to zero everything that isn't being used. Chris@49: arrayops::inplace_set(memptr(), eT(0), (it.col() * n_rows) + it.row()); Chris@49: Chris@49: while(it != it_end) Chris@49: { Chris@49: const uword cur_loc = (it.col() * n_rows) + it.row(); Chris@49: Chris@49: access::rw(mem[cur_loc]) *= (*it); Chris@49: Chris@49: ++it; Chris@49: Chris@49: const uword next_loc = (it == it_end) Chris@49: ? (p.get_n_cols() * n_rows) Chris@49: : (it.col() * n_rows) + it.row(); Chris@49: Chris@49: arrayops::inplace_set(memptr() + cur_loc + 1, eT(0), (next_loc - cur_loc - 1)); Chris@49: } Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator/=(const SpBase& m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const SpProxy p(m.get_ref()); Chris@49: Chris@49: arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "element-wise division"); Chris@49: Chris@49: // If you use this method, you are probably stupid or misguided, but for completeness it is implemented. Chris@49: // Unfortunately the best way to do this is loop over every element. Chris@49: for(uword c = 0; c < n_cols; ++c) Chris@49: for(uword r = 0; r < n_rows; ++r) Chris@49: { Chris@49: at(r, c) /= p.at(r, c); Chris@49: } Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: mat_injector< Mat > Chris@49: Mat::operator<<(const eT val) Chris@49: { Chris@49: return mat_injector< Mat >(*this, val); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: mat_injector< Mat > Chris@49: Mat::operator<<(const injector_end_of_row<>& x) Chris@49: { Chris@49: return mat_injector< Mat >(*this, x); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! creation of subview (row vector) Chris@49: template Chris@49: arma_inline Chris@49: subview_row Chris@49: Mat::row(const uword row_num) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( row_num >= n_rows, "Mat::row(): index out of bounds" ); Chris@49: Chris@49: return subview_row(*this, row_num); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! creation of subview (row vector) Chris@49: template Chris@49: arma_inline Chris@49: const subview_row Chris@49: Mat::row(const uword row_num) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( row_num >= n_rows, "Mat::row(): index out of bounds" ); Chris@49: Chris@49: return subview_row(*this, row_num); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: subview_row Chris@49: Mat::operator()(const uword row_num, const span& col_span) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const bool col_all = col_span.whole; Chris@49: Chris@49: const uword local_n_cols = n_cols; Chris@49: Chris@49: const uword in_col1 = col_all ? 0 : col_span.a; Chris@49: const uword in_col2 = col_span.b; Chris@49: const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; Chris@49: Chris@49: arma_debug_check Chris@49: ( Chris@49: (row_num >= n_rows) Chris@49: || Chris@49: ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ) Chris@49: , Chris@49: "Mat::operator(): indices out of bounds or incorrectly used" Chris@49: ); Chris@49: Chris@49: return subview_row(*this, row_num, in_col1, submat_n_cols); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: const subview_row Chris@49: Mat::operator()(const uword row_num, const span& col_span) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const bool col_all = col_span.whole; Chris@49: Chris@49: const uword local_n_cols = n_cols; Chris@49: Chris@49: const uword in_col1 = col_all ? 0 : col_span.a; Chris@49: const uword in_col2 = col_span.b; Chris@49: const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; Chris@49: Chris@49: arma_debug_check Chris@49: ( Chris@49: (row_num >= n_rows) Chris@49: || Chris@49: ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ) Chris@49: , Chris@49: "Mat::operator(): indices out of bounds or incorrectly used" Chris@49: ); Chris@49: Chris@49: return subview_row(*this, row_num, in_col1, submat_n_cols); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! creation of subview (column vector) Chris@49: template Chris@49: arma_inline Chris@49: subview_col Chris@49: Mat::col(const uword col_num) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( col_num >= n_cols, "Mat::col(): index out of bounds"); Chris@49: Chris@49: return subview_col(*this, col_num); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! creation of subview (column vector) Chris@49: template Chris@49: arma_inline Chris@49: const subview_col Chris@49: Mat::col(const uword col_num) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( col_num >= n_cols, "Mat::col(): index out of bounds"); Chris@49: Chris@49: return subview_col(*this, col_num); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: subview_col Chris@49: Mat::operator()(const span& row_span, const uword col_num) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const bool row_all = row_span.whole; Chris@49: Chris@49: const uword local_n_rows = n_rows; Chris@49: Chris@49: const uword in_row1 = row_all ? 0 : row_span.a; Chris@49: const uword in_row2 = row_span.b; Chris@49: const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1; Chris@49: Chris@49: arma_debug_check Chris@49: ( Chris@49: (col_num >= n_cols) Chris@49: || Chris@49: ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) Chris@49: , Chris@49: "Mat::operator(): indices out of bounds or incorrectly used" Chris@49: ); Chris@49: Chris@49: return subview_col(*this, col_num, in_row1, submat_n_rows); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: const subview_col Chris@49: Mat::operator()(const span& row_span, const uword col_num) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const bool row_all = row_span.whole; Chris@49: Chris@49: const uword local_n_rows = n_rows; Chris@49: Chris@49: const uword in_row1 = row_all ? 0 : row_span.a; Chris@49: const uword in_row2 = row_span.b; Chris@49: const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1; Chris@49: Chris@49: arma_debug_check Chris@49: ( Chris@49: (col_num >= n_cols) Chris@49: || Chris@49: ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) Chris@49: , Chris@49: "Mat::operator(): indices out of bounds or incorrectly used" Chris@49: ); Chris@49: Chris@49: return subview_col(*this, col_num, in_row1, submat_n_rows); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! create a Col object which uses memory from an existing matrix object. Chris@49: //! this approach is currently not alias safe Chris@49: //! and does not take into account that the parent matrix object could be deleted. Chris@49: //! if deleted memory is accessed by the created Col object, Chris@49: //! it will cause memory corruption and/or a crash Chris@49: template Chris@49: inline Chris@49: Col Chris@49: Mat::unsafe_col(const uword col_num) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( col_num >= n_cols, "Mat::unsafe_col(): index out of bounds"); Chris@49: Chris@49: return Col(colptr(col_num), n_rows, false, true); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! create a Col object which uses memory from an existing matrix object. Chris@49: //! this approach is currently not alias safe Chris@49: //! and does not take into account that the parent matrix object could be deleted. Chris@49: //! if deleted memory is accessed by the created Col object, Chris@49: //! it will cause memory corruption and/or a crash Chris@49: template Chris@49: inline Chris@49: const Col Chris@49: Mat::unsafe_col(const uword col_num) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( col_num >= n_cols, "Mat::unsafe_col(): index out of bounds"); Chris@49: Chris@49: typedef const Col out_type; Chris@49: Chris@49: return out_type(const_cast(colptr(col_num)), n_rows, false, true); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! creation of subview (submatrix comprised of specified row vectors) Chris@49: template Chris@49: arma_inline Chris@49: subview Chris@49: Mat::rows(const uword in_row1, const uword in_row2) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check Chris@49: ( Chris@49: (in_row1 > in_row2) || (in_row2 >= n_rows), Chris@49: "Mat::rows(): indices out of bounds or incorrectly used" Chris@49: ); Chris@49: Chris@49: const uword subview_n_rows = in_row2 - in_row1 + 1; Chris@49: Chris@49: return subview(*this, in_row1, 0, subview_n_rows, n_cols ); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! creation of subview (submatrix comprised of specified row vectors) Chris@49: template Chris@49: arma_inline Chris@49: const subview Chris@49: Mat::rows(const uword in_row1, const uword in_row2) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check Chris@49: ( Chris@49: (in_row1 > in_row2) || (in_row2 >= n_rows), Chris@49: "Mat::rows(): indices out of bounds or incorrectly used" Chris@49: ); Chris@49: Chris@49: const uword subview_n_rows = in_row2 - in_row1 + 1; Chris@49: Chris@49: return subview(*this, in_row1, 0, subview_n_rows, n_cols ); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! creation of subview (submatrix comprised of specified column vectors) Chris@49: template Chris@49: arma_inline Chris@49: subview Chris@49: Mat::cols(const uword in_col1, const uword in_col2) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check Chris@49: ( Chris@49: (in_col1 > in_col2) || (in_col2 >= n_cols), Chris@49: "Mat::cols(): indices out of bounds or incorrectly used" Chris@49: ); Chris@49: Chris@49: const uword subview_n_cols = in_col2 - in_col1 + 1; Chris@49: Chris@49: return subview(*this, 0, in_col1, n_rows, subview_n_cols); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! creation of subview (submatrix comprised of specified column vectors) Chris@49: template Chris@49: arma_inline Chris@49: const subview Chris@49: Mat::cols(const uword in_col1, const uword in_col2) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check Chris@49: ( Chris@49: (in_col1 > in_col2) || (in_col2 >= n_cols), Chris@49: "Mat::cols(): indices out of bounds or incorrectly used" Chris@49: ); Chris@49: Chris@49: const uword subview_n_cols = in_col2 - in_col1 + 1; Chris@49: Chris@49: return subview(*this, 0, in_col1, n_rows, subview_n_cols); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! creation of subview (submatrix) Chris@49: template Chris@49: arma_inline Chris@49: subview Chris@49: Mat::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check Chris@49: ( Chris@49: (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols), Chris@49: "Mat::submat(): indices out of bounds or incorrectly used" Chris@49: ); Chris@49: Chris@49: const uword subview_n_rows = in_row2 - in_row1 + 1; Chris@49: const uword subview_n_cols = in_col2 - in_col1 + 1; Chris@49: Chris@49: return subview(*this, in_row1, in_col1, subview_n_rows, subview_n_cols); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! creation of subview (generic submatrix) Chris@49: template Chris@49: arma_inline Chris@49: const subview Chris@49: Mat::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check Chris@49: ( Chris@49: (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols), Chris@49: "Mat::submat(): indices out of bounds or incorrectly used" Chris@49: ); Chris@49: Chris@49: const uword subview_n_rows = in_row2 - in_row1 + 1; Chris@49: const uword subview_n_cols = in_col2 - in_col1 + 1; Chris@49: Chris@49: return subview(*this, in_row1, in_col1, subview_n_rows, subview_n_cols); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! creation of subview (submatrix) Chris@49: template Chris@49: inline Chris@49: subview Chris@49: Mat::submat(const span& row_span, const span& col_span) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const bool row_all = row_span.whole; Chris@49: const bool col_all = col_span.whole; Chris@49: Chris@49: const uword local_n_rows = n_rows; Chris@49: const uword local_n_cols = n_cols; Chris@49: Chris@49: const uword in_row1 = row_all ? 0 : row_span.a; Chris@49: const uword in_row2 = row_span.b; Chris@49: const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1; Chris@49: Chris@49: const uword in_col1 = col_all ? 0 : col_span.a; Chris@49: const uword in_col2 = col_span.b; Chris@49: const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; Chris@49: Chris@49: arma_debug_check Chris@49: ( Chris@49: ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) Chris@49: || Chris@49: ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ) Chris@49: , Chris@49: "Mat::submat(): indices out of bounds or incorrectly used" Chris@49: ); Chris@49: Chris@49: return subview(*this, in_row1, in_col1, submat_n_rows, submat_n_cols); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! creation of subview (generic submatrix) Chris@49: template Chris@49: inline Chris@49: const subview Chris@49: Mat::submat(const span& row_span, const span& col_span) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const bool row_all = row_span.whole; Chris@49: const bool col_all = col_span.whole; Chris@49: Chris@49: const uword local_n_rows = n_rows; Chris@49: const uword local_n_cols = n_cols; Chris@49: Chris@49: const uword in_row1 = row_all ? 0 : row_span.a; Chris@49: const uword in_row2 = row_span.b; Chris@49: const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1; Chris@49: Chris@49: const uword in_col1 = col_all ? 0 : col_span.a; Chris@49: const uword in_col2 = col_span.b; Chris@49: const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; Chris@49: Chris@49: arma_debug_check Chris@49: ( Chris@49: ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) Chris@49: || Chris@49: ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ) Chris@49: , Chris@49: "Mat::submat(): indices out of bounds or incorrectly used" Chris@49: ); Chris@49: Chris@49: return subview(*this, in_row1, in_col1, submat_n_rows, submat_n_cols); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: subview Chris@49: Mat::operator()(const span& row_span, const span& col_span) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return (*this).submat(row_span, col_span); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: const subview Chris@49: Mat::operator()(const span& row_span, const span& col_span) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return (*this).submat(row_span, col_span); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: subview_elem1 Chris@49: Mat::elem(const Base& a) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return subview_elem1(*this, a); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: const subview_elem1 Chris@49: Mat::elem(const Base& a) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return subview_elem1(*this, a); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: subview_elem1 Chris@49: Mat::operator()(const Base& a) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return subview_elem1(*this, a); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: const subview_elem1 Chris@49: Mat::operator()(const Base& a) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return subview_elem1(*this, a); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: subview_elem2 Chris@49: Mat::elem(const Base& ri, const Base& ci) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return subview_elem2(*this, ri, ci, false, false); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: const subview_elem2 Chris@49: Mat::elem(const Base& ri, const Base& ci) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return subview_elem2(*this, ri, ci, false, false); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: subview_elem2 Chris@49: Mat::submat(const Base& ri, const Base& ci) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return subview_elem2(*this, ri, ci, false, false); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: const subview_elem2 Chris@49: Mat::submat(const Base& ri, const Base& ci) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return subview_elem2(*this, ri, ci, false, false); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: subview_elem2 Chris@49: Mat::operator()(const Base& ri, const Base& ci) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return subview_elem2(*this, ri, ci, false, false); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: const subview_elem2 Chris@49: Mat::operator()(const Base& ri, const Base& ci) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return subview_elem2(*this, ri, ci, false, false); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: subview_elem2 Chris@49: Mat::rows(const Base& ri) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return subview_elem2(*this, ri, ri, false, true); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: const subview_elem2 Chris@49: Mat::rows(const Base& ri) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return subview_elem2(*this, ri, ri, false, true); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: subview_elem2 Chris@49: Mat::cols(const Base& ci) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return subview_elem2(*this, ci, ci, true, false); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: const subview_elem2 Chris@49: Mat::cols(const Base& ci) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return subview_elem2(*this, ci, ci, true, false); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: arma_inline Chris@49: subview_each1< Mat, 0 > Chris@49: Mat::each_col() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return subview_each1< Mat, 0>(*this); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: arma_inline Chris@49: subview_each1< Mat, 1 > Chris@49: Mat::each_row() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return subview_each1< Mat, 1>(*this); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: subview_each2< Mat, 0, T1 > Chris@49: Mat::each_col(const Base& indices) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return subview_each2< Mat, 0, T1 >(*this, indices); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: subview_each2< Mat, 1, T1 > Chris@49: Mat::each_row(const Base& indices) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return subview_each2< Mat, 1, T1 >(*this, indices); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! creation of diagview (diagonal) Chris@49: template Chris@49: arma_inline Chris@49: diagview Chris@49: Mat::diag(const sword in_id) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const uword row_offset = (in_id < 0) ? uword(-in_id) : 0; Chris@49: const uword col_offset = (in_id > 0) ? uword( in_id) : 0; 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: "Mat::diag(): requested diagonal 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: return diagview(*this, row_offset, col_offset, len); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! creation of diagview (diagonal) Chris@49: template Chris@49: arma_inline Chris@49: const diagview Chris@49: Mat::diag(const sword in_id) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const uword row_offset = (in_id < 0) ? -in_id : 0; Chris@49: const uword col_offset = (in_id > 0) ? in_id : 0; 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: "Mat::diag(): requested diagonal 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: return diagview(*this, row_offset, col_offset, len); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::swap_rows(const uword in_row1, const uword in_row2) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const uword local_n_rows = n_rows; Chris@49: const uword local_n_cols = n_cols; Chris@49: Chris@49: arma_debug_check Chris@49: ( Chris@49: (in_row1 >= local_n_rows) || (in_row2 >= local_n_rows), Chris@49: "Mat::swap_rows(): index out of bounds" Chris@49: ); Chris@49: Chris@49: if(n_elem > 0) Chris@49: { Chris@49: for(uword ucol=0; ucol < local_n_cols; ++ucol) Chris@49: { Chris@49: const uword offset = ucol * local_n_rows; Chris@49: const uword pos1 = in_row1 + offset; Chris@49: const uword pos2 = in_row2 + offset; Chris@49: Chris@49: std::swap( access::rw(mem[pos1]), access::rw(mem[pos2]) ); Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::swap_cols(const uword in_colA, const uword in_colB) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const uword local_n_rows = n_rows; Chris@49: const uword local_n_cols = n_cols; Chris@49: Chris@49: arma_debug_check Chris@49: ( Chris@49: (in_colA >= local_n_cols) || (in_colB >= local_n_cols), Chris@49: "Mat::swap_cols(): index out of bounds" Chris@49: ); Chris@49: Chris@49: if(n_elem > 0) Chris@49: { Chris@49: eT* ptrA = colptr(in_colA); Chris@49: eT* ptrB = colptr(in_colB); Chris@49: Chris@49: eT tmp_i; Chris@49: eT tmp_j; Chris@49: Chris@49: uword iq,jq; Chris@49: for(iq=0, jq=1; jq < local_n_rows; iq+=2, jq+=2) Chris@49: { Chris@49: tmp_i = ptrA[iq]; Chris@49: tmp_j = ptrA[jq]; Chris@49: Chris@49: ptrA[iq] = ptrB[iq]; Chris@49: ptrA[jq] = ptrB[jq]; Chris@49: Chris@49: ptrB[iq] = tmp_i; Chris@49: ptrB[jq] = tmp_j; Chris@49: } Chris@49: Chris@49: if(iq < local_n_rows) Chris@49: { Chris@49: std::swap( ptrA[iq], ptrB[iq] ); Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! remove specified row Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::shed_row(const uword row_num) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( row_num >= n_rows, "Mat::shed_row(): index out of bounds"); Chris@49: Chris@49: shed_rows(row_num, row_num); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! remove specified column Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::shed_col(const uword col_num) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( col_num >= n_cols, "Mat::shed_col(): index out of bounds"); Chris@49: Chris@49: shed_cols(col_num, col_num); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! remove specified rows Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::shed_rows(const uword in_row1, const uword in_row2) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check Chris@49: ( Chris@49: (in_row1 > in_row2) || (in_row2 >= n_rows), Chris@49: "Mat::shed_rows(): indices out of bounds or incorrectly used" Chris@49: ); Chris@49: Chris@49: const uword n_keep_front = in_row1; Chris@49: const uword n_keep_back = n_rows - (in_row2 + 1); Chris@49: Chris@49: Mat X(n_keep_front + n_keep_back, n_cols); Chris@49: Chris@49: if(n_keep_front > 0) Chris@49: { Chris@49: X.rows( 0, (n_keep_front-1) ) = rows( 0, (in_row1-1) ); Chris@49: } Chris@49: Chris@49: if(n_keep_back > 0) Chris@49: { Chris@49: X.rows( n_keep_front, (n_keep_front+n_keep_back-1) ) = rows( (in_row2+1), (n_rows-1) ); Chris@49: } Chris@49: Chris@49: steal_mem(X); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! remove specified columns Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::shed_cols(const uword in_col1, const uword in_col2) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check Chris@49: ( Chris@49: (in_col1 > in_col2) || (in_col2 >= n_cols), Chris@49: "Mat::shed_cols(): indices out of bounds or incorrectly used" Chris@49: ); Chris@49: Chris@49: const uword n_keep_front = in_col1; Chris@49: const uword n_keep_back = n_cols - (in_col2 + 1); Chris@49: Chris@49: Mat X(n_rows, n_keep_front + n_keep_back); Chris@49: Chris@49: if(n_keep_front > 0) Chris@49: { Chris@49: X.cols( 0, (n_keep_front-1) ) = cols( 0, (in_col1-1) ); Chris@49: } Chris@49: Chris@49: if(n_keep_back > 0) Chris@49: { Chris@49: X.cols( n_keep_front, (n_keep_front+n_keep_back-1) ) = cols( (in_col2+1), (n_cols-1) ); Chris@49: } Chris@49: Chris@49: steal_mem(X); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! insert N rows at the specified row position, Chris@49: //! optionally setting the elements of the inserted rows to zero Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::insert_rows(const uword row_num, const uword N, const bool set_to_zero) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const uword t_n_rows = n_rows; Chris@49: const uword t_n_cols = n_cols; Chris@49: Chris@49: const uword A_n_rows = row_num; Chris@49: const uword B_n_rows = t_n_rows - row_num; Chris@49: Chris@49: // insertion at row_num == n_rows is in effect an append operation Chris@49: arma_debug_check( (row_num > t_n_rows), "Mat::insert_rows(): index out of bounds"); Chris@49: Chris@49: if(N > 0) Chris@49: { Chris@49: Mat out(t_n_rows + N, t_n_cols); Chris@49: Chris@49: if(A_n_rows > 0) Chris@49: { Chris@49: out.rows(0, A_n_rows-1) = rows(0, A_n_rows-1); Chris@49: } Chris@49: Chris@49: if(B_n_rows > 0) Chris@49: { Chris@49: out.rows(row_num + N, t_n_rows + N - 1) = rows(row_num, t_n_rows-1); Chris@49: } Chris@49: Chris@49: if(set_to_zero == true) Chris@49: { Chris@49: out.rows(row_num, row_num + N - 1).zeros(); Chris@49: } Chris@49: Chris@49: steal_mem(out); Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! insert N columns at the specified column position, Chris@49: //! optionally setting the elements of the inserted columns to zero Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::insert_cols(const uword col_num, const uword N, const bool set_to_zero) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const uword t_n_rows = n_rows; Chris@49: const uword t_n_cols = n_cols; Chris@49: Chris@49: const uword A_n_cols = col_num; Chris@49: const uword B_n_cols = t_n_cols - col_num; Chris@49: Chris@49: // insertion at col_num == n_cols is in effect an append operation Chris@49: arma_debug_check( (col_num > t_n_cols), "Mat::insert_cols(): index out of bounds"); Chris@49: Chris@49: if(N > 0) Chris@49: { Chris@49: Mat out(t_n_rows, t_n_cols + N); Chris@49: Chris@49: if(A_n_cols > 0) Chris@49: { Chris@49: out.cols(0, A_n_cols-1) = cols(0, A_n_cols-1); Chris@49: } Chris@49: Chris@49: if(B_n_cols > 0) Chris@49: { Chris@49: out.cols(col_num + N, t_n_cols + N - 1) = cols(col_num, t_n_cols-1); Chris@49: } Chris@49: Chris@49: if(set_to_zero == true) Chris@49: { Chris@49: out.cols(col_num, col_num + N - 1).zeros(); Chris@49: } Chris@49: Chris@49: steal_mem(out); Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! insert the given object at the specified row position; Chris@49: //! the given object must have the same number of columns as the matrix Chris@49: template Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::insert_rows(const uword row_num, const Base& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const unwrap tmp(X.get_ref()); Chris@49: const Mat& C = tmp.M; Chris@49: Chris@49: const uword C_n_rows = C.n_rows; Chris@49: const uword C_n_cols = C.n_cols; Chris@49: Chris@49: const uword t_n_rows = n_rows; Chris@49: const uword t_n_cols = n_cols; Chris@49: Chris@49: const uword A_n_rows = row_num; Chris@49: const uword B_n_rows = t_n_rows - row_num; Chris@49: Chris@49: bool err_state = false; Chris@49: char* err_msg = 0; Chris@49: Chris@49: // insertion at row_num == n_rows is in effect an append operation Chris@49: Chris@49: arma_debug_set_error Chris@49: ( Chris@49: err_state, Chris@49: err_msg, Chris@49: (row_num > t_n_rows), Chris@49: "Mat::insert_rows(): index out of bounds" Chris@49: ); Chris@49: Chris@49: arma_debug_set_error Chris@49: ( Chris@49: err_state, Chris@49: err_msg, Chris@49: ( (C_n_cols != t_n_cols) && ( (t_n_rows > 0) || (t_n_cols > 0) ) && ( (C_n_rows > 0) || (C_n_cols > 0) ) ), Chris@49: "Mat::insert_rows(): given object has an incompatible number of columns" Chris@49: ); Chris@49: Chris@49: arma_debug_check(err_state, err_msg); Chris@49: Chris@49: if(C_n_rows > 0) Chris@49: { Chris@49: Mat out( t_n_rows + C_n_rows, (std::max)(t_n_cols, C_n_cols) ); Chris@49: Chris@49: if(t_n_cols > 0) Chris@49: { Chris@49: if(A_n_rows > 0) Chris@49: { Chris@49: out.rows(0, A_n_rows-1) = rows(0, A_n_rows-1); Chris@49: } Chris@49: Chris@49: if( (t_n_cols > 0) && (B_n_rows > 0) ) Chris@49: { Chris@49: out.rows(row_num + C_n_rows, t_n_rows + C_n_rows - 1) = rows(row_num, t_n_rows - 1); Chris@49: } Chris@49: } Chris@49: Chris@49: if(C_n_cols > 0) Chris@49: { Chris@49: out.rows(row_num, row_num + C_n_rows - 1) = C; Chris@49: } Chris@49: Chris@49: steal_mem(out); Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! insert the given object at the specified column position; Chris@49: //! the given object must have the same number of rows as the matrix Chris@49: template Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::insert_cols(const uword col_num, const Base& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const unwrap tmp(X.get_ref()); Chris@49: const Mat& C = tmp.M; Chris@49: Chris@49: const uword C_n_rows = C.n_rows; Chris@49: const uword C_n_cols = C.n_cols; Chris@49: Chris@49: const uword t_n_rows = n_rows; Chris@49: const uword t_n_cols = n_cols; Chris@49: Chris@49: const uword A_n_cols = col_num; Chris@49: const uword B_n_cols = t_n_cols - col_num; Chris@49: Chris@49: bool err_state = false; Chris@49: char* err_msg = 0; Chris@49: Chris@49: // insertion at col_num == n_cols is in effect an append operation Chris@49: Chris@49: arma_debug_set_error Chris@49: ( Chris@49: err_state, Chris@49: err_msg, Chris@49: (col_num > t_n_cols), Chris@49: "Mat::insert_cols(): index out of bounds" Chris@49: ); Chris@49: Chris@49: arma_debug_set_error Chris@49: ( Chris@49: err_state, Chris@49: err_msg, Chris@49: ( (C_n_rows != t_n_rows) && ( (t_n_rows > 0) || (t_n_cols > 0) ) && ( (C_n_rows > 0) || (C_n_cols > 0) ) ), Chris@49: "Mat::insert_cols(): given object has an incompatible number of rows" Chris@49: ); Chris@49: Chris@49: arma_debug_check(err_state, err_msg); Chris@49: Chris@49: if(C_n_cols > 0) Chris@49: { Chris@49: Mat out( (std::max)(t_n_rows, C_n_rows), t_n_cols + C_n_cols ); Chris@49: Chris@49: if(t_n_rows > 0) Chris@49: { Chris@49: if(A_n_cols > 0) Chris@49: { Chris@49: out.cols(0, A_n_cols-1) = cols(0, A_n_cols-1); Chris@49: } Chris@49: Chris@49: if(B_n_cols > 0) Chris@49: { Chris@49: out.cols(col_num + C_n_cols, t_n_cols + C_n_cols - 1) = cols(col_num, t_n_cols - 1); Chris@49: } Chris@49: } Chris@49: Chris@49: if(C_n_rows > 0) Chris@49: { Chris@49: out.cols(col_num, col_num + C_n_cols - 1) = C; Chris@49: } Chris@49: Chris@49: steal_mem(out); Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const Gen& X) Chris@49: : n_rows(X.n_rows) Chris@49: , n_cols(X.n_cols) Chris@49: , n_elem(n_rows*n_cols) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: Chris@49: init_cold(); Chris@49: Chris@49: X.apply(*this); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator=(const Gen& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: Chris@49: init_warm(X.n_rows, X.n_cols); Chris@49: Chris@49: X.apply(*this); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator+=(const Gen& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: Chris@49: X.apply_inplace_plus(*this); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator-=(const Gen& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: Chris@49: X.apply_inplace_minus(*this); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator*=(const Gen& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: Chris@49: const Mat tmp(X); Chris@49: Chris@49: return (*this).operator*=(tmp); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator%=(const Gen& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: Chris@49: X.apply_inplace_schur(*this); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator/=(const Gen& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: Chris@49: X.apply_inplace_div(*this); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! create a matrix from Op, i.e. run the previously delayed unary operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const Op& X) Chris@49: : n_rows(0) Chris@49: , n_cols(0) Chris@49: , n_elem(0) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: Chris@49: op_type::apply(*this, X); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! create a matrix from Op, i.e. run the previously delayed unary operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator=(const Op& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: Chris@49: op_type::apply(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place matrix addition, with the right-hand-side operand having delayed operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator+=(const Op& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: Chris@49: const Mat m(X); Chris@49: Chris@49: return (*this).operator+=(m); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place matrix subtraction, with the right-hand-side operand having delayed operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator-=(const Op& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: Chris@49: const Mat m(X); Chris@49: Chris@49: return (*this).operator-=(m); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place matrix multiplication, with the right-hand-side operand having delayed operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator*=(const Op& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: Chris@49: glue_times::apply_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place matrix element-wise multiplication, with the right-hand-side operand having delayed operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator%=(const Op& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: Chris@49: const Mat m(X); Chris@49: Chris@49: return (*this).operator%=(m); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place matrix element-wise division, with the right-hand-side operand having delayed operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator/=(const Op& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: Chris@49: const Mat m(X); Chris@49: Chris@49: return (*this).operator/=(m); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! create a matrix from eOp, i.e. run the previously delayed unary operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const eOp& X) Chris@49: : n_rows(X.get_n_rows()) Chris@49: , n_cols(X.get_n_cols()) Chris@49: , n_elem(X.get_n_elem()) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: Chris@49: init_cold(); Chris@49: Chris@49: eop_type::apply(*this, X); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! create a matrix from eOp, i.e. run the previously delayed unary operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator=(const eOp& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: Chris@49: const bool bad_alias = (eOp::proxy_type::has_subview && X.P.is_alias(*this)); Chris@49: Chris@49: if(bad_alias == false) Chris@49: { Chris@49: init_warm(X.get_n_rows(), X.get_n_cols()); Chris@49: Chris@49: eop_type::apply(*this, X); Chris@49: } Chris@49: else Chris@49: { Chris@49: arma_extra_debug_print("bad_alias = true"); Chris@49: Chris@49: Mat tmp(X); Chris@49: Chris@49: steal_mem(tmp); Chris@49: } Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator+=(const eOp& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: Chris@49: eop_type::apply_inplace_plus(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator-=(const eOp& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: Chris@49: eop_type::apply_inplace_minus(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator*=(const eOp& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: Chris@49: glue_times::apply_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator%=(const eOp& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: Chris@49: eop_type::apply_inplace_schur(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator/=(const eOp& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: Chris@49: eop_type::apply_inplace_div(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! EXPERIMENTAL Chris@49: template Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const mtOp& X) Chris@49: : n_rows(0) Chris@49: , n_cols(0) Chris@49: , n_elem(0) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: op_type::apply(*this, X); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! EXPERIMENTAL Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator=(const mtOp& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: op_type::apply(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! EXPERIMENTAL Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator+=(const mtOp& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const Mat m(X); Chris@49: Chris@49: return (*this).operator+=(m); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! EXPERIMENTAL Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator-=(const mtOp& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const Mat m(X); Chris@49: Chris@49: return (*this).operator-=(m); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! EXPERIMENTAL Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator*=(const mtOp& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const Mat m(X); Chris@49: Chris@49: return (*this).operator*=(m); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! EXPERIMENTAL Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator%=(const mtOp& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const Mat m(X); Chris@49: Chris@49: return (*this).operator%=(m); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! EXPERIMENTAL Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator/=(const mtOp& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const Mat m(X); Chris@49: Chris@49: return (*this).operator/=(m); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! create a matrix from Glue, i.e. run the previously delayed binary operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const Glue& X) Chris@49: : n_rows(0) Chris@49: , n_cols(0) Chris@49: , n_elem(0) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); Chris@49: Chris@49: glue_type::apply(*this, X); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! create a matrix from Glue, i.e. run the previously delayed binary operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator=(const Glue& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); Chris@49: Chris@49: glue_type::apply(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place matrix addition, with the right-hand-side operands having delayed operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator+=(const Glue& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); Chris@49: Chris@49: const Mat m(X); Chris@49: Chris@49: return (*this).operator+=(m); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place matrix subtraction, with the right-hand-side operands having delayed operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator-=(const Glue& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); Chris@49: Chris@49: const Mat m(X); Chris@49: Chris@49: return (*this).operator-=(m); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place matrix multiplications, with the right-hand-side operands having delayed operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator*=(const Glue& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); Chris@49: Chris@49: glue_times::apply_inplace(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place matrix element-wise multiplication, with the right-hand-side operands having delayed operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator%=(const Glue& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); Chris@49: Chris@49: const Mat m(X); Chris@49: Chris@49: return (*this).operator%=(m); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place matrix element-wise division, with the right-hand-side operands having delayed operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator/=(const Glue& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); Chris@49: Chris@49: const Mat m(X); Chris@49: Chris@49: return (*this).operator/=(m); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator+=(const Glue& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: glue_times::apply_inplace_plus(*this, X, sword(+1)); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator-=(const Glue& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: glue_times::apply_inplace_plus(*this, X, sword(-1)); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! create a matrix from eGlue, i.e. run the previously delayed binary operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const eGlue& X) Chris@49: : n_rows(X.get_n_rows()) Chris@49: , n_cols(X.get_n_cols()) Chris@49: , n_elem(X.get_n_elem()) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); Chris@49: Chris@49: init_cold(); Chris@49: Chris@49: eglue_type::apply(*this, X); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! create a matrix from eGlue, i.e. run the previously delayed binary operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator=(const eGlue& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); Chris@49: Chris@49: const bool bad_alias = Chris@49: ( Chris@49: (eGlue::proxy1_type::has_subview && X.P1.is_alias(*this)) Chris@49: || Chris@49: (eGlue::proxy2_type::has_subview && X.P2.is_alias(*this)) Chris@49: ); Chris@49: Chris@49: if(bad_alias == false) Chris@49: { Chris@49: init_warm(X.get_n_rows(), X.get_n_cols()); Chris@49: Chris@49: eglue_type::apply(*this, X); Chris@49: } Chris@49: else Chris@49: { Chris@49: arma_extra_debug_print("bad_alias = true"); Chris@49: Chris@49: Mat tmp(X); Chris@49: Chris@49: steal_mem(tmp); Chris@49: } Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place matrix addition, with the right-hand-side operands having delayed operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator+=(const eGlue& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); Chris@49: Chris@49: eglue_type::apply_inplace_plus(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! in-place matrix subtraction, with the right-hand-side operands having delayed operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator-=(const eGlue& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); Chris@49: Chris@49: eglue_type::apply_inplace_minus(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator*=(const eGlue& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); Chris@49: Chris@49: glue_times::apply_inplace(*this, X); Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator%=(const eGlue& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); Chris@49: Chris@49: eglue_type::apply_inplace_schur(*this, X); Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator/=(const eGlue& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); Chris@49: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); Chris@49: Chris@49: eglue_type::apply_inplace_div(*this, X); Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! EXPERIMENTAL: create a matrix from mtGlue, i.e. run the previously delayed binary operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: Mat::Mat(const mtGlue& X) Chris@49: : n_rows(0) Chris@49: , n_cols(0) Chris@49: , n_elem(0) Chris@49: , vec_state(0) Chris@49: , mem_state(0) Chris@49: , mem() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: glue_type::apply(*this, X); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! EXPERIMENTAL: create a matrix from Glue, i.e. run the previously delayed binary operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator=(const mtGlue& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: glue_type::apply(*this, X); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! EXPERIMENTAL: in-place matrix addition, with the right-hand-side operands having delayed operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator+=(const mtGlue& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const Mat m(X); Chris@49: Chris@49: return (*this).operator+=(m); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! EXPERIMENTAL: in-place matrix subtraction, with the right-hand-side operands having delayed operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator-=(const mtGlue& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const Mat m(X); Chris@49: Chris@49: return (*this).operator-=(m); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! EXPERIMENTAL: in-place matrix multiplications, with the right-hand-side operands having delayed operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator*=(const mtGlue& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const Mat m(X); Chris@49: Chris@49: glue_times::apply_inplace(*this, m); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! EXPERIMENTAL: in-place matrix element-wise multiplication, with the right-hand-side operands having delayed operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator%=(const mtGlue& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const Mat m(X); Chris@49: Chris@49: return (*this).operator%=(m); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! EXPERIMENTAL: in-place matrix element-wise division, with the right-hand-side operands having delayed operations Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::operator/=(const mtGlue& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const Mat m(X); Chris@49: Chris@49: return (*this).operator/=(m); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! linear element accessor (treats the matrix as a vector); no bounds check; assumes memory is aligned Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: const eT& Chris@49: Mat::at_alt(const uword ii) const Chris@49: { Chris@49: const eT* mem_aligned = mem; Chris@49: memory::mark_as_aligned(mem_aligned); Chris@49: Chris@49: return mem_aligned[ii]; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! linear element accessor (treats the matrix as a vector); bounds checking not done when ARMA_NO_DEBUG is defined Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: eT& Chris@49: Mat::operator() (const uword ii) Chris@49: { Chris@49: arma_debug_check( (ii >= n_elem), "Mat::operator(): index out of bounds"); Chris@49: return access::rw(mem[ii]); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! linear element accessor (treats the matrix as a vector); bounds checking not done when ARMA_NO_DEBUG is defined Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: const eT& Chris@49: Mat::operator() (const uword ii) const Chris@49: { Chris@49: arma_debug_check( (ii >= n_elem), "Mat::operator(): index out of bounds"); Chris@49: return mem[ii]; Chris@49: } Chris@49: Chris@49: Chris@49: //! linear element accessor (treats the matrix as a vector); no bounds check. Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: eT& Chris@49: Mat::operator[] (const uword ii) Chris@49: { Chris@49: return access::rw(mem[ii]); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! linear element accessor (treats the matrix as a vector); no bounds check Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: const eT& Chris@49: Mat::operator[] (const uword ii) const Chris@49: { Chris@49: return mem[ii]; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! linear element accessor (treats the matrix as a vector); no bounds check. Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: eT& Chris@49: Mat::at(const uword ii) Chris@49: { Chris@49: return access::rw(mem[ii]); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! linear element accessor (treats the matrix as a vector); no bounds check Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: const eT& Chris@49: Mat::at(const uword ii) const Chris@49: { Chris@49: return mem[ii]; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: eT& Chris@49: Mat::operator() (const uword in_row, const uword in_col) Chris@49: { Chris@49: arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "Mat::operator(): index out of bounds"); Chris@49: return access::rw(mem[in_row + in_col*n_rows]); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: const eT& Chris@49: Mat::operator() (const uword in_row, const uword in_col) const Chris@49: { Chris@49: arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "Mat::operator(): index out of bounds"); Chris@49: return mem[in_row + in_col*n_rows]; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! element accessor; no bounds check Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: eT& Chris@49: Mat::at(const uword in_row, const uword in_col) Chris@49: { Chris@49: return access::rw( mem[in_row + in_col*n_rows] ); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! element accessor; no bounds check Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: const eT& Chris@49: Mat::at(const uword in_row, const uword in_col) const Chris@49: { Chris@49: return mem[in_row + in_col*n_rows]; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! prefix ++ Chris@49: template Chris@49: arma_inline Chris@49: const Mat& Chris@49: Mat::operator++() Chris@49: { Chris@49: Mat_aux::prefix_pp(*this); Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! postfix ++ (must not return the object by reference) Chris@49: template Chris@49: arma_inline Chris@49: void Chris@49: Mat::operator++(int) Chris@49: { Chris@49: Mat_aux::postfix_pp(*this); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! prefix -- Chris@49: template Chris@49: arma_inline Chris@49: const Mat& Chris@49: Mat::operator--() Chris@49: { Chris@49: Mat_aux::prefix_mm(*this); Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! postfix -- (must not return the object by reference) Chris@49: template Chris@49: arma_inline Chris@49: void Chris@49: Mat::operator--(int) Chris@49: { Chris@49: Mat_aux::postfix_mm(*this); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! returns true if the matrix has no elements Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: bool Chris@49: Mat::is_empty() const Chris@49: { Chris@49: return (n_elem == 0); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! returns true if the object can be interpreted as a column or row vector Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: bool Chris@49: Mat::is_vec() const Chris@49: { Chris@49: return ( (n_rows == 1) || (n_cols == 1) ); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! returns true if the object can be interpreted as a row vector Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: bool Chris@49: Mat::is_rowvec() const Chris@49: { Chris@49: return (n_rows == 1); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! returns true if the object can be interpreted as a column vector Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: bool Chris@49: Mat::is_colvec() const Chris@49: { Chris@49: return (n_cols == 1); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! returns true if the object has the same number of non-zero rows and columnns Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: bool Chris@49: Mat::is_square() const Chris@49: { Chris@49: return (n_rows == n_cols); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! returns true if all of the elements are finite Chris@49: template Chris@49: inline Chris@49: arma_warn_unused Chris@49: bool Chris@49: Mat::is_finite() const Chris@49: { Chris@49: return arrayops::is_finite( memptr(), n_elem ); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! returns true if the given index is currently in range Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: bool Chris@49: Mat::in_range(const uword ii) const Chris@49: { Chris@49: return (ii < n_elem); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! returns true if the given start and end indices are currently in range Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: bool Chris@49: Mat::in_range(const span& x) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(x.whole == true) Chris@49: { Chris@49: return true; Chris@49: } Chris@49: else Chris@49: { Chris@49: const uword a = x.a; Chris@49: const uword b = x.b; Chris@49: Chris@49: return ( (a <= b) && (b < n_elem) ); Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! returns true if the given location is currently in range Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: bool Chris@49: Mat::in_range(const uword in_row, const uword in_col) const Chris@49: { Chris@49: return ( (in_row < n_rows) && (in_col < n_cols) ); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: bool Chris@49: Mat::in_range(const span& row_span, const uword in_col) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(row_span.whole == true) Chris@49: { Chris@49: return (in_col < n_cols); Chris@49: } Chris@49: else Chris@49: { Chris@49: const uword in_row1 = row_span.a; Chris@49: const uword in_row2 = row_span.b; Chris@49: Chris@49: return ( (in_row1 <= in_row2) && (in_row2 < n_rows) && (in_col < n_cols) ); Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: bool Chris@49: Mat::in_range(const uword in_row, const span& col_span) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(col_span.whole == true) Chris@49: { Chris@49: return (in_row < n_rows); Chris@49: } Chris@49: else Chris@49: { Chris@49: const uword in_col1 = col_span.a; Chris@49: const uword in_col2 = col_span.b; Chris@49: Chris@49: return ( (in_row < n_rows) && (in_col1 <= in_col2) && (in_col2 < n_cols) ); Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: bool Chris@49: Mat::in_range(const span& row_span, const span& col_span) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const uword in_row1 = row_span.a; Chris@49: const uword in_row2 = row_span.b; Chris@49: Chris@49: const uword in_col1 = col_span.a; Chris@49: const uword in_col2 = col_span.b; Chris@49: Chris@49: const bool rows_ok = row_span.whole ? true : ( (in_row1 <= in_row2) && (in_row2 < n_rows) ); Chris@49: const bool cols_ok = col_span.whole ? true : ( (in_col1 <= in_col2) && (in_col2 < n_cols) ); Chris@49: Chris@49: return ( (rows_ok == true) && (cols_ok == true) ); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! returns a pointer to array of eTs for a specified column; no bounds check Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: eT* Chris@49: Mat::colptr(const uword in_col) Chris@49: { Chris@49: return & access::rw(mem[in_col*n_rows]); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! returns a pointer to array of eTs for a specified column; no bounds check Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: const eT* Chris@49: Mat::colptr(const uword in_col) const Chris@49: { Chris@49: return & mem[in_col*n_rows]; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! returns a pointer to array of eTs used by the matrix Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: eT* Chris@49: Mat::memptr() Chris@49: { Chris@49: return const_cast(mem); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! returns a pointer to array of eTs used by the matrix Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: const eT* Chris@49: Mat::memptr() const Chris@49: { Chris@49: return mem; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! print contents of the matrix (to the cout stream), Chris@49: //! optionally preceding with a user specified line of text. Chris@49: //! the precision and cell width are modified. Chris@49: //! on return, the stream's state are restored to their original values. Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::impl_print(const std::string& extra_text) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(extra_text.length() != 0) Chris@49: { Chris@49: const std::streamsize orig_width = ARMA_DEFAULT_OSTREAM.width(); Chris@49: Chris@49: ARMA_DEFAULT_OSTREAM << extra_text << '\n'; Chris@49: Chris@49: ARMA_DEFAULT_OSTREAM.width(orig_width); Chris@49: } Chris@49: Chris@49: arma_ostream::print(ARMA_DEFAULT_OSTREAM, *this, true); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! print contents of the matrix to a user specified stream, Chris@49: //! optionally preceding with a user specified line of text. Chris@49: //! the precision and cell width are modified. Chris@49: //! on return, the stream's state are restored to their original values. Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::impl_print(std::ostream& user_stream, const std::string& extra_text) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(extra_text.length() != 0) Chris@49: { Chris@49: const std::streamsize orig_width = user_stream.width(); Chris@49: Chris@49: user_stream << extra_text << '\n'; Chris@49: Chris@49: user_stream.width(orig_width); Chris@49: } Chris@49: Chris@49: arma_ostream::print(user_stream, *this, true); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! print contents of the matrix (to the cout stream), Chris@49: //! optionally preceding with a user specified line of text. Chris@49: //! the stream's state are used as is and are not modified Chris@49: //! (i.e. the precision and cell width are not modified). Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::impl_raw_print(const std::string& extra_text) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(extra_text.length() != 0) Chris@49: { Chris@49: const std::streamsize orig_width = ARMA_DEFAULT_OSTREAM.width(); Chris@49: Chris@49: ARMA_DEFAULT_OSTREAM << extra_text << '\n'; Chris@49: Chris@49: ARMA_DEFAULT_OSTREAM.width(orig_width); Chris@49: } Chris@49: Chris@49: arma_ostream::print(ARMA_DEFAULT_OSTREAM, *this, false); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! print contents of the matrix to a user specified stream, Chris@49: //! optionally preceding with a user specified line of text. Chris@49: //! the stream's state are used as is and are not modified. Chris@49: //! (i.e. the precision and cell width are not modified). Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(extra_text.length() != 0) Chris@49: { Chris@49: const std::streamsize orig_width = user_stream.width(); Chris@49: Chris@49: user_stream << extra_text << '\n'; Chris@49: Chris@49: user_stream.width(orig_width); Chris@49: } Chris@49: Chris@49: arma_ostream::print(user_stream, *this, false); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! change the matrix to have user specified dimensions (data is not preserved) Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::set_size(const uword in_elem) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: switch(vec_state) Chris@49: { Chris@49: case 0: Chris@49: case 1: Chris@49: init_warm(in_elem, 1); Chris@49: break; Chris@49: Chris@49: case 2: Chris@49: init_warm(1, in_elem); Chris@49: break; Chris@49: Chris@49: default: Chris@49: ; Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! change the matrix to have user specified dimensions (data is not preserved) Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::set_size(const uword in_rows, const uword in_cols) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: init_warm(in_rows, in_cols); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! change the matrix to have user specified dimensions (data is preserved) Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::resize(const uword in_elem) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: switch(vec_state) Chris@49: { Chris@49: case 0: Chris@49: case 1: Chris@49: (*this).resize(in_elem, 1); Chris@49: break; Chris@49: Chris@49: case 2: Chris@49: (*this).resize(1, in_elem); Chris@49: break; Chris@49: Chris@49: default: Chris@49: ; Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! change the matrix to have user specified dimensions (data is preserved) Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::resize(const uword in_rows, const uword in_cols) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: *this = arma::resize(*this, in_rows, in_cols); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! change the matrix to have user specified dimensions (data is preserved) Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::reshape(const uword in_rows, const uword in_cols, const uword dim) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: *this = arma::reshape(*this, in_rows, in_cols, dim); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! change the matrix (without preserving data) to have the same dimensions as the given expression Chris@49: template Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::copy_size(const Base& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const Proxy P(X.get_ref()); Chris@49: Chris@49: const uword X_n_rows = P.get_n_rows(); Chris@49: const uword X_n_cols = P.get_n_cols(); Chris@49: Chris@49: init_warm(X_n_rows, X_n_cols); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! transform each element in the matrix using a functor Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::transform(functor F) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: eT* out_mem = memptr(); Chris@49: Chris@49: const uword N = n_elem; Chris@49: Chris@49: uword ii, jj; Chris@49: Chris@49: for(ii=0, jj=1; jj < N; ii+=2, jj+=2) Chris@49: { Chris@49: eT tmp_ii = out_mem[ii]; Chris@49: eT tmp_jj = out_mem[jj]; Chris@49: Chris@49: tmp_ii = eT( F(tmp_ii) ); Chris@49: tmp_jj = eT( F(tmp_jj) ); Chris@49: Chris@49: out_mem[ii] = tmp_ii; Chris@49: out_mem[jj] = tmp_jj; Chris@49: } Chris@49: Chris@49: if(ii < N) Chris@49: { Chris@49: out_mem[ii] = eT( F(out_mem[ii]) ); Chris@49: } Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! imbue (fill) the matrix with values provided by a functor Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::imbue(functor F) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: eT* out_mem = memptr(); Chris@49: Chris@49: const uword N = n_elem; Chris@49: Chris@49: uword ii, jj; Chris@49: Chris@49: for(ii=0, jj=1; jj < N; ii+=2, jj+=2) Chris@49: { Chris@49: const eT tmp_ii = eT( F() ); Chris@49: const eT tmp_jj = eT( F() ); Chris@49: Chris@49: out_mem[ii] = tmp_ii; Chris@49: out_mem[jj] = tmp_jj; Chris@49: } Chris@49: Chris@49: if(ii < N) Chris@49: { Chris@49: out_mem[ii] = eT( F() ); Chris@49: } Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! fill the matrix with the specified value Chris@49: template Chris@49: arma_hot Chris@49: inline Chris@49: const Mat& Chris@49: Mat::fill(const eT val) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arrayops::inplace_set( memptr(), val, n_elem ); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::zeros() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return fill(eT(0)); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::zeros(const uword in_elem) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: set_size(in_elem); Chris@49: Chris@49: return fill(eT(0)); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::zeros(const uword in_rows, const uword in_cols) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: set_size(in_rows, in_cols); Chris@49: Chris@49: return fill(eT(0)); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::ones() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return fill(eT(1)); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::ones(const uword in_elem) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: set_size(in_elem); Chris@49: Chris@49: return fill(eT(1)); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::ones(const uword in_rows, const uword in_cols) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: set_size(in_rows, in_cols); Chris@49: Chris@49: return fill(eT(1)); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::randu() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: eop_aux_randu::fill( memptr(), n_elem ); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::randu(const uword in_elem) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: set_size(in_elem); Chris@49: Chris@49: return (*this).randu(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::randu(const uword in_rows, const uword in_cols) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: set_size(in_rows, in_cols); Chris@49: Chris@49: return (*this).randu(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::randn() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: eop_aux_randn::fill( memptr(), n_elem ); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::randn(const uword in_elem) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: set_size(in_elem); Chris@49: Chris@49: return (*this).randn(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::randn(const uword in_rows, const uword in_cols) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: set_size(in_rows, in_cols); Chris@49: Chris@49: return (*this).randn(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::eye() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: fill(eT(0)); Chris@49: Chris@49: const uword N = (std::min)(n_rows, n_cols); Chris@49: Chris@49: for(uword ii=0; ii Chris@49: inline Chris@49: const Mat& Chris@49: Mat::eye(const uword in_rows, const uword in_cols) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: set_size(in_rows, in_cols); Chris@49: Chris@49: return (*this).eye(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::reset() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: switch(vec_state) Chris@49: { Chris@49: default: Chris@49: init_warm(0, 0); Chris@49: break; Chris@49: Chris@49: case 1: Chris@49: init_warm(0, 1); Chris@49: break; Chris@49: Chris@49: case 2: Chris@49: init_warm(1, 0); Chris@49: break; Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::set_real(const Base::pod_type,T1>& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: Mat_aux::set_real(*this, X); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::set_imag(const Base::pod_type,T1>& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: Mat_aux::set_imag(*this, X); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_warn_unused Chris@49: eT Chris@49: Mat::min() const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( (n_elem == 0), "min(): object has no elements" ); Chris@49: Chris@49: return op_min::direct_min(memptr(), n_elem); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_warn_unused Chris@49: eT Chris@49: Mat::max() const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( (n_elem == 0), "max(): object has no elements" ); Chris@49: Chris@49: return op_max::direct_max(memptr(), n_elem); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: eT Chris@49: Mat::min(uword& index_of_min_val) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( (n_elem == 0), "min(): object has no elements" ); Chris@49: Chris@49: return op_min::direct_min(memptr(), n_elem, index_of_min_val); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: eT Chris@49: Mat::max(uword& index_of_max_val) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( (n_elem == 0), "max(): object has no elements" ); Chris@49: Chris@49: return op_max::direct_max(memptr(), n_elem, index_of_max_val); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: eT Chris@49: Mat::min(uword& row_of_min_val, uword& col_of_min_val) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( (n_elem == 0), "min(): object has no elements" ); Chris@49: Chris@49: uword iq; Chris@49: Chris@49: eT val = op_min::direct_min(memptr(), n_elem, iq); Chris@49: Chris@49: row_of_min_val = iq % n_rows; Chris@49: col_of_min_val = iq / n_rows; Chris@49: Chris@49: return val; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: eT Chris@49: Mat::max(uword& row_of_max_val, uword& col_of_max_val) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( (n_elem == 0), "max(): object has no elements" ); Chris@49: Chris@49: uword iq; Chris@49: Chris@49: eT val = op_max::direct_max(memptr(), n_elem, iq); Chris@49: Chris@49: row_of_max_val = iq % n_rows; Chris@49: col_of_max_val = iq / n_rows; Chris@49: Chris@49: return val; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! save the matrix to a file Chris@49: template Chris@49: inline Chris@49: bool Chris@49: Mat::save(const std::string name, const file_type type, const bool print_status) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: bool save_okay; Chris@49: Chris@49: switch(type) Chris@49: { Chris@49: case raw_ascii: Chris@49: save_okay = diskio::save_raw_ascii(*this, name); Chris@49: break; Chris@49: Chris@49: case arma_ascii: Chris@49: save_okay = diskio::save_arma_ascii(*this, name); Chris@49: break; Chris@49: Chris@49: case csv_ascii: Chris@49: save_okay = diskio::save_csv_ascii(*this, name); Chris@49: break; Chris@49: Chris@49: case raw_binary: Chris@49: save_okay = diskio::save_raw_binary(*this, name); Chris@49: break; Chris@49: Chris@49: case arma_binary: Chris@49: save_okay = diskio::save_arma_binary(*this, name); Chris@49: break; Chris@49: Chris@49: case pgm_binary: Chris@49: save_okay = diskio::save_pgm_binary(*this, name); Chris@49: break; Chris@49: Chris@49: case hdf5_binary: Chris@49: save_okay = diskio::save_hdf5_binary(*this, name); Chris@49: break; Chris@49: Chris@49: default: Chris@49: arma_warn(print_status, "Mat::save(): unsupported file type"); Chris@49: save_okay = false; Chris@49: } Chris@49: Chris@49: arma_warn( (print_status && (save_okay == false)), "Mat::save(): couldn't write to ", name); Chris@49: Chris@49: return save_okay; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! save the matrix to a stream Chris@49: template Chris@49: inline Chris@49: bool Chris@49: Mat::save(std::ostream& os, const file_type type, const bool print_status) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: bool save_okay; Chris@49: Chris@49: switch(type) Chris@49: { Chris@49: case raw_ascii: Chris@49: save_okay = diskio::save_raw_ascii(*this, os); Chris@49: break; Chris@49: Chris@49: case arma_ascii: Chris@49: save_okay = diskio::save_arma_ascii(*this, os); Chris@49: break; Chris@49: Chris@49: case csv_ascii: Chris@49: save_okay = diskio::save_csv_ascii(*this, os); Chris@49: break; Chris@49: Chris@49: case raw_binary: Chris@49: save_okay = diskio::save_raw_binary(*this, os); Chris@49: break; Chris@49: Chris@49: case arma_binary: Chris@49: save_okay = diskio::save_arma_binary(*this, os); Chris@49: break; Chris@49: Chris@49: case pgm_binary: Chris@49: save_okay = diskio::save_pgm_binary(*this, os); Chris@49: break; Chris@49: Chris@49: default: Chris@49: arma_warn(print_status, "Mat::save(): unsupported file type"); Chris@49: save_okay = false; Chris@49: } Chris@49: Chris@49: arma_warn( (print_status && (save_okay == false)), "Mat::save(): couldn't write to the given stream"); Chris@49: Chris@49: return save_okay; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! load a matrix from a file Chris@49: template Chris@49: inline Chris@49: bool Chris@49: Mat::load(const std::string name, const file_type type, const bool print_status) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: bool load_okay; Chris@49: std::string err_msg; Chris@49: Chris@49: switch(type) Chris@49: { Chris@49: case auto_detect: Chris@49: load_okay = diskio::load_auto_detect(*this, name, err_msg); Chris@49: break; Chris@49: Chris@49: case raw_ascii: Chris@49: load_okay = diskio::load_raw_ascii(*this, name, err_msg); Chris@49: break; Chris@49: Chris@49: case arma_ascii: Chris@49: load_okay = diskio::load_arma_ascii(*this, name, err_msg); Chris@49: break; Chris@49: Chris@49: case csv_ascii: Chris@49: load_okay = diskio::load_csv_ascii(*this, name, err_msg); Chris@49: break; Chris@49: Chris@49: case raw_binary: Chris@49: load_okay = diskio::load_raw_binary(*this, name, err_msg); Chris@49: break; Chris@49: Chris@49: case arma_binary: Chris@49: load_okay = diskio::load_arma_binary(*this, name, err_msg); Chris@49: break; Chris@49: Chris@49: case pgm_binary: Chris@49: load_okay = diskio::load_pgm_binary(*this, name, err_msg); Chris@49: break; Chris@49: Chris@49: case hdf5_binary: Chris@49: load_okay = diskio::load_hdf5_binary(*this, name, err_msg); Chris@49: break; Chris@49: Chris@49: default: Chris@49: arma_warn(print_status, "Mat::load(): unsupported file type"); Chris@49: load_okay = false; Chris@49: } Chris@49: Chris@49: if( (print_status == true) && (load_okay == false) ) Chris@49: { Chris@49: if(err_msg.length() > 0) Chris@49: { Chris@49: arma_warn(true, "Mat::load(): ", err_msg, name); Chris@49: } Chris@49: else Chris@49: { Chris@49: arma_warn(true, "Mat::load(): couldn't read ", name); Chris@49: } Chris@49: } Chris@49: Chris@49: if(load_okay == false) Chris@49: { Chris@49: (*this).reset(); Chris@49: } Chris@49: Chris@49: return load_okay; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! load a matrix from a stream Chris@49: template Chris@49: inline Chris@49: bool Chris@49: Mat::load(std::istream& is, const file_type type, const bool print_status) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: bool load_okay; Chris@49: std::string err_msg; Chris@49: Chris@49: switch(type) Chris@49: { Chris@49: case auto_detect: Chris@49: load_okay = diskio::load_auto_detect(*this, is, err_msg); Chris@49: break; Chris@49: Chris@49: case raw_ascii: Chris@49: load_okay = diskio::load_raw_ascii(*this, is, err_msg); Chris@49: break; Chris@49: Chris@49: case arma_ascii: Chris@49: load_okay = diskio::load_arma_ascii(*this, is, err_msg); Chris@49: break; Chris@49: Chris@49: case csv_ascii: Chris@49: load_okay = diskio::load_csv_ascii(*this, is, err_msg); Chris@49: break; Chris@49: Chris@49: case raw_binary: Chris@49: load_okay = diskio::load_raw_binary(*this, is, err_msg); Chris@49: break; Chris@49: Chris@49: case arma_binary: Chris@49: load_okay = diskio::load_arma_binary(*this, is, err_msg); Chris@49: break; Chris@49: Chris@49: case pgm_binary: Chris@49: load_okay = diskio::load_pgm_binary(*this, is, err_msg); Chris@49: break; Chris@49: Chris@49: default: Chris@49: arma_warn(print_status, "Mat::load(): unsupported file type"); Chris@49: load_okay = false; Chris@49: } Chris@49: Chris@49: Chris@49: if( (print_status == true) && (load_okay == false) ) Chris@49: { Chris@49: if(err_msg.length() > 0) Chris@49: { Chris@49: arma_warn(true, "Mat::load(): ", err_msg, "the given stream"); Chris@49: } Chris@49: else Chris@49: { Chris@49: arma_warn(true, "Mat::load(): couldn't load from the given stream"); Chris@49: } Chris@49: } Chris@49: Chris@49: if(load_okay == false) Chris@49: { Chris@49: (*this).reset(); Chris@49: } Chris@49: Chris@49: return load_okay; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! save the matrix to a file, without printing any error messages Chris@49: template Chris@49: inline Chris@49: bool Chris@49: Mat::quiet_save(const std::string name, const file_type type) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return (*this).save(name, type, false); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! save the matrix to a stream, without printing any error messages Chris@49: template Chris@49: inline Chris@49: bool Chris@49: Mat::quiet_save(std::ostream& os, const file_type type) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return (*this).save(os, type, false); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! load a matrix from a file, without printing any error messages Chris@49: template Chris@49: inline Chris@49: bool Chris@49: Mat::quiet_load(const std::string name, const file_type type) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return (*this).load(name, type, false); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! load a matrix from a stream, without printing any error messages Chris@49: template Chris@49: inline Chris@49: bool Chris@49: Mat::quiet_load(std::istream& is, const file_type type) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return (*this).load(is, type, false); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: Mat::row_iterator::row_iterator(Mat& in_M, const uword in_row) Chris@49: : M (in_M ) Chris@49: , row(in_row) Chris@49: , col(0 ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: eT& Chris@49: Mat::row_iterator::operator*() Chris@49: { Chris@49: return M.at(row,col); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename Mat::row_iterator& Chris@49: Mat::row_iterator::operator++() Chris@49: { Chris@49: ++col; Chris@49: Chris@49: if(col >= M.n_cols) Chris@49: { Chris@49: col = 0; Chris@49: ++row; Chris@49: } Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::row_iterator::operator++(int) Chris@49: { Chris@49: operator++(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename Mat::row_iterator& Chris@49: Mat::row_iterator::operator--() Chris@49: { Chris@49: if(col > 0) Chris@49: { Chris@49: --col; Chris@49: } Chris@49: else Chris@49: { Chris@49: if(row > 0) Chris@49: { Chris@49: col = M.n_cols - 1; Chris@49: --row; Chris@49: } Chris@49: } Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::row_iterator::operator--(int) Chris@49: { Chris@49: operator--(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: bool Chris@49: Mat::row_iterator::operator!=(const typename Mat::row_iterator& X) const Chris@49: { Chris@49: return ( (row != X.row) || (col != X.col) ) ? true : false; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: bool Chris@49: Mat::row_iterator::operator==(const typename Mat::row_iterator& X) const Chris@49: { Chris@49: return ( (row == X.row) && (col == X.col) ) ? true : false; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: Mat::const_row_iterator::const_row_iterator(const Mat& in_M, const uword in_row) Chris@49: : M (in_M ) Chris@49: , row(in_row) Chris@49: , col(0 ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: Mat::const_row_iterator::const_row_iterator(const typename Mat::row_iterator& X) Chris@49: : M (X.M) Chris@49: , row(X.row) Chris@49: , col(X.col) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: eT Chris@49: Mat::const_row_iterator::operator*() const Chris@49: { Chris@49: return M.at(row,col); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename Mat::const_row_iterator& Chris@49: Mat::const_row_iterator::operator++() Chris@49: { Chris@49: ++col; Chris@49: Chris@49: if(col >= M.n_cols) Chris@49: { Chris@49: col = 0; Chris@49: ++row; Chris@49: } Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::const_row_iterator::operator++(int) Chris@49: { Chris@49: operator++(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename Mat::const_row_iterator& Chris@49: Mat::const_row_iterator::operator--() Chris@49: { Chris@49: if(col > 0) Chris@49: { Chris@49: --col; Chris@49: } Chris@49: else Chris@49: { Chris@49: if(row > 0) Chris@49: { Chris@49: col = M.n_cols - 1; Chris@49: --row; Chris@49: } Chris@49: } Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::const_row_iterator::operator--(int) Chris@49: { Chris@49: operator--(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: bool Chris@49: Mat::const_row_iterator::operator!=(const typename Mat::const_row_iterator& X) const Chris@49: { Chris@49: return ( (row != X.row) || (col != X.col) ) ? true : false; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: bool Chris@49: Mat::const_row_iterator::operator==(const typename Mat::const_row_iterator& X) const Chris@49: { Chris@49: return ( (row == X.row) && (col == X.col) ) ? true : false; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename Mat::iterator Chris@49: Mat::begin() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return memptr(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename Mat::const_iterator Chris@49: Mat::begin() const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return memptr(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename Mat::const_iterator Chris@49: Mat::cbegin() const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return memptr(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename Mat::iterator Chris@49: Mat::end() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return memptr() + n_elem; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename Mat::const_iterator Chris@49: Mat::end() const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return memptr() + n_elem; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename Mat::const_iterator Chris@49: Mat::cend() const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return memptr() + n_elem; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename Mat::col_iterator Chris@49: Mat::begin_col(const uword col_num) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( (col_num >= n_cols), "begin_col(): index out of bounds"); Chris@49: Chris@49: return colptr(col_num); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename Mat::const_col_iterator Chris@49: Mat::begin_col(const uword col_num) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( (col_num >= n_cols), "begin_col(): index out of bounds"); Chris@49: Chris@49: return colptr(col_num); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename Mat::col_iterator Chris@49: Mat::end_col(const uword col_num) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( (col_num >= n_cols), "end_col(): index out of bounds"); Chris@49: Chris@49: return colptr(col_num) + n_rows; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename Mat::const_col_iterator Chris@49: Mat::end_col(const uword col_num) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( (col_num >= n_cols), "end_col(): index out of bounds"); Chris@49: Chris@49: return colptr(col_num) + n_rows; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename Mat::row_iterator Chris@49: Mat::begin_row(const uword row_num) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( (row_num >= n_rows), "Mat::begin_row(): index out of bounds" ); Chris@49: Chris@49: return typename Mat::row_iterator(*this, row_num); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename Mat::const_row_iterator Chris@49: Mat::begin_row(const uword row_num) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( (row_num >= n_rows), "Mat::begin_row(): index out of bounds" ); Chris@49: Chris@49: return typename Mat::const_row_iterator(*this, row_num); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename Mat::row_iterator Chris@49: Mat::end_row(const uword row_num) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( (row_num >= n_rows), "Mat::end_row(): index out of bounds" ); Chris@49: Chris@49: return typename Mat::row_iterator(*this, row_num + 1); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename Mat::const_row_iterator Chris@49: Mat::end_row(const uword row_num) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( (row_num >= n_rows), "Mat::end_row(): index out of bounds" ); Chris@49: Chris@49: return typename Mat::const_row_iterator(*this, row_num + 1); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! resets this matrix to an empty matrix Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat::clear() Chris@49: { Chris@49: reset(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! returns true if the matrix has no elements Chris@49: template Chris@49: inline Chris@49: bool Chris@49: Mat::empty() const Chris@49: { Chris@49: return (n_elem == 0); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! returns the number of elements in this matrix Chris@49: template Chris@49: inline Chris@49: uword Chris@49: Mat::size() const Chris@49: { Chris@49: return n_elem; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: Mat::fixed::fixed() Chris@49: : Mat( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : mem_local) ) Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: Mat::fixed::fixed(const fixed& X) Chris@49: : Mat( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : mem_local) ) Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: eT* dest = (use_extra) ? mem_local_extra : mem_local; Chris@49: Chris@49: arrayops::copy( dest, X.mem, fixed_n_elem ); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: template Chris@49: inline Chris@49: Mat::fixed::fixed(const Base& A) Chris@49: : Mat( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : mem_local) ) Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: Mat::operator=(A.get_ref()); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: template Chris@49: inline Chris@49: Mat::fixed::fixed(const Base& A, const Base& B) Chris@49: : Mat( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : mem_local) ) Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: Mat::init(A,B); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: Mat::fixed::fixed(const eT* aux_mem) Chris@49: : Mat( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : mem_local) ) Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: eT* dest = (use_extra) ? mem_local_extra : mem_local; Chris@49: Chris@49: arrayops::copy( dest, aux_mem, fixed_n_elem ); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: Mat::fixed::fixed(const char* text) Chris@49: : Mat( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : mem_local) ) Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: Mat::operator=(text); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: Mat::fixed::fixed(const std::string& text) Chris@49: : Mat( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : mem_local) ) Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: Mat::operator=(text); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: #if defined(ARMA_USE_CXX11) Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: Mat::fixed::fixed(const std::initializer_list& list) Chris@49: : Mat( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : mem_local) ) Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: Chris@49: (*this).operator=(list); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: Mat::fixed::operator=(const std::initializer_list& list) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const uword N = list.size(); Chris@49: Chris@49: arma_debug_check( (N > fixed_n_elem), "Mat::fixed: initialiser list is too long" ); Chris@49: Chris@49: eT* this_mem = (*this).memptr(); Chris@49: Chris@49: arrayops::copy( this_mem, list.begin(), N ); Chris@49: Chris@49: for(uword iq=N; iq < fixed_n_elem; ++iq) { this_mem[iq] = eT(0); } Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: #endif Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: const Op< typename Mat::template fixed::Mat_fixed_type, op_htrans > Chris@49: Mat::fixed::t() const Chris@49: { Chris@49: return Op< typename Mat::template fixed::Mat_fixed_type, op_htrans >(*this); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: const Op< typename Mat::template fixed::Mat_fixed_type, op_htrans > Chris@49: Mat::fixed::ht() const Chris@49: { Chris@49: return Op< typename Mat::template fixed::Mat_fixed_type, op_htrans >(*this); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: const Op< typename Mat::template fixed::Mat_fixed_type, op_strans > Chris@49: Mat::fixed::st() const Chris@49: { Chris@49: return Op< typename Mat::template fixed::Mat_fixed_type, op_strans >(*this); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: const eT& Chris@49: Mat::fixed::at_alt(const uword ii) const Chris@49: { Chris@49: #if defined(ARMA_HAVE_ALIGNED_ATTRIBUTE) Chris@49: Chris@49: return (use_extra) ? mem_local_extra[ii] : mem_local[ii]; Chris@49: Chris@49: #else Chris@49: const eT* mem_aligned = (use_extra) ? mem_local_extra : mem_local; Chris@49: Chris@49: memory::mark_as_aligned(mem_aligned); Chris@49: Chris@49: return mem_aligned[ii]; Chris@49: #endif Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: eT& Chris@49: Mat::fixed::operator[] (const uword ii) Chris@49: { Chris@49: return (use_extra) ? mem_local_extra[ii] : mem_local[ii]; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: const eT& Chris@49: Mat::fixed::operator[] (const uword ii) const Chris@49: { Chris@49: return (use_extra) ? mem_local_extra[ii] : mem_local[ii]; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: eT& Chris@49: Mat::fixed::at(const uword ii) Chris@49: { Chris@49: return (use_extra) ? mem_local_extra[ii] : mem_local[ii]; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: const eT& Chris@49: Mat::fixed::at(const uword ii) const Chris@49: { Chris@49: return (use_extra) ? mem_local_extra[ii] : mem_local[ii]; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: eT& Chris@49: Mat::fixed::operator() (const uword ii) Chris@49: { Chris@49: arma_debug_check( (ii >= fixed_n_elem), "Mat::operator(): index out of bounds"); Chris@49: Chris@49: return (use_extra) ? mem_local_extra[ii] : mem_local[ii]; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: const eT& Chris@49: Mat::fixed::operator() (const uword ii) const Chris@49: { Chris@49: arma_debug_check( (ii >= fixed_n_elem), "Mat::operator(): index out of bounds"); Chris@49: Chris@49: return (use_extra) ? mem_local_extra[ii] : mem_local[ii]; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: eT& Chris@49: Mat::fixed::at(const uword in_row, const uword in_col) Chris@49: { Chris@49: const uword iq = in_row + in_col*fixed_n_rows; Chris@49: Chris@49: return (use_extra) ? mem_local_extra[iq] : mem_local[iq]; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: const eT& Chris@49: Mat::fixed::at(const uword in_row, const uword in_col) const Chris@49: { Chris@49: const uword iq = in_row + in_col*fixed_n_rows; Chris@49: Chris@49: return (use_extra) ? mem_local_extra[iq] : mem_local[iq]; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: eT& Chris@49: Mat::fixed::operator() (const uword in_row, const uword in_col) Chris@49: { Chris@49: arma_debug_check( ((in_row >= fixed_n_rows) || (in_col >= fixed_n_cols)), "Mat::operator(): index out of bounds"); Chris@49: Chris@49: const uword iq = in_row + in_col*fixed_n_rows; Chris@49: Chris@49: return (use_extra) ? mem_local_extra[iq] : mem_local[iq]; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: const eT& Chris@49: Mat::fixed::operator() (const uword in_row, const uword in_col) const Chris@49: { Chris@49: arma_debug_check( ((in_row >= fixed_n_rows) || (in_col >= fixed_n_cols)), "Mat::operator(): index out of bounds"); Chris@49: Chris@49: const uword iq = in_row + in_col*fixed_n_rows; Chris@49: Chris@49: return (use_extra) ? mem_local_extra[iq] : mem_local[iq]; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: eT* Chris@49: Mat::fixed::colptr(const uword in_col) Chris@49: { Chris@49: eT* mem_actual = (use_extra) ? mem_local_extra : mem_local; Chris@49: Chris@49: return & access::rw(mem_actual[in_col*fixed_n_rows]); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: const eT* Chris@49: Mat::fixed::colptr(const uword in_col) const Chris@49: { Chris@49: const eT* mem_actual = (use_extra) ? mem_local_extra : mem_local; Chris@49: Chris@49: return & mem_actual[in_col*fixed_n_rows]; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: eT* Chris@49: Mat::fixed::memptr() Chris@49: { Chris@49: return (use_extra) ? mem_local_extra : mem_local; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: const eT* Chris@49: Mat::fixed::memptr() const Chris@49: { Chris@49: return (use_extra) ? mem_local_extra : mem_local; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_inline Chris@49: arma_warn_unused Chris@49: bool Chris@49: Mat::fixed::is_vec() const Chris@49: { Chris@49: return ( (fixed_n_rows == 1) || (fixed_n_cols == 1) ); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_hot Chris@49: inline Chris@49: const Mat& Chris@49: Mat::fixed::fill(const eT val) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: eT* mem_use = (use_extra) ? &(mem_local_extra[0]) : &(mem_local[0]); Chris@49: Chris@49: arrayops::inplace_set_fixed( mem_use, val ); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_hot Chris@49: inline Chris@49: const Mat& Chris@49: Mat::fixed::zeros() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: eT* mem_use = (use_extra) ? &(mem_local_extra[0]) : &(mem_local[0]); Chris@49: Chris@49: arrayops::inplace_set_fixed( mem_use, eT(0) ); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: arma_hot Chris@49: inline Chris@49: const Mat& Chris@49: Mat::fixed::ones() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: eT* mem_use = (use_extra) ? &(mem_local_extra[0]) : &(mem_local[0]); Chris@49: Chris@49: arrayops::inplace_set_fixed( mem_use, eT(1) ); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! prefix ++ Chris@49: template Chris@49: arma_inline Chris@49: void Chris@49: Mat_aux::prefix_pp(Mat& x) Chris@49: { Chris@49: eT* memptr = x.memptr(); Chris@49: const uword n_elem = x.n_elem; Chris@49: Chris@49: uword i,j; Chris@49: Chris@49: for(i=0, j=1; j Chris@49: arma_inline Chris@49: void Chris@49: Mat_aux::prefix_pp(Mat< std::complex >& x) Chris@49: { Chris@49: x += T(1); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! postfix ++ Chris@49: template Chris@49: arma_inline Chris@49: void Chris@49: Mat_aux::postfix_pp(Mat& x) Chris@49: { Chris@49: eT* memptr = x.memptr(); Chris@49: const uword n_elem = x.n_elem; Chris@49: Chris@49: uword i,j; Chris@49: Chris@49: for(i=0, j=1; j Chris@49: arma_inline Chris@49: void Chris@49: Mat_aux::postfix_pp(Mat< std::complex >& x) Chris@49: { Chris@49: x += T(1); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! prefix -- Chris@49: template Chris@49: arma_inline Chris@49: void Chris@49: Mat_aux::prefix_mm(Mat& x) Chris@49: { Chris@49: eT* memptr = x.memptr(); Chris@49: const uword n_elem = x.n_elem; Chris@49: Chris@49: uword i,j; Chris@49: Chris@49: for(i=0, j=1; j Chris@49: arma_inline Chris@49: void Chris@49: Mat_aux::prefix_mm(Mat< std::complex >& x) Chris@49: { Chris@49: x -= T(1); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! postfix -- Chris@49: template Chris@49: arma_inline Chris@49: void Chris@49: Mat_aux::postfix_mm(Mat& x) Chris@49: { Chris@49: eT* memptr = x.memptr(); Chris@49: const uword n_elem = x.n_elem; Chris@49: Chris@49: uword i,j; Chris@49: Chris@49: for(i=0, j=1; j Chris@49: arma_inline Chris@49: void Chris@49: Mat_aux::postfix_mm(Mat< std::complex >& x) Chris@49: { Chris@49: x -= T(1); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat_aux::set_real(Mat& out, const Base& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const unwrap tmp(X.get_ref()); Chris@49: const Mat& A = tmp.M; Chris@49: Chris@49: arma_debug_assert_same_size( out, A, "Mat::set_real()" ); Chris@49: Chris@49: out = A; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat_aux::set_imag(Mat&, const Base&) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat_aux::set_real(Mat< std::complex >& out, const Base& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: typedef typename std::complex eT; Chris@49: Chris@49: const Proxy P(X.get_ref()); Chris@49: Chris@49: const uword local_n_rows = P.get_n_rows(); Chris@49: const uword local_n_cols = P.get_n_cols(); Chris@49: Chris@49: arma_debug_assert_same_size( out.n_rows, out.n_cols, local_n_rows, local_n_cols, "Mat::set_real()" ); Chris@49: Chris@49: eT* out_mem = out.memptr(); Chris@49: Chris@49: if(Proxy::prefer_at_accessor == false) Chris@49: { Chris@49: typedef typename Proxy::ea_type ea_type; Chris@49: Chris@49: ea_type A = P.get_ea(); Chris@49: Chris@49: const uword N = out.n_elem; Chris@49: Chris@49: for(uword i=0; i( A[i], out_mem[i].imag() ); Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: for(uword col=0; col < local_n_cols; ++col) Chris@49: for(uword row=0; row < local_n_rows; ++row) Chris@49: { Chris@49: (*out_mem) = std::complex( P.at(row,col), (*out_mem).imag() ); Chris@49: out_mem++; Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: void Chris@49: Mat_aux::set_imag(Mat< std::complex >& out, const Base& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: typedef typename std::complex eT; Chris@49: Chris@49: const Proxy P(X.get_ref()); Chris@49: Chris@49: const uword local_n_rows = P.get_n_rows(); Chris@49: const uword local_n_cols = P.get_n_cols(); Chris@49: Chris@49: arma_debug_assert_same_size( out.n_rows, out.n_cols, local_n_rows, local_n_cols, "Mat::set_imag()" ); Chris@49: Chris@49: eT* out_mem = out.memptr(); Chris@49: Chris@49: if(Proxy::prefer_at_accessor == false) Chris@49: { Chris@49: typedef typename Proxy::ea_type ea_type; Chris@49: Chris@49: ea_type A = P.get_ea(); Chris@49: Chris@49: const uword N = out.n_elem; Chris@49: Chris@49: for(uword i=0; i( out_mem[i].real(), A[i] ); Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: for(uword col=0; col < local_n_cols; ++col) Chris@49: for(uword row=0; row < local_n_rows; ++row) Chris@49: { Chris@49: (*out_mem) = std::complex( (*out_mem).real(), P.at(row,col) ); Chris@49: out_mem++; Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: #ifdef ARMA_EXTRA_MAT_MEAT Chris@49: #include ARMA_INCFILE_WRAP(ARMA_EXTRA_MAT_MEAT) Chris@49: #endif Chris@49: Chris@49: Chris@49: Chris@49: //! @}