max@0: // Copyright (C) 2008-2011 NICTA (www.nicta.com.au) max@0: // Copyright (C) 2008-2011 Conrad Sanderson max@0: // max@0: // This file is part of the Armadillo C++ library. max@0: // It is provided without any warranty of fitness max@0: // for any purpose. You can redistribute this file max@0: // and/or modify it under the terms of the GNU max@0: // Lesser General Public License (LGPL) as published max@0: // by the Free Software Foundation, either version 3 max@0: // of the License or (at your option) any later version. max@0: // (see http://www.opensource.org/licenses for more info) max@0: max@0: max@0: //! \addtogroup Cube max@0: //! @{ max@0: max@0: max@0: template max@0: inline max@0: Cube::~Cube() max@0: { max@0: arma_extra_debug_sigprint_this(this); max@0: max@0: delete_mat(); max@0: max@0: if(mem_state == 0) max@0: { max@0: if(n_elem > Cube_prealloc::mem_n_elem) max@0: { max@0: #if defined(ARMA_USE_TBB_ALLOC) max@0: scalable_free((void *)(mem)); max@0: #else max@0: delete [] mem; max@0: #endif max@0: } max@0: } max@0: max@0: if(arma_config::debug == true) max@0: { max@0: // try to expose buggy user code that accesses deleted objects max@0: access::rw(n_rows) = 0; max@0: access::rw(n_cols) = 0; max@0: access::rw(n_slices) = 0; max@0: access::rw(n_elem) = 0; max@0: access::rw(mat_ptrs) = 0; max@0: access::rw(mem) = 0; max@0: } max@0: max@0: arma_type_check(( is_supported_elem_type::value == false )); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: Cube::Cube() max@0: : n_rows(0) max@0: , n_cols(0) max@0: , n_elem_slice(0) max@0: , n_slices(0) max@0: , n_elem(0) max@0: , mem_state(0) max@0: , mat_ptrs() max@0: , mem() max@0: { max@0: arma_extra_debug_sigprint_this(this); max@0: } max@0: max@0: max@0: max@0: //! construct the cube to have user specified dimensions max@0: template max@0: inline max@0: Cube::Cube(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices) max@0: : n_rows(in_n_rows) max@0: , n_cols(in_n_cols) max@0: , n_elem_slice(in_n_rows*in_n_cols) max@0: , n_slices(in_n_slices) max@0: , n_elem(in_n_rows*in_n_cols*in_n_slices) max@0: , mem_state(0) max@0: , mat_ptrs() max@0: , mem() max@0: { max@0: arma_extra_debug_sigprint_this(this); max@0: max@0: init_cold(); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: void max@0: Cube::init_cold() max@0: { max@0: arma_extra_debug_sigprint( arma_boost::format("n_rows = %d, n_cols = %d, n_slices = %d") % n_rows % n_cols % n_slices ); max@0: max@0: arma_debug_check max@0: ( max@0: ( max@0: ( (n_rows > 0x0FFF) || (n_cols > 0x0FFF) || (n_slices > 0xFF) ) max@0: ? ( (float(n_rows) * float(n_cols) * float(n_slices)) > float(ARMA_MAX_UWORD) ) max@0: : false max@0: ), max@0: "Cube::init(): requested size is too large" max@0: ); max@0: max@0: if(n_elem <= Cube_prealloc::mem_n_elem) max@0: { max@0: access::rw(mem) = mem_local; max@0: } max@0: else max@0: { max@0: arma_extra_debug_print("Cube::init(): allocating memory"); max@0: max@0: #if defined(ARMA_USE_TBB_ALLOC) max@0: access::rw(mem) = (eT *)scalable_malloc(sizeof(eT)*n_elem); max@0: #else max@0: access::rw(mem) = new(std::nothrow) eT[n_elem]; max@0: #endif max@0: max@0: arma_check_bad_alloc( (mem == 0), "Cube::init(): out of memory" ); max@0: } max@0: max@0: max@0: if(n_elem == 0) max@0: { max@0: access::rw(n_rows) = 0; max@0: access::rw(n_cols) = 0; max@0: access::rw(n_elem_slice) = 0; max@0: access::rw(n_slices) = 0; max@0: } max@0: else max@0: { max@0: create_mat(); max@0: } max@0: } max@0: max@0: max@0: max@0: //! internal cube construction; if the requested size is small enough, memory from the stack is used. max@0: //! otherwise memory is allocated via 'new' max@0: template max@0: inline max@0: void max@0: Cube::init_warm(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices) max@0: { max@0: arma_extra_debug_sigprint( arma_boost::format("in_n_rows = %d, in_n_cols = %d, in_n_slices = %d") % in_n_rows % in_n_cols % in_n_slices ); max@0: max@0: if( (n_rows == in_n_rows) && (n_cols == in_n_cols) && (n_slices == in_n_slices) ) max@0: { max@0: return; max@0: } max@0: max@0: const uword t_mem_state = mem_state; max@0: max@0: bool err_state = false; max@0: char* err_msg = 0; max@0: max@0: arma_debug_set_error max@0: ( max@0: err_state, max@0: err_msg, max@0: (t_mem_state == 3), max@0: "Cube::init(): size is fixed and hence cannot be changed" max@0: ); max@0: max@0: arma_debug_set_error max@0: ( max@0: err_state, max@0: err_msg, max@0: ( max@0: ( (in_n_rows > 0x0FFF) || (in_n_cols > 0x0FFF) || (in_n_slices > 0xFF) ) max@0: ? ( (float(in_n_rows) * float(in_n_cols) * float(in_n_slices)) > float(ARMA_MAX_UWORD) ) max@0: : false max@0: ), max@0: "Cube::init(): requested size is too large" max@0: ); max@0: max@0: arma_debug_check(err_state, err_msg); max@0: max@0: const uword old_n_elem = n_elem; max@0: const uword new_n_elem = in_n_rows * in_n_cols * in_n_slices; max@0: max@0: if(old_n_elem == new_n_elem) max@0: { max@0: delete_mat(); max@0: max@0: if(new_n_elem > 0) max@0: { max@0: access::rw(n_rows) = in_n_rows; max@0: access::rw(n_cols) = in_n_cols; max@0: access::rw(n_elem_slice) = in_n_rows*in_n_cols; max@0: access::rw(n_slices) = in_n_slices; max@0: max@0: create_mat(); max@0: } max@0: } max@0: else max@0: { max@0: arma_debug_check( (t_mem_state == 2), "Cube::init(): requested size is not compatible with the size of auxiliary memory" ); max@0: max@0: delete_mat(); max@0: max@0: if(t_mem_state == 0) max@0: { max@0: if(n_elem > Cube_prealloc::mem_n_elem ) max@0: { max@0: arma_extra_debug_print("Cube::init(): freeing memory"); max@0: max@0: #if defined(ARMA_USE_TBB_ALLOC) max@0: scalable_free((void *)(mem)); max@0: #else max@0: delete [] mem; max@0: #endif max@0: } max@0: } max@0: max@0: access::rw(mem_state) = 0; max@0: max@0: if(new_n_elem <= Cube_prealloc::mem_n_elem) max@0: { max@0: access::rw(mem) = mem_local; max@0: } max@0: else max@0: { max@0: arma_extra_debug_print("Cube::init(): allocating memory"); max@0: max@0: #if defined(ARMA_USE_TBB_ALLOC) max@0: access::rw(mem) = (eT *)scalable_malloc(sizeof(eT)*new_n_elem); max@0: #else max@0: access::rw(mem) = new(std::nothrow) eT[new_n_elem]; max@0: #endif max@0: max@0: arma_check_bad_alloc( (mem == 0), "Cube::init(): out of memory" ); max@0: } max@0: max@0: if(new_n_elem > 0) max@0: { max@0: access::rw(n_rows) = in_n_rows; max@0: access::rw(n_cols) = in_n_cols; max@0: access::rw(n_elem_slice) = in_n_rows*in_n_cols; max@0: access::rw(n_slices) = in_n_slices; max@0: access::rw(n_elem) = new_n_elem; max@0: max@0: create_mat(); max@0: } max@0: } max@0: max@0: max@0: if(new_n_elem == 0) max@0: { max@0: access::rw(n_rows) = 0; max@0: access::rw(n_cols) = 0; max@0: access::rw(n_elem_slice) = 0; max@0: access::rw(n_slices) = 0; max@0: access::rw(n_elem) = 0; max@0: } max@0: } max@0: max@0: max@0: max@0: //! for constructing a complex cube out of two non-complex cubes max@0: template max@0: template max@0: inline max@0: void max@0: Cube::init max@0: ( max@0: const BaseCube::pod_type,T1>& A, max@0: const BaseCube::pod_type,T2>& B max@0: ) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: typedef typename T1::elem_type T; max@0: typedef typename ProxyCube::ea_type ea_type1; max@0: typedef typename ProxyCube::ea_type ea_type2; max@0: max@0: arma_type_check(( is_complex::value == false )); //!< compile-time abort if eT isn't std::complex max@0: arma_type_check(( is_complex< T>::value == true )); //!< compile-time abort if T is std::complex max@0: max@0: arma_type_check(( is_same_type< std::complex, eT >::value == false )); //!< compile-time abort if types are not compatible max@0: max@0: const ProxyCube X(A.get_ref()); max@0: const ProxyCube Y(B.get_ref()); max@0: max@0: arma_assert_same_size(X, Y, "Cube()"); max@0: max@0: init_warm(X.get_n_rows(), X.get_n_cols(), X.get_n_slices()); max@0: max@0: const uword N = n_elem; max@0: eT* out_mem = memptr(); max@0: ea_type1 PX = X.get_ea(); max@0: ea_type2 PY = Y.get_ea(); max@0: max@0: for(uword i=0; i(PX[i], PY[i]); max@0: } max@0: } max@0: max@0: max@0: max@0: //! try to steal the memory from a given cube; max@0: //! if memory can't be stolen, copy the given cube max@0: template max@0: inline max@0: void max@0: Cube::steal_mem(Cube& x) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: if(this != &x) max@0: { max@0: if( (x.mem_state == 0) && (x.n_elem > Cube_prealloc::mem_n_elem) ) max@0: { max@0: reset(); max@0: max@0: const uword x_n_slices = x.n_slices; max@0: max@0: access::rw(n_rows) = x.n_rows; max@0: access::rw(n_cols) = x.n_cols; max@0: access::rw(n_elem_slice) = x.n_elem_slice; max@0: access::rw(n_slices) = x_n_slices; max@0: access::rw(n_elem) = x.n_elem; max@0: access::rw(mem) = x.mem; max@0: max@0: if(x_n_slices > Cube_prealloc::mat_ptrs_size) max@0: { max@0: access::rw( mat_ptrs) = x.mat_ptrs; max@0: access::rw(x.mat_ptrs) = 0; max@0: } max@0: else max@0: { max@0: access::rw(mat_ptrs) = const_cast< const Mat** >(mat_ptrs_local); max@0: max@0: for(uword i=0; i < x_n_slices; ++i) max@0: { max@0: mat_ptrs[i] = x.mat_ptrs[i]; max@0: x.mat_ptrs[i] = 0; max@0: } max@0: } max@0: max@0: access::rw(x.n_rows) = 0; max@0: access::rw(x.n_cols) = 0; max@0: access::rw(x.n_elem_slice) = 0; max@0: access::rw(x.n_slices) = 0; max@0: access::rw(x.n_elem) = 0; max@0: access::rw(x.mem) = 0; max@0: } max@0: else max@0: { max@0: (*this).operator=(x); max@0: } max@0: } max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: void max@0: Cube::delete_mat() max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: for(uword slice = 0; slice < n_slices; ++slice) max@0: { max@0: delete access::rw(mat_ptrs[slice]); max@0: } max@0: max@0: if(mem_state <= 2) max@0: { max@0: if(n_slices > Cube_prealloc::mat_ptrs_size) max@0: { max@0: delete [] mat_ptrs; max@0: } max@0: } max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: void max@0: Cube::create_mat() max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: if(mem_state <= 2) max@0: { max@0: if(n_slices <= Cube_prealloc::mat_ptrs_size) max@0: { max@0: access::rw(mat_ptrs) = const_cast< const Mat** >(mat_ptrs_local); max@0: } max@0: else max@0: { max@0: access::rw(mat_ptrs) = new(std::nothrow) const Mat*[n_slices]; max@0: max@0: arma_check_bad_alloc( (mat_ptrs == 0), "Cube::create_mat(): out of memory" ); max@0: } max@0: } max@0: max@0: for(uword slice = 0; slice < n_slices; ++slice) max@0: { max@0: mat_ptrs[slice] = new Mat('j', slice_memptr(slice), n_rows, n_cols); max@0: } max@0: } max@0: max@0: max@0: max@0: //! Set the cube to be equal to the specified scalar. max@0: //! NOTE: the size of the cube will be 1x1x1 max@0: template max@0: arma_inline max@0: const Cube& max@0: Cube::operator=(const eT val) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: init_warm(1,1,1); max@0: access::rw(mem[0]) = val; max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! In-place addition of a scalar to all elements of the cube max@0: template max@0: arma_inline max@0: const Cube& max@0: Cube::operator+=(const eT val) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arrayops::inplace_plus( memptr(), val, n_elem ); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! In-place subtraction of a scalar from all elements of the cube max@0: template max@0: arma_inline max@0: const Cube& max@0: Cube::operator-=(const eT val) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arrayops::inplace_minus( memptr(), val, n_elem ); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! In-place multiplication of all elements of the cube with a scalar max@0: template max@0: arma_inline max@0: const Cube& max@0: Cube::operator*=(const eT val) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arrayops::inplace_mul( memptr(), val, n_elem ); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! In-place division of all elements of the cube with a scalar max@0: template max@0: arma_inline max@0: const Cube& max@0: Cube::operator/=(const eT val) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arrayops::inplace_div( memptr(), val, n_elem ); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! construct a cube from a given cube max@0: template max@0: inline max@0: Cube::Cube(const Cube& x) max@0: : n_rows(x.n_rows) max@0: , n_cols(x.n_cols) max@0: , n_elem_slice(x.n_elem_slice) max@0: , n_slices(x.n_slices) max@0: , n_elem(x.n_elem) max@0: , mem_state(0) max@0: , mat_ptrs() max@0: , mem() max@0: { max@0: arma_extra_debug_sigprint_this(this); max@0: arma_extra_debug_sigprint(arma_boost::format("this = %x in_cube = %x") % this % &x); max@0: max@0: init_cold(); max@0: max@0: arrayops::copy( memptr(), x.mem, n_elem ); max@0: } max@0: max@0: max@0: max@0: //! construct a cube from a given cube max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator=(const Cube& x) max@0: { max@0: arma_extra_debug_sigprint(arma_boost::format("this = %x in_cube = %x") % this % &x); max@0: max@0: if(this != &x) max@0: { max@0: init_warm(x.n_rows, x.n_cols, x.n_slices); max@0: max@0: arrayops::copy( memptr(), x.mem, n_elem ); max@0: } max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! construct a cube from a given auxiliary array of eTs. max@0: //! if copy_aux_mem is true, new memory is allocated and the array is copied. max@0: //! if copy_aux_mem is false, the auxiliary array is used directly (without allocating memory and copying). max@0: //! note that in the latter case max@0: //! the default is to copy the array. max@0: max@0: template max@0: inline max@0: Cube::Cube(eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const uword aux_n_slices, const bool copy_aux_mem, const bool strict) max@0: : n_rows ( aux_n_rows ) max@0: , n_cols ( aux_n_cols ) max@0: , n_elem_slice( aux_n_rows*aux_n_cols ) max@0: , n_slices ( aux_n_slices ) max@0: , n_elem ( aux_n_rows*aux_n_cols*aux_n_slices ) max@0: , mem_state ( copy_aux_mem ? 0 : (strict ? 2 : 1) ) max@0: , mat_ptrs ( 0 ) max@0: , mem ( copy_aux_mem ? 0 : aux_mem ) max@0: { max@0: arma_extra_debug_sigprint_this(this); max@0: max@0: if(copy_aux_mem == true) max@0: { max@0: init_cold(); max@0: max@0: arrayops::copy( memptr(), aux_mem, n_elem ); max@0: } max@0: else max@0: { max@0: create_mat(); max@0: } max@0: } max@0: max@0: max@0: max@0: //! construct a cube from a given auxiliary read-only array of eTs. max@0: //! the array is copied. max@0: template max@0: inline max@0: Cube::Cube(const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const uword aux_n_slices) max@0: : n_rows(aux_n_rows) max@0: , n_cols(aux_n_cols) max@0: , n_elem_slice(aux_n_rows*aux_n_cols) max@0: , n_slices(aux_n_slices) max@0: , n_elem(aux_n_rows*aux_n_cols*aux_n_slices) max@0: , mem_state(0) max@0: , mat_ptrs() max@0: , mem() max@0: { max@0: arma_extra_debug_sigprint_this(this); max@0: max@0: init_cold(); max@0: max@0: arrayops::copy( memptr(), aux_mem, n_elem ); max@0: } max@0: max@0: max@0: max@0: //! in-place cube addition max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator+=(const Cube& m) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_assert_same_size(*this, m, "cube addition"); max@0: max@0: arrayops::inplace_plus( memptr(), m.memptr(), n_elem ); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! in-place cube subtraction max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator-=(const Cube& m) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_assert_same_size(*this, m, "cube subtraction"); max@0: max@0: arrayops::inplace_minus( memptr(), m.memptr(), n_elem ); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! in-place element-wise cube multiplication max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator%=(const Cube& m) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_assert_same_size(*this, m, "element-wise cube multiplication"); max@0: max@0: arrayops::inplace_mul( memptr(), m.memptr(), n_elem ); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! in-place element-wise cube division max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator/=(const Cube& m) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_assert_same_size(*this, m, "element-wise cube division"); max@0: max@0: arrayops::inplace_div( memptr(), m.memptr(), n_elem ); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! for constructing a complex cube out of two non-complex cubes max@0: template max@0: template max@0: inline max@0: Cube::Cube max@0: ( max@0: const BaseCube::pod_type,T1>& A, max@0: const BaseCube::pod_type,T2>& B max@0: ) max@0: : n_rows(0) max@0: , n_cols(0) max@0: , n_elem_slice(0) max@0: , n_slices(0) max@0: , n_elem(0) max@0: , mem_state(0) max@0: , mat_ptrs() max@0: , mem() max@0: { max@0: arma_extra_debug_sigprint_this(this); max@0: max@0: init(A,B); max@0: } max@0: max@0: max@0: max@0: //! construct a cube from a subview_cube instance (e.g. construct a cube from a delayed subcube operation) max@0: template max@0: inline max@0: Cube::Cube(const subview_cube& X) max@0: : n_rows(X.n_rows) max@0: , n_cols(X.n_cols) max@0: , n_elem_slice(X.n_elem_slice) max@0: , n_slices(X.n_slices) max@0: , n_elem(X.n_elem) max@0: , mem_state(0) max@0: , mat_ptrs() max@0: , mem() max@0: { max@0: arma_extra_debug_sigprint_this(this); max@0: max@0: init_cold(); max@0: max@0: subview_cube::extract(*this, X); max@0: } max@0: max@0: max@0: max@0: //! construct a cube from a subview_cube instance (e.g. construct a cube from a delayed subcube operation) max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator=(const subview_cube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: const bool alias = (this == &(X.m)); max@0: max@0: if(alias == false) max@0: { max@0: init_warm(X.n_rows, X.n_cols, X.n_slices); max@0: max@0: subview_cube::extract(*this, X); max@0: } max@0: else max@0: { max@0: Cube tmp(X); max@0: max@0: steal_mem(tmp); max@0: } max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! in-place cube addition (using a subcube on the right-hand-side) max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator+=(const subview_cube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: subview_cube::plus_inplace(*this, X); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! in-place cube subtraction (using a subcube on the right-hand-side) max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator-=(const subview_cube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: subview_cube::minus_inplace(*this, X); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! in-place element-wise cube mutiplication (using a subcube on the right-hand-side) max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator%=(const subview_cube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: subview_cube::schur_inplace(*this, X); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! in-place element-wise cube division (using a subcube on the right-hand-side) max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator/=(const subview_cube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: subview_cube::div_inplace(*this, X); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! provide the reference to the matrix representing a single slice max@0: template max@0: arma_inline max@0: Mat& max@0: Cube::slice(const uword in_slice) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_check max@0: ( max@0: (in_slice >= n_slices), max@0: "Cube::slice(): index out of bounds" max@0: ); max@0: max@0: return const_cast< Mat& >( *(mat_ptrs[in_slice]) ); max@0: } max@0: max@0: max@0: max@0: //! provide the reference to the matrix representing a single slice max@0: template max@0: arma_inline max@0: const Mat& max@0: Cube::slice(const uword in_slice) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_check max@0: ( max@0: (in_slice >= n_slices), max@0: "Cube::slice(): index out of bounds" max@0: ); max@0: max@0: return *(mat_ptrs[in_slice]); max@0: } max@0: max@0: max@0: max@0: //! creation of subview_cube (subcube comprised of specified slices) max@0: template max@0: arma_inline max@0: subview_cube max@0: Cube::slices(const uword in_slice1, const uword in_slice2) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_check max@0: ( max@0: (in_slice1 > in_slice2) || (in_slice2 >= n_slices), max@0: "Cube::slices(): indices out of bounds or incorrectly used" max@0: ); max@0: max@0: const uword subcube_n_slices = in_slice2 - in_slice1 + 1; max@0: max@0: return subview_cube(*this, 0, 0, in_slice1, n_rows, n_cols, subcube_n_slices); max@0: } max@0: max@0: max@0: max@0: //! creation of subview_cube (subcube comprised of specified slices) max@0: template max@0: arma_inline max@0: const subview_cube max@0: Cube::slices(const uword in_slice1, const uword in_slice2) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_check max@0: ( max@0: (in_slice1 > in_slice2) || (in_slice2 >= n_slices), max@0: "Cube::rows(): indices out of bounds or incorrectly used" max@0: ); max@0: max@0: const uword subcube_n_slices = in_slice2 - in_slice1 + 1; max@0: max@0: return subview_cube(*this, 0, 0, in_slice1, n_rows, n_cols, subcube_n_slices); max@0: } max@0: max@0: max@0: max@0: //! creation of subview_cube (generic subcube) max@0: template max@0: arma_inline max@0: subview_cube max@0: Cube::subcube(const uword in_row1, const uword in_col1, const uword in_slice1, const uword in_row2, const uword in_col2, const uword in_slice2) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_check max@0: ( max@0: (in_row1 > in_row2) || (in_col1 > in_col2) || (in_slice1 > in_slice2) || max@0: (in_row2 >= n_rows) || (in_col2 >= n_cols) || (in_slice2 >= n_slices), max@0: "Cube::subcube(): indices out of bounds or incorrectly used" max@0: ); max@0: max@0: const uword subcube_n_rows = in_row2 - in_row1 + 1; max@0: const uword subcube_n_cols = in_col2 - in_col1 + 1; max@0: const uword subcube_n_slices = in_slice2 - in_slice1 + 1; max@0: max@0: return subview_cube(*this, in_row1, in_col1, in_slice1, subcube_n_rows, subcube_n_cols, subcube_n_slices); max@0: } max@0: max@0: max@0: max@0: //! creation of subview_cube (generic subcube) max@0: template max@0: arma_inline max@0: const subview_cube max@0: Cube::subcube(const uword in_row1, const uword in_col1, const uword in_slice1, const uword in_row2, const uword in_col2, const uword in_slice2) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_check max@0: ( max@0: (in_row1 > in_row2) || (in_col1 > in_col2) || (in_slice1 > in_slice2) || max@0: (in_row2 >= n_rows) || (in_col2 >= n_cols) || (in_slice2 >= n_slices), max@0: "Cube::subcube(): indices out of bounds or incorrectly used" max@0: ); max@0: max@0: const uword subcube_n_rows = in_row2 - in_row1 + 1; max@0: const uword subcube_n_cols = in_col2 - in_col1 + 1; max@0: const uword subcube_n_slices = in_slice2 - in_slice1 + 1; max@0: max@0: return subview_cube(*this, in_row1, in_col1, in_slice1, subcube_n_rows, subcube_n_cols, subcube_n_slices); max@0: } max@0: max@0: max@0: max@0: //! creation of subview_cube (generic subcube) max@0: template max@0: inline max@0: subview_cube max@0: Cube::subcube(const span& row_span, const span& col_span, const span& slice_span) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: const bool row_all = row_span.whole; max@0: const bool col_all = col_span.whole; max@0: const bool slice_all = slice_span.whole; max@0: max@0: const uword local_n_rows = n_rows; max@0: const uword local_n_cols = n_cols; max@0: const uword local_n_slices = n_slices; max@0: max@0: const uword in_row1 = row_all ? 0 : row_span.a; max@0: const uword in_row2 = row_span.b; max@0: const uword subcube_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1; max@0: max@0: const uword in_col1 = col_all ? 0 : col_span.a; max@0: const uword in_col2 = col_span.b; max@0: const uword subcube_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; max@0: max@0: const uword in_slice1 = slice_all ? 0 : slice_span.a; max@0: const uword in_slice2 = slice_span.b; max@0: const uword subcube_n_slices = slice_all ? local_n_slices : in_slice2 - in_slice1 + 1; max@0: max@0: arma_debug_check max@0: ( max@0: ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) max@0: || max@0: ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ) max@0: || max@0: ( slice_all ? false : ((in_slice1 > in_slice2) || (in_slice2 >= local_n_slices)) ) max@0: , max@0: "Cube::subcube(): indices out of bounds or incorrectly used" max@0: ); max@0: max@0: return subview_cube(*this, in_row1, in_col1, in_slice1, subcube_n_rows, subcube_n_cols, subcube_n_slices); max@0: } max@0: max@0: max@0: max@0: //! creation of subview_cube (generic subcube) max@0: template max@0: inline max@0: const subview_cube max@0: Cube::subcube(const span& row_span, const span& col_span, const span& slice_span) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: const bool row_all = row_span.whole; max@0: const bool col_all = col_span.whole; max@0: const bool slice_all = slice_span.whole; max@0: max@0: const uword local_n_rows = n_rows; max@0: const uword local_n_cols = n_cols; max@0: const uword local_n_slices = n_slices; max@0: max@0: const uword in_row1 = row_all ? 0 : row_span.a; max@0: const uword in_row2 = row_span.b; max@0: const uword subcube_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1; max@0: max@0: const uword in_col1 = col_all ? 0 : col_span.a; max@0: const uword in_col2 = col_span.b; max@0: const uword subcube_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; max@0: max@0: const uword in_slice1 = slice_all ? 0 : slice_span.a; max@0: const uword in_slice2 = slice_span.b; max@0: const uword subcube_n_slices = slice_all ? local_n_slices : in_slice2 - in_slice1 + 1; max@0: max@0: arma_debug_check max@0: ( max@0: ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ) max@0: || max@0: ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ) max@0: || max@0: ( slice_all ? false : ((in_slice1 > in_slice2) || (in_slice2 >= local_n_slices)) ) max@0: , max@0: "Cube::subcube(): indices out of bounds or incorrectly used" max@0: ); max@0: max@0: return subview_cube(*this, in_row1, in_col1, in_slice1, subcube_n_rows, subcube_n_cols, subcube_n_slices); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: subview_cube max@0: Cube::operator()(const span& row_span, const span& col_span, const span& slice_span) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: return (*this).subcube(row_span, col_span, slice_span); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: const subview_cube max@0: Cube::operator()(const span& row_span, const span& col_span, const span& slice_span) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: return (*this).subcube(row_span, col_span, slice_span); max@0: } max@0: max@0: max@0: max@0: //! remove specified slice max@0: template max@0: inline max@0: void max@0: Cube::shed_slice(const uword slice_num) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_check( slice_num >= n_slices, "Cube::shed_slice(): out of bounds"); max@0: max@0: shed_slices(slice_num, slice_num); max@0: } max@0: max@0: max@0: max@0: //! remove specified slices max@0: template max@0: inline max@0: void max@0: Cube::shed_slices(const uword in_slice1, const uword in_slice2) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_check max@0: ( max@0: (in_slice1 > in_slice2) || (in_slice2 >= n_slices), max@0: "Cube::shed_slices(): indices out of bounds or incorrectly used" max@0: ); max@0: max@0: const uword n_keep_front = in_slice1; max@0: const uword n_keep_back = n_slices - (in_slice2 + 1); max@0: max@0: Cube X(n_rows, n_cols, n_keep_front + n_keep_back); max@0: max@0: if(n_keep_front > 0) max@0: { max@0: X.slices( 0, (n_keep_front-1) ) = slices( 0, (in_slice1-1) ); max@0: } max@0: max@0: if(n_keep_back > 0) max@0: { max@0: X.slices( n_keep_front, (n_keep_front+n_keep_back-1) ) = slices( (in_slice2+1), (n_slices-1) ); max@0: } max@0: max@0: steal_mem(X); max@0: } max@0: max@0: max@0: max@0: //! insert N slices at the specified slice position, max@0: //! optionally setting the elements of the inserted slices to zero max@0: template max@0: inline max@0: void max@0: Cube::insert_slices(const uword slice_num, const uword N, const bool set_to_zero) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: const uword t_n_slices = n_slices; max@0: max@0: const uword A_n_slices = slice_num; max@0: const uword B_n_slices = t_n_slices - slice_num; max@0: max@0: // insertion at slice_num == n_slices is in effect an append operation max@0: arma_debug_check( (slice_num > t_n_slices), "Cube::insert_slices(): out of bounds"); max@0: max@0: if(N > 0) max@0: { max@0: Cube out(n_rows, n_cols, t_n_slices + N); max@0: max@0: if(A_n_slices > 0) max@0: { max@0: out.slices(0, A_n_slices-1) = slices(0, A_n_slices-1); max@0: } max@0: max@0: if(B_n_slices > 0) max@0: { max@0: out.slices(slice_num + N, t_n_slices + N - 1) = slices(slice_num, t_n_slices-1); max@0: } max@0: max@0: if(set_to_zero == true) max@0: { max@0: //out.slices(slice_num, slice_num + N - 1).zeros(); max@0: max@0: for(uword i=slice_num; i < (slice_num + N); ++i) max@0: { max@0: out.slice(i).zeros(); max@0: } max@0: } max@0: max@0: steal_mem(out); max@0: } max@0: } max@0: max@0: max@0: max@0: //! insert the given object at the specified slice position; max@0: //! the given object must have the same number of rows and columns as the cube max@0: template max@0: template max@0: inline max@0: void max@0: Cube::insert_slices(const uword slice_num, const BaseCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: const unwrap_cube tmp(X.get_ref()); max@0: const Cube& C = tmp.M; max@0: max@0: const uword N = C.n_slices; max@0: max@0: const uword t_n_slices = n_slices; max@0: max@0: const uword A_n_slices = slice_num; max@0: const uword B_n_slices = t_n_slices - slice_num; max@0: max@0: // insertion at slice_num == n_slices is in effect an append operation max@0: arma_debug_check( (slice_num > t_n_slices), "Cube::insert_slices(): out of bounds"); max@0: max@0: arma_debug_check max@0: ( max@0: ( (C.n_rows != n_rows) || (C.n_cols != n_cols) ), max@0: "Cube::insert_slices(): given object has an incompatible dimensions" max@0: ); max@0: max@0: if(N > 0) max@0: { max@0: Cube out(n_rows, n_cols, t_n_slices + N); max@0: max@0: if(A_n_slices > 0) max@0: { max@0: out.slices(0, A_n_slices-1) = slices(0, A_n_slices-1); max@0: } max@0: max@0: if(B_n_slices > 0) max@0: { max@0: out.slices(slice_num + N, t_n_slices + N - 1) = slices(slice_num, t_n_slices - 1); max@0: } max@0: max@0: out.slices(slice_num, slice_num + N - 1) = C; max@0: max@0: steal_mem(out); max@0: } max@0: } max@0: max@0: max@0: max@0: //! create a cube from OpCube, i.e. run the previously delayed unary operations max@0: template max@0: template max@0: inline max@0: Cube::Cube(const GenCube& X) max@0: : n_rows(X.n_rows) max@0: , n_cols(X.n_cols) max@0: , n_elem_slice(X.n_rows*X.n_cols) max@0: , n_slices(X.n_slices) max@0: , n_elem(X.n_rows*X.n_cols*X.n_slices) max@0: , mem_state(0) max@0: , mat_ptrs() max@0: , mem() max@0: { max@0: arma_extra_debug_sigprint_this(this); max@0: max@0: init_cold(); max@0: max@0: X.apply(*this); max@0: } max@0: max@0: max@0: max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator=(const GenCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: init_warm(X.n_rows, X.n_cols, X.n_slices); max@0: max@0: X.apply(*this); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator+=(const GenCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: X.apply_inplace_plus(*this); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator-=(const GenCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: X.apply_inplace_minus(*this); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator%=(const GenCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: X.apply_inplace_schur(*this); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator/=(const GenCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: X.apply_inplace_div(*this); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! create a cube from OpCube, i.e. run the previously delayed unary operations max@0: template max@0: template max@0: inline max@0: Cube::Cube(const OpCube& X) max@0: : n_rows(0) max@0: , n_cols(0) max@0: , n_elem_slice(0) max@0: , n_slices(0) max@0: , n_elem(0) max@0: , mem_state(0) max@0: , mat_ptrs() max@0: , mem() max@0: { max@0: arma_extra_debug_sigprint_this(this); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: max@0: op_type::apply(*this, X); max@0: } max@0: max@0: max@0: max@0: //! create a cube from OpCube, i.e. run the previously delayed unary operations max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator=(const OpCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: max@0: op_type::apply(*this, X); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! in-place cube addition, with the right-hand-side operand having delayed operations max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator+=(const OpCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: max@0: const Cube m(X); max@0: max@0: return (*this).operator+=(m); max@0: } max@0: max@0: max@0: max@0: //! in-place cube subtraction, with the right-hand-side operand having delayed operations max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator-=(const OpCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: max@0: const Cube m(X); max@0: max@0: return (*this).operator-=(m); max@0: } max@0: max@0: max@0: max@0: //! in-place cube element-wise multiplication, with the right-hand-side operand having delayed operations max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator%=(const OpCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: max@0: const Cube m(X); max@0: max@0: return (*this).operator%=(m); max@0: } max@0: max@0: max@0: max@0: //! in-place cube element-wise division, with the right-hand-side operand having delayed operations max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator/=(const OpCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: max@0: const Cube m(X); max@0: max@0: return (*this).operator/=(m); max@0: } max@0: max@0: max@0: max@0: //! create a cube from eOpCube, i.e. run the previously delayed unary operations max@0: template max@0: template max@0: inline max@0: Cube::Cube(const eOpCube& X) max@0: : n_rows(X.get_n_rows()) max@0: , n_cols(X.get_n_cols()) max@0: , n_elem_slice(X.get_n_elem_slice()) max@0: , n_slices(X.get_n_slices()) max@0: , n_elem(X.get_n_elem()) max@0: , mem_state(0) max@0: , mat_ptrs() max@0: , mem() max@0: { max@0: arma_extra_debug_sigprint_this(this); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: max@0: init_cold(); max@0: max@0: eop_type::apply(*this, X); max@0: } max@0: max@0: max@0: max@0: //! create a cube from eOpCube, i.e. run the previously delayed unary operations max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator=(const eOpCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: max@0: const bool bad_alias = ( X.P.has_subview && X.P.is_alias(*this) ); max@0: max@0: if(bad_alias == false) max@0: { max@0: init_warm(X.get_n_rows(), X.get_n_cols(), X.get_n_slices()); max@0: max@0: eop_type::apply(*this, X); max@0: } max@0: else max@0: { max@0: Cube tmp(X); max@0: max@0: steal_mem(tmp); max@0: } max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! in-place cube addition, with the right-hand-side operand having delayed operations max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator+=(const eOpCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: max@0: eop_type::apply_inplace_plus(*this, X); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! in-place cube subtraction, with the right-hand-side operand having delayed operations max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator-=(const eOpCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: max@0: eop_type::apply_inplace_minus(*this, X); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! in-place cube element-wise multiplication, with the right-hand-side operand having delayed operations max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator%=(const eOpCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: max@0: eop_type::apply_inplace_schur(*this, X); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! in-place cube element-wise division, with the right-hand-side operand having delayed operations max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator/=(const eOpCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: max@0: eop_type::apply_inplace_div(*this, X); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! EXPERIMENTAL max@0: template max@0: template max@0: inline max@0: Cube::Cube(const mtOpCube& X) max@0: : n_rows(0) max@0: , n_cols(0) max@0: , n_elem_slice(0) max@0: , n_slices(0) max@0: , n_elem(0) max@0: , mem_state(0) max@0: , mat_ptrs() max@0: , mem() max@0: { max@0: arma_extra_debug_sigprint_this(this); max@0: max@0: op_type::apply(*this, X); max@0: } max@0: max@0: max@0: max@0: //! EXPERIMENTAL max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator=(const mtOpCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: op_type::apply(*this, X); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! EXPERIMENTAL max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator+=(const mtOpCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: const Cube m(X); max@0: max@0: return (*this).operator+=(m); max@0: } max@0: max@0: max@0: max@0: //! EXPERIMENTAL max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator-=(const mtOpCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: const Cube m(X); max@0: max@0: return (*this).operator-=(m); max@0: } max@0: max@0: max@0: max@0: //! EXPERIMENTAL max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator%=(const mtOpCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: const Cube m(X); max@0: max@0: return (*this).operator%=(m); max@0: } max@0: max@0: max@0: max@0: //! EXPERIMENTAL max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator/=(const mtOpCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: const Cube m(X); max@0: max@0: return (*this).operator/=(m); max@0: } max@0: max@0: max@0: max@0: //! create a cube from Glue, i.e. run the previously delayed binary operations max@0: template max@0: template max@0: inline max@0: Cube::Cube(const GlueCube& X) max@0: : n_rows(0) max@0: , n_cols(0) max@0: , n_elem_slice(0) max@0: , n_slices(0) max@0: , n_elem(0) max@0: , mem_state(0) max@0: , mat_ptrs() max@0: , mem() max@0: { max@0: arma_extra_debug_sigprint_this(this); max@0: this->operator=(X); max@0: } max@0: max@0: max@0: max@0: //! create a cube from Glue, i.e. run the previously delayed binary operations max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator=(const GlueCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); max@0: max@0: glue_type::apply(*this, X); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: //! in-place cube addition, with the right-hand-side operands having delayed operations max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator+=(const GlueCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); max@0: max@0: const Cube m(X); max@0: max@0: return (*this).operator+=(m); max@0: } max@0: max@0: max@0: max@0: //! in-place cube subtraction, with the right-hand-side operands having delayed operations max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator-=(const GlueCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); max@0: max@0: const Cube m(X); max@0: max@0: return (*this).operator-=(m); max@0: } max@0: max@0: max@0: max@0: //! in-place cube element-wise multiplication, with the right-hand-side operands having delayed operations max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator%=(const GlueCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); max@0: max@0: const Cube m(X); max@0: max@0: return (*this).operator%=(m); max@0: } max@0: max@0: max@0: max@0: //! in-place cube element-wise division, with the right-hand-side operands having delayed operations max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator/=(const GlueCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); max@0: max@0: const Cube m(X); max@0: max@0: return (*this).operator/=(m); max@0: } max@0: max@0: max@0: max@0: //! create a cube from eGlue, i.e. run the previously delayed binary operations max@0: template max@0: template max@0: inline max@0: Cube::Cube(const eGlueCube& X) max@0: : n_rows(X.get_n_rows()) max@0: , n_cols(X.get_n_cols()) max@0: , n_elem_slice(X.get_n_elem_slice()) max@0: , n_slices(X.get_n_slices()) max@0: , n_elem(X.get_n_elem()) max@0: , mem_state(0) max@0: , mat_ptrs() max@0: , mem() max@0: { max@0: arma_extra_debug_sigprint_this(this); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); max@0: max@0: init_cold(); max@0: max@0: eglue_type::apply(*this, X); max@0: } max@0: max@0: max@0: max@0: //! create a cube from Glue, i.e. run the previously delayed binary operations max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator=(const eGlueCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); max@0: max@0: const bool bad_alias = ( (X.P1.has_subview && X.P1.is_alias(*this)) || (X.P2.has_subview && X.P2.is_alias(*this)) ); max@0: max@0: if(bad_alias == false) max@0: { max@0: init_warm(X.get_n_rows(), X.get_n_cols(), X.get_n_slices()); max@0: max@0: eglue_type::apply(*this, X); max@0: } max@0: else max@0: { max@0: Cube tmp(X); max@0: max@0: steal_mem(tmp); max@0: } max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! in-place cube addition, with the right-hand-side operands having delayed operations max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator+=(const eGlueCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); max@0: max@0: eglue_type::apply_inplace_plus(*this, X); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! in-place cube subtraction, with the right-hand-side operands having delayed operations max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator-=(const eGlueCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); max@0: max@0: eglue_type::apply_inplace_minus(*this, X); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! in-place cube element-wise multiplication, with the right-hand-side operands having delayed operations max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator%=(const eGlueCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); max@0: max@0: eglue_type::apply_inplace_schur(*this, X); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! in-place cube element-wise division, with the right-hand-side operands having delayed operations max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator/=(const eGlueCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false )); max@0: arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false )); max@0: max@0: eglue_type::apply_inplace_div(*this, X); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! EXPERIMENTAL max@0: template max@0: template max@0: inline max@0: Cube::Cube(const mtGlueCube& X) max@0: : n_rows(0) max@0: , n_cols(0) max@0: , n_elem_slice(0) max@0: , n_slices(0) max@0: , n_elem(0) max@0: , mem_state(0) max@0: , mat_ptrs() max@0: , mem() max@0: { max@0: arma_extra_debug_sigprint_this(this); max@0: max@0: glue_type::apply(*this, X); max@0: } max@0: max@0: max@0: max@0: //! EXPERIMENTAL max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator=(const mtGlueCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: glue_type::apply(*this, X); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! EXPERIMENTAL max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator+=(const mtGlueCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: const Cube m(X); max@0: max@0: return (*this).operator+=(m); max@0: } max@0: max@0: max@0: max@0: //! EXPERIMENTAL max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator-=(const mtGlueCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: const Cube m(X); max@0: max@0: return (*this).operator-=(m); max@0: } max@0: max@0: max@0: max@0: //! EXPERIMENTAL max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator%=(const mtGlueCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: const Cube m(X); max@0: max@0: return (*this).operator%=(m); max@0: } max@0: max@0: max@0: max@0: //! EXPERIMENTAL max@0: template max@0: template max@0: inline max@0: const Cube& max@0: Cube::operator/=(const mtGlueCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: const Cube m(X); max@0: max@0: return (*this).operator/=(m); max@0: } max@0: max@0: max@0: max@0: //! linear element accessor (treats the cube as a vector); bounds checking not done when ARMA_NO_DEBUG is defined max@0: template max@0: arma_inline max@0: arma_warn_unused max@0: eT& max@0: Cube::operator() (const uword i) max@0: { max@0: arma_debug_check( (i >= n_elem), "Cube::operator(): index out of bounds"); max@0: return access::rw(mem[i]); max@0: } max@0: max@0: max@0: max@0: //! linear element accessor (treats the cube as a vector); bounds checking not done when ARMA_NO_DEBUG is defined max@0: template max@0: arma_inline max@0: arma_warn_unused max@0: eT max@0: Cube::operator() (const uword i) const max@0: { max@0: arma_debug_check( (i >= n_elem), "Cube::operator(): index out of bounds"); max@0: return mem[i]; max@0: } max@0: max@0: max@0: //! linear element accessor (treats the cube as a vector); no bounds check. max@0: template max@0: arma_inline max@0: arma_warn_unused max@0: eT& max@0: Cube::operator[] (const uword i) max@0: { max@0: return access::rw(mem[i]); max@0: } max@0: max@0: max@0: max@0: //! linear element accessor (treats the cube as a vector); no bounds check max@0: template max@0: arma_inline max@0: arma_warn_unused max@0: eT max@0: Cube::operator[] (const uword i) const max@0: { max@0: return mem[i]; max@0: } max@0: max@0: max@0: max@0: //! linear element accessor (treats the cube as a vector); no bounds check. max@0: template max@0: arma_inline max@0: arma_warn_unused max@0: eT& max@0: Cube::at(const uword i) max@0: { max@0: return access::rw(mem[i]); max@0: } max@0: max@0: max@0: max@0: //! linear element accessor (treats the cube as a vector); no bounds check max@0: template max@0: arma_inline max@0: arma_warn_unused max@0: eT max@0: Cube::at(const uword i) const max@0: { max@0: return mem[i]; max@0: } max@0: max@0: max@0: max@0: //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined max@0: template max@0: arma_inline max@0: arma_warn_unused max@0: eT& max@0: Cube::operator() (const uword in_row, const uword in_col, const uword in_slice) max@0: { max@0: arma_debug_check max@0: ( max@0: (in_row >= n_rows) || max@0: (in_col >= n_cols) || max@0: (in_slice >= n_slices) max@0: , max@0: "Cube::operator(): index out of bounds" max@0: ); max@0: max@0: return access::rw(mem[in_slice*n_elem_slice + in_col*n_rows + in_row]); max@0: } max@0: max@0: max@0: max@0: //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined max@0: template max@0: arma_inline max@0: arma_warn_unused max@0: eT max@0: Cube::operator() (const uword in_row, const uword in_col, const uword in_slice) const max@0: { max@0: arma_debug_check max@0: ( max@0: (in_row >= n_rows) || max@0: (in_col >= n_cols) || max@0: (in_slice >= n_slices) max@0: , max@0: "Cube::operator(): index out of bounds" max@0: ); max@0: max@0: return mem[in_slice*n_elem_slice + in_col*n_rows + in_row]; max@0: } max@0: max@0: max@0: max@0: //! element accessor; no bounds check max@0: template max@0: arma_inline max@0: arma_warn_unused max@0: eT& max@0: Cube::at(const uword in_row, const uword in_col, const uword in_slice) max@0: { max@0: return access::rw( mem[in_slice*n_elem_slice + in_col*n_rows + in_row] ); max@0: } max@0: max@0: max@0: max@0: //! element accessor; no bounds check max@0: template max@0: arma_inline max@0: arma_warn_unused max@0: eT max@0: Cube::at(const uword in_row, const uword in_col, const uword in_slice) const max@0: { max@0: return mem[in_slice*n_elem_slice + in_col*n_rows + in_row]; max@0: } max@0: max@0: max@0: max@0: //! prefix ++ max@0: template max@0: arma_inline max@0: const Cube& max@0: Cube::operator++() max@0: { max@0: Cube_aux::prefix_pp(*this); max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! postfix ++ (must not return the object by reference) max@0: template max@0: arma_inline max@0: void max@0: Cube::operator++(int) max@0: { max@0: Cube_aux::postfix_pp(*this); max@0: } max@0: max@0: max@0: max@0: //! prefix -- max@0: template max@0: arma_inline max@0: const Cube& max@0: Cube::operator--() max@0: { max@0: Cube_aux::prefix_mm(*this); max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! postfix -- (must not return the object by reference) max@0: template max@0: arma_inline max@0: void max@0: Cube::operator--(int) max@0: { max@0: Cube_aux::postfix_mm(*this); max@0: } max@0: max@0: max@0: max@0: //! returns true if all of the elements are finite max@0: template max@0: arma_inline max@0: arma_warn_unused max@0: bool max@0: Cube::is_finite() const max@0: { max@0: return arrayops::is_finite( memptr(), n_elem ); max@0: } max@0: max@0: max@0: max@0: //! returns true if the cube has no elements max@0: template max@0: arma_inline max@0: arma_warn_unused max@0: bool max@0: Cube::is_empty() const max@0: { max@0: return (n_elem == 0); max@0: } max@0: max@0: max@0: max@0: //! returns true if the given index is currently in range max@0: template max@0: arma_inline max@0: arma_warn_unused max@0: bool max@0: Cube::in_range(const uword i) const max@0: { max@0: return (i < n_elem); max@0: } max@0: max@0: max@0: max@0: //! returns true if the given start and end indices are currently in range max@0: template max@0: arma_inline max@0: arma_warn_unused max@0: bool max@0: Cube::in_range(const span& x) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: if(x.whole == true) max@0: { max@0: return true; max@0: } max@0: else max@0: { max@0: const uword a = x.a; max@0: const uword b = x.b; max@0: max@0: return ( (a <= b) && (b < n_elem) ); max@0: } max@0: } max@0: max@0: max@0: max@0: //! returns true if the given location is currently in range max@0: template max@0: arma_inline max@0: arma_warn_unused max@0: bool max@0: Cube::in_range(const uword in_row, const uword in_col, const uword in_slice) const max@0: { max@0: return ( (in_row < n_rows) && (in_col < n_cols) && (in_slice < n_slices) ); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: arma_warn_unused max@0: bool max@0: Cube::in_range(const span& row_span, const span& col_span, const span& slice_span) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: const uword in_row1 = row_span.a; max@0: const uword in_row2 = row_span.b; max@0: max@0: const uword in_col1 = col_span.a; max@0: const uword in_col2 = col_span.b; max@0: max@0: const uword in_slice1 = slice_span.a; max@0: const uword in_slice2 = slice_span.b; max@0: max@0: max@0: const bool rows_ok = row_span.whole ? true : ( (in_row1 <= in_row2) && (in_row2 < n_rows) ); max@0: const bool cols_ok = col_span.whole ? true : ( (in_col1 <= in_col2) && (in_col2 < n_cols) ); max@0: const bool slices_ok = slice_span.whole ? true : ( (in_slice1 <= in_slice2) && (in_slice2 < n_slices) ); max@0: max@0: max@0: return ( (rows_ok == true) && (cols_ok == true) && (slices_ok == true) ); max@0: } max@0: max@0: max@0: max@0: //! returns a pointer to array of eTs used by the cube max@0: template max@0: arma_inline max@0: arma_warn_unused max@0: eT* max@0: Cube::memptr() max@0: { max@0: return const_cast(mem); max@0: } max@0: max@0: max@0: max@0: //! returns a pointer to array of eTs used by the cube max@0: template max@0: arma_inline max@0: arma_warn_unused max@0: const eT* max@0: Cube::memptr() const max@0: { max@0: return mem; max@0: } max@0: max@0: max@0: max@0: //! returns a pointer to array of eTs used by the specified slice in the cube max@0: template max@0: arma_inline max@0: arma_warn_unused max@0: eT* max@0: Cube::slice_memptr(const uword slice) max@0: { max@0: return const_cast( &mem[ slice*n_elem_slice ] ); max@0: } max@0: max@0: max@0: max@0: //! returns a pointer to array of eTs used by the specified slice in the cube max@0: template max@0: arma_inline max@0: arma_warn_unused max@0: const eT* max@0: Cube::slice_memptr(const uword slice) const max@0: { max@0: return &mem[ slice*n_elem_slice ]; max@0: } max@0: max@0: max@0: max@0: //! returns a pointer to array of eTs used by the specified slice in the cube max@0: template max@0: arma_inline max@0: arma_warn_unused max@0: eT* max@0: Cube::slice_colptr(const uword slice, const uword col) max@0: { max@0: return const_cast( &mem[ slice*n_elem_slice + col*n_rows] ); max@0: } max@0: max@0: max@0: max@0: //! returns a pointer to array of eTs used by the specified slice in the cube max@0: template max@0: arma_inline max@0: arma_warn_unused max@0: const eT* max@0: Cube::slice_colptr(const uword slice, const uword col) const max@0: { max@0: return &mem[ slice*n_elem_slice + col*n_rows ]; max@0: } max@0: max@0: max@0: max@0: //! print contents of the cube (to the cout stream), max@0: //! optionally preceding with a user specified line of text. max@0: //! the precision and cell width are modified. max@0: //! on return, the stream's state are restored to their original values. max@0: template max@0: inline max@0: void max@0: Cube::impl_print(const std::string& extra_text) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: if(extra_text.length() != 0) max@0: { max@0: ARMA_DEFAULT_OSTREAM << extra_text << '\n'; max@0: } max@0: max@0: arma_ostream::print(ARMA_DEFAULT_OSTREAM, *this, true); max@0: } max@0: max@0: max@0: //! print contents of the cube to a user specified stream, max@0: //! optionally preceding with a user specified line of text. max@0: //! the precision and cell width are modified. max@0: //! on return, the stream's state are restored to their original values. max@0: template max@0: inline max@0: void max@0: Cube::impl_print(std::ostream& user_stream, const std::string& extra_text) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: if(extra_text.length() != 0) max@0: { max@0: user_stream << extra_text << '\n'; max@0: } max@0: max@0: arma_ostream::print(user_stream, *this, true); max@0: } max@0: max@0: max@0: max@0: //! print contents of the cube (to the cout stream), max@0: //! optionally preceding with a user specified line of text. max@0: //! the stream's state are used as is and are not modified max@0: //! (i.e. the precision and cell width are not modified). max@0: template max@0: inline max@0: void max@0: Cube::impl_raw_print(const std::string& extra_text) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: if(extra_text.length() != 0) max@0: { max@0: ARMA_DEFAULT_OSTREAM << extra_text << '\n'; max@0: } max@0: max@0: arma_ostream::print(ARMA_DEFAULT_OSTREAM, *this, false); max@0: } max@0: max@0: max@0: max@0: //! print contents of the cube to a user specified stream, max@0: //! optionally preceding with a user specified line of text. max@0: //! the stream's state are used as is and are not modified. max@0: //! (i.e. the precision and cell width are not modified). max@0: template max@0: inline max@0: void max@0: Cube::impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: if(extra_text.length() != 0) max@0: { max@0: user_stream << extra_text << '\n'; max@0: } max@0: max@0: arma_ostream::print(user_stream, *this, false); max@0: } max@0: max@0: max@0: max@0: //! change the cube to have user specified dimensions (data is not preserved) max@0: template max@0: inline max@0: void max@0: Cube::set_size(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: init_warm(in_n_rows, in_n_cols, in_n_slices); max@0: } max@0: max@0: max@0: max@0: //! change the cube to have user specified dimensions (data is preserved) max@0: template max@0: inline max@0: void max@0: Cube::reshape(const uword in_rows, const uword in_cols, const uword in_slices, const uword dim) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: *this = arma::reshape(*this, in_rows, in_cols, in_slices, dim); max@0: } max@0: max@0: max@0: max@0: //! change the cube to have user specified dimensions (data is preserved) max@0: template max@0: inline max@0: void max@0: Cube::resize(const uword in_rows, const uword in_cols, const uword in_slices) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: *this = arma::resize(*this, in_rows, in_cols, in_slices); max@0: } max@0: max@0: max@0: max@0: //! change the cube (without preserving data) to have the same dimensions as the given cube max@0: template max@0: template max@0: inline max@0: void max@0: Cube::copy_size(const Cube& m) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: init_warm(m.n_rows, m.n_cols, m.n_slices); max@0: } max@0: max@0: max@0: max@0: //! fill the cube with the specified value max@0: template max@0: inline max@0: const Cube& max@0: Cube::fill(const eT val) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arrayops::inplace_set( memptr(), val, n_elem ); max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: const Cube& max@0: Cube::zeros() max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: return (*this).fill(eT(0)); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: const Cube& max@0: Cube::zeros(const uword in_rows, const uword in_cols, const uword in_slices) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: set_size(in_rows, in_cols, in_slices); max@0: max@0: return (*this).fill(eT(0)); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: const Cube& max@0: Cube::ones() max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: return (*this).fill(eT(1)); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: const Cube& max@0: Cube::ones(const uword in_rows, const uword in_cols, const uword in_slices) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: set_size(in_rows, in_cols, in_slices); max@0: max@0: return (*this).fill(eT(1)); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: const Cube& max@0: Cube::randu() max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: const uword N = n_elem; max@0: eT* ptr = memptr(); max@0: max@0: uword i,j; max@0: max@0: for(i=0, j=1; j()); max@0: ptr[j] = eT(eop_aux_randu()); max@0: } max@0: max@0: if(i < N) max@0: { max@0: ptr[i] = eT(eop_aux_randu()); max@0: } max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: const Cube& max@0: Cube::randu(const uword in_rows, const uword in_cols, const uword in_slices) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: set_size(in_rows, in_cols, in_slices); max@0: max@0: return (*this).randu(); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: const Cube& max@0: Cube::randn() max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: const uword N = n_elem; max@0: eT* ptr = memptr(); max@0: max@0: for(uword i=0; i()); max@0: } max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: const Cube& max@0: Cube::randn(const uword in_rows, const uword in_cols, const uword in_slices) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: set_size(in_rows, in_cols, in_slices); max@0: max@0: return (*this).randn(); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: void max@0: Cube::reset() max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: init_warm(0,0,0); max@0: } max@0: max@0: max@0: max@0: template max@0: template max@0: inline max@0: void max@0: Cube::set_real(const BaseCube::pod_type,T1>& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: Cube_aux::set_real(*this, X); max@0: } max@0: max@0: max@0: max@0: template max@0: template max@0: inline max@0: void max@0: Cube::set_imag(const BaseCube::pod_type,T1>& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: Cube_aux::set_imag(*this, X); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: arma_warn_unused max@0: eT max@0: Cube::min() const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_check( (n_elem == 0), "min(): object has no elements" ); max@0: max@0: return op_min::direct_min(memptr(), n_elem); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: arma_warn_unused max@0: eT max@0: Cube::max() const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_check( (n_elem == 0), "max(): object has no elements" ); max@0: max@0: return op_max::direct_max(memptr(), n_elem); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: eT max@0: Cube::min(uword& index_of_min_val) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_check( (n_elem == 0), "min(): object has no elements" ); max@0: max@0: return op_min::direct_min(memptr(), n_elem, index_of_min_val); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: eT max@0: Cube::max(uword& index_of_max_val) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_check( (n_elem == 0), "max(): object has no elements" ); max@0: max@0: return op_max::direct_max(memptr(), n_elem, index_of_max_val); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: eT max@0: Cube::min(uword& row_of_min_val, uword& col_of_min_val, uword& slice_of_min_val) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_check( (n_elem == 0), "min(): object has no elements" ); max@0: max@0: uword i; max@0: max@0: eT val = op_min::direct_min(memptr(), n_elem, i); max@0: max@0: const uword in_slice = i / n_elem_slice; max@0: const uword offset = in_slice * n_elem_slice; max@0: const uword j = i - offset; max@0: max@0: row_of_min_val = j % n_rows; max@0: col_of_min_val = j / n_rows; max@0: slice_of_min_val = in_slice; max@0: max@0: return val; max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: eT max@0: Cube::max(uword& row_of_max_val, uword& col_of_max_val, uword& slice_of_max_val) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_check( (n_elem == 0), "max(): object has no elements" ); max@0: max@0: uword i; max@0: max@0: eT val = op_max::direct_max(memptr(), n_elem, i); max@0: max@0: const uword in_slice = i / n_elem_slice; max@0: const uword offset = in_slice * n_elem_slice; max@0: const uword j = i - offset; max@0: max@0: row_of_max_val = j % n_rows; max@0: col_of_max_val = j / n_rows; max@0: slice_of_max_val = in_slice; max@0: max@0: return val; max@0: } max@0: max@0: max@0: max@0: //! save the cube to a file max@0: template max@0: inline max@0: bool max@0: Cube::save(const std::string name, const file_type type, const bool print_status) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: bool save_okay; max@0: max@0: switch(type) max@0: { max@0: case raw_ascii: max@0: save_okay = diskio::save_raw_ascii(*this, name); max@0: break; max@0: max@0: case arma_ascii: max@0: save_okay = diskio::save_arma_ascii(*this, name); max@0: break; max@0: max@0: case raw_binary: max@0: save_okay = diskio::save_raw_binary(*this, name); max@0: break; max@0: max@0: case arma_binary: max@0: save_okay = diskio::save_arma_binary(*this, name); max@0: break; max@0: max@0: case ppm_binary: max@0: save_okay = diskio::save_ppm_binary(*this, name); max@0: break; max@0: max@0: default: max@0: arma_warn(print_status, "Cube::save(): unsupported file type"); max@0: save_okay = false; max@0: } max@0: max@0: arma_warn( (print_status && (save_okay == false)), "Cube::save(): couldn't write to ", name); max@0: max@0: return save_okay; max@0: } max@0: max@0: max@0: max@0: //! save the cube to a stream max@0: template max@0: inline max@0: bool max@0: Cube::save(std::ostream& os, const file_type type, const bool print_status) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: bool save_okay; max@0: max@0: switch(type) max@0: { max@0: case raw_ascii: max@0: save_okay = diskio::save_raw_ascii(*this, os); max@0: break; max@0: max@0: case arma_ascii: max@0: save_okay = diskio::save_arma_ascii(*this, os); max@0: break; max@0: max@0: case raw_binary: max@0: save_okay = diskio::save_raw_binary(*this, os); max@0: break; max@0: max@0: case arma_binary: max@0: save_okay = diskio::save_arma_binary(*this, os); max@0: break; max@0: max@0: case ppm_binary: max@0: save_okay = diskio::save_ppm_binary(*this, os); max@0: break; max@0: max@0: default: max@0: arma_warn(print_status, "Cube::save(): unsupported file type"); max@0: save_okay = false; max@0: } max@0: max@0: arma_warn( (print_status && (save_okay == false)), "Cube::save(): couldn't write to given stream"); max@0: max@0: return save_okay; max@0: } max@0: max@0: max@0: max@0: //! load a cube from a file max@0: template max@0: inline max@0: bool max@0: Cube::load(const std::string name, const file_type type, const bool print_status) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: bool load_okay; max@0: std::string err_msg; max@0: max@0: switch(type) max@0: { max@0: case auto_detect: max@0: load_okay = diskio::load_auto_detect(*this, name, err_msg); max@0: break; max@0: max@0: case raw_ascii: max@0: load_okay = diskio::load_raw_ascii(*this, name, err_msg); max@0: break; max@0: max@0: case arma_ascii: max@0: load_okay = diskio::load_arma_ascii(*this, name, err_msg); max@0: break; max@0: max@0: case raw_binary: max@0: load_okay = diskio::load_raw_binary(*this, name, err_msg); max@0: break; max@0: max@0: case arma_binary: max@0: load_okay = diskio::load_arma_binary(*this, name, err_msg); max@0: break; max@0: max@0: case ppm_binary: max@0: load_okay = diskio::load_ppm_binary(*this, name, err_msg); max@0: break; max@0: max@0: default: max@0: arma_warn(print_status, "Cube::load(): unsupported file type"); max@0: load_okay = false; max@0: } max@0: max@0: if( (print_status == true) && (load_okay == false) ) max@0: { max@0: if(err_msg.length() > 0) max@0: { max@0: arma_warn(true, "Cube::load(): ", err_msg, name); max@0: } max@0: else max@0: { max@0: arma_warn(true, "Cube::load(): couldn't read ", name); max@0: } max@0: } max@0: max@0: if(load_okay == false) max@0: { max@0: (*this).reset(); max@0: } max@0: max@0: return load_okay; max@0: } max@0: max@0: max@0: max@0: //! load a cube from a stream max@0: template max@0: inline max@0: bool max@0: Cube::load(std::istream& is, const file_type type, const bool print_status) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: bool load_okay; max@0: std::string err_msg; max@0: max@0: switch(type) max@0: { max@0: case auto_detect: max@0: load_okay = diskio::load_auto_detect(*this, is, err_msg); max@0: break; max@0: max@0: case raw_ascii: max@0: load_okay = diskio::load_raw_ascii(*this, is, err_msg); max@0: break; max@0: max@0: case arma_ascii: max@0: load_okay = diskio::load_arma_ascii(*this, is, err_msg); max@0: break; max@0: max@0: case raw_binary: max@0: load_okay = diskio::load_raw_binary(*this, is, err_msg); max@0: break; max@0: max@0: case arma_binary: max@0: load_okay = diskio::load_arma_binary(*this, is, err_msg); max@0: break; max@0: max@0: case ppm_binary: max@0: load_okay = diskio::load_ppm_binary(*this, is, err_msg); max@0: break; max@0: max@0: default: max@0: arma_warn(print_status, "Cube::load(): unsupported file type"); max@0: load_okay = false; max@0: } max@0: max@0: max@0: if( (print_status == true) && (load_okay == false) ) max@0: { max@0: if(err_msg.length() > 0) max@0: { max@0: arma_warn(true, "Cube::load(): ", err_msg, "the given stream"); max@0: } max@0: else max@0: { max@0: arma_warn(true, "Cube::load(): couldn't load from the given stream"); max@0: } max@0: } max@0: max@0: if(load_okay == false) max@0: { max@0: (*this).reset(); max@0: } max@0: max@0: return load_okay; max@0: } max@0: max@0: max@0: max@0: //! save the cube to a file, without printing any error messages max@0: template max@0: inline max@0: bool max@0: Cube::quiet_save(const std::string name, const file_type type) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: return (*this).save(name, type, false); max@0: } max@0: max@0: max@0: max@0: //! save the cube to a stream, without printing any error messages max@0: template max@0: inline max@0: bool max@0: Cube::quiet_save(std::ostream& os, const file_type type) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: return (*this).save(os, type, false); max@0: } max@0: max@0: max@0: max@0: //! load a cube from a file, without printing any error messages max@0: template max@0: inline max@0: bool max@0: Cube::quiet_load(const std::string name, const file_type type) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: return (*this).load(name, type, false); max@0: } max@0: max@0: max@0: max@0: //! load a cube from a stream, without printing any error messages max@0: template max@0: inline max@0: bool max@0: Cube::quiet_load(std::istream& is, const file_type type) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: return (*this).load(is, type, false); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: typename Cube::iterator max@0: Cube::begin() max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: return memptr(); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: typename Cube::const_iterator max@0: Cube::begin() const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: return memptr(); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: typename Cube::iterator max@0: Cube::end() max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: return memptr() + n_elem; max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: typename Cube::const_iterator max@0: Cube::end() const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: return memptr() + n_elem; max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: typename Cube::slice_iterator max@0: Cube::begin_slice(const uword slice_num) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_check( (slice_num >= n_slices), "begin_slice(): index out of bounds"); max@0: max@0: return slice_memptr(slice_num); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: typename Cube::const_slice_iterator max@0: Cube::begin_slice(const uword slice_num) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_check( (slice_num >= n_slices), "begin_slice(): index out of bounds"); max@0: max@0: return slice_memptr(slice_num); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: typename Cube::slice_iterator max@0: Cube::end_slice(const uword slice_num) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_check( (slice_num >= n_slices), "end_slice(): index out of bounds"); max@0: max@0: return slice_memptr(slice_num) + n_elem_slice; max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: typename Cube::const_slice_iterator max@0: Cube::end_slice(const uword slice_num) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_debug_check( (slice_num >= n_slices), "end_slice(): index out of bounds"); max@0: max@0: return slice_memptr(slice_num) + n_elem_slice; max@0: } max@0: max@0: max@0: max@0: template max@0: template max@0: arma_inline max@0: void max@0: Cube::fixed::mem_setup() max@0: { max@0: arma_extra_debug_sigprint_this(this); max@0: max@0: if(fixed_n_elem > 0) max@0: { max@0: access::rw(Cube::n_rows) = fixed_n_rows; max@0: access::rw(Cube::n_cols) = fixed_n_cols; max@0: access::rw(Cube::n_elem_slice) = fixed_n_rows * fixed_n_cols; max@0: access::rw(Cube::n_slices) = fixed_n_slices; max@0: access::rw(Cube::n_elem) = fixed_n_elem; max@0: access::rw(Cube::mem_state) = 3; max@0: access::rw(Cube::mat_ptrs) = const_cast< const Mat** >( \ max@0: (fixed_n_slices > Cube_prealloc::mat_ptrs_size) ? mat_ptrs_local_extra : mat_ptrs_local ); max@0: access::rw(Cube::mem) = (fixed_n_elem > Cube_prealloc::mem_n_elem) ? mem_local_extra : mem_local; max@0: max@0: create_mat(); max@0: } max@0: else max@0: { max@0: access::rw(Cube::n_rows) = 0; max@0: access::rw(Cube::n_cols) = 0; max@0: access::rw(Cube::n_elem_slice) = 0; max@0: access::rw(Cube::n_slices) = 0; max@0: access::rw(Cube::n_elem) = 0; max@0: access::rw(Cube::mem_state) = 3; max@0: access::rw(Cube::mat_ptrs) = 0; max@0: access::rw(Cube::mem) = 0; max@0: } max@0: } max@0: max@0: max@0: max@0: //! prefix ++ max@0: template max@0: arma_inline max@0: void max@0: Cube_aux::prefix_pp(Cube& x) max@0: { max@0: eT* memptr = x.memptr(); max@0: const uword n_elem = x.n_elem; max@0: max@0: uword i,j; max@0: max@0: for(i=0, j=1; j max@0: arma_inline max@0: void max@0: Cube_aux::prefix_pp(Cube< std::complex >& x) max@0: { max@0: x += T(1); max@0: } max@0: max@0: max@0: max@0: //! postfix ++ max@0: template max@0: arma_inline max@0: void max@0: Cube_aux::postfix_pp(Cube& x) max@0: { max@0: eT* memptr = x.memptr(); max@0: const uword n_elem = x.n_elem; max@0: max@0: uword i,j; max@0: max@0: for(i=0, j=1; j max@0: arma_inline max@0: void max@0: Cube_aux::postfix_pp(Cube< std::complex >& x) max@0: { max@0: x += T(1); max@0: } max@0: max@0: max@0: max@0: //! prefix -- max@0: template max@0: arma_inline max@0: void max@0: Cube_aux::prefix_mm(Cube& x) max@0: { max@0: eT* memptr = x.memptr(); max@0: const uword n_elem = x.n_elem; max@0: max@0: uword i,j; max@0: max@0: for(i=0, j=1; j max@0: arma_inline max@0: void max@0: Cube_aux::prefix_mm(Cube< std::complex >& x) max@0: { max@0: x -= T(1); max@0: } max@0: max@0: max@0: max@0: //! postfix -- max@0: template max@0: arma_inline max@0: void max@0: Cube_aux::postfix_mm(Cube& x) max@0: { max@0: eT* memptr = x.memptr(); max@0: const uword n_elem = x.n_elem; max@0: max@0: uword i,j; max@0: max@0: for(i=0, j=1; j max@0: arma_inline max@0: void max@0: Cube_aux::postfix_mm(Cube< std::complex >& x) max@0: { max@0: x -= T(1); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: void max@0: Cube_aux::set_real(Cube& out, const BaseCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: const unwrap_cube tmp(X.get_ref()); max@0: const Cube& A = tmp.M; max@0: max@0: arma_debug_assert_same_size( out, A, "Cube::set_real()" ); max@0: max@0: out = A; max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: void max@0: Cube_aux::set_imag(Cube& out, const BaseCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: void max@0: Cube_aux::set_real(Cube< std::complex >& out, const BaseCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: typedef typename std::complex eT; max@0: typedef typename ProxyCube::ea_type ea_type; max@0: max@0: const ProxyCube A(X.get_ref()); max@0: max@0: arma_debug_assert_same_size max@0: ( max@0: out.n_rows, out.n_cols, out.n_slices, max@0: A.get_n_rows(), A.get_n_cols(), A.get_n_slices(), max@0: "Cube::set_real()" max@0: ); max@0: max@0: const uword n_elem = out.n_elem; max@0: eT* out_mem = out.memptr(); max@0: ea_type PA = A.get_ea(); max@0: max@0: for(uword i=0; i( PA[i], out_mem[i].imag() ); max@0: } max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: void max@0: Cube_aux::set_imag(Cube< std::complex >& out, const BaseCube& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: typedef typename std::complex eT; max@0: typedef typename ProxyCube::ea_type ea_type; max@0: max@0: const ProxyCube A(X.get_ref()); max@0: max@0: arma_debug_assert_same_size max@0: ( max@0: out.n_rows, out.n_cols, out.n_slices, max@0: A.get_n_rows(), A.get_n_cols(), A.get_n_slices(), max@0: "Cube::set_imag()" max@0: ); max@0: max@0: const uword n_elem = out.n_elem; max@0: eT* out_mem = out.memptr(); max@0: ea_type PA = A.get_ea(); max@0: max@0: for(uword i=0; i( out_mem[i].real(), PA[i] ); max@0: } max@0: } max@0: max@0: max@0: max@0: #ifdef ARMA_EXTRA_CUBE_MEAT max@0: #include ARMA_INCFILE_WRAP(ARMA_EXTRA_CUBE_MEAT) max@0: #endif max@0: max@0: max@0: max@0: //! @}