123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556 |
- // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
- // Copyright 2008-2016 National ICT Australia (NICTA)
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- // ------------------------------------------------------------------------
- //! \addtogroup subview_field
- //! @{
- template<typename oT>
- inline
- subview_field<oT>::~subview_field()
- {
- arma_extra_debug_sigprint();
- }
- template<typename oT>
- arma_inline
- subview_field<oT>::subview_field
- (
- const field<oT>& in_f,
- const uword in_row1,
- const uword in_col1,
- const uword in_n_rows,
- const uword in_n_cols
- )
- : f(in_f)
- , aux_row1(in_row1)
- , aux_col1(in_col1)
- , aux_slice1(0)
- , n_rows(in_n_rows)
- , n_cols(in_n_cols)
- , n_slices( (in_f.n_slices > 0) ? uword(1) : uword(0) )
- , n_elem(in_n_rows*in_n_cols*n_slices)
- {
- arma_extra_debug_sigprint();
- }
- template<typename oT>
- arma_inline
- subview_field<oT>::subview_field
- (
- const field<oT>& in_f,
- const uword in_row1,
- const uword in_col1,
- const uword in_slice1,
- const uword in_n_rows,
- const uword in_n_cols,
- const uword in_n_slices
- )
- : f(in_f)
- , aux_row1(in_row1)
- , aux_col1(in_col1)
- , aux_slice1(in_slice1)
- , n_rows(in_n_rows)
- , n_cols(in_n_cols)
- , n_slices(in_n_slices)
- , n_elem(in_n_rows*in_n_cols*in_n_slices)
- {
- arma_extra_debug_sigprint();
- }
- template<typename oT>
- inline
- void
- subview_field<oT>::operator= (const field<oT>& x)
- {
- arma_extra_debug_sigprint();
-
- subview_field<oT>& t = *this;
-
- arma_debug_check( (t.n_rows != x.n_rows) || (t.n_cols != x.n_cols) || (t.n_slices != x.n_slices), "incompatible field dimensions" );
-
- if(t.n_slices == 1)
- {
- for(uword col=0; col < t.n_cols; ++col)
- for(uword row=0; row < t.n_rows; ++row)
- {
- t.at(row,col) = x.at(row,col);
- }
- }
- else
- {
- for(uword slice=0; slice < t.n_slices; ++slice)
- for(uword col=0; col < t.n_cols; ++col )
- for(uword row=0; row < t.n_rows; ++row )
- {
- t.at(row,col,slice) = x.at(row,col,slice);
- }
- }
- }
- //! x.subfield(...) = y.subfield(...)
- template<typename oT>
- inline
- void
- subview_field<oT>::operator= (const subview_field<oT>& x)
- {
- arma_extra_debug_sigprint();
-
- if(check_overlap(x))
- {
- const field<oT> tmp(x);
-
- (*this).operator=(tmp);
-
- return;
- }
-
- subview_field<oT>& t = *this;
-
- arma_debug_check( (t.n_rows != x.n_rows) || (t.n_cols != x.n_cols) || (t.n_slices != x.n_slices), "incompatible field dimensions" );
-
- if(t.n_slices == 1)
- {
- for(uword col=0; col < t.n_cols; ++col)
- for(uword row=0; row < t.n_rows; ++row)
- {
- t.at(row,col) = x.at(row,col);
- }
- }
- else
- {
- for(uword slice=0; slice < t.n_slices; ++slice)
- for(uword col=0; col < t.n_cols; ++col )
- for(uword row=0; row < t.n_rows; ++row )
- {
- t.at(row,col,slice) = x.at(row,col,slice);
- }
- }
- }
- template<typename oT>
- arma_inline
- oT&
- subview_field<oT>::operator[](const uword i)
- {
- const uword n_elem_slice = n_rows*n_cols;
-
- const uword in_slice = i / n_elem_slice;
- const uword offset = in_slice * n_elem_slice;
- const uword j = i - offset;
-
- const uword in_col = j / n_rows;
- const uword in_row = j % n_rows;
-
- const uword index = (in_slice + aux_slice1)*(f.n_rows*f.n_cols) + (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
-
- return *((const_cast< field<oT>& >(f)).mem[index]);
- }
- template<typename oT>
- arma_inline
- const oT&
- subview_field<oT>::operator[](const uword i) const
- {
- const uword n_elem_slice = n_rows*n_cols;
-
- const uword in_slice = i / n_elem_slice;
- const uword offset = in_slice * n_elem_slice;
- const uword j = i - offset;
-
- const uword in_col = j / n_rows;
- const uword in_row = j % n_rows;
-
- const uword index = (in_slice + aux_slice1)*(f.n_rows*f.n_cols) + (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
-
- return *(f.mem[index]);
- }
- template<typename oT>
- arma_inline
- oT&
- subview_field<oT>::operator()(const uword i)
- {
- arma_debug_check( (i >= n_elem), "subview_field::operator(): index out of bounds" );
-
- return operator[](i);
- }
- template<typename oT>
- arma_inline
- const oT&
- subview_field<oT>::operator()(const uword i) const
- {
- arma_debug_check( (i >= n_elem), "subview_field::operator(): index out of bounds" );
-
- return operator[](i);
- }
- template<typename oT>
- arma_inline
- oT&
- subview_field<oT>::operator()(const uword in_row, const uword in_col)
- {
- return operator()(in_row, in_col, 0);
- }
- template<typename oT>
- arma_inline
- const oT&
- subview_field<oT>::operator()(const uword in_row, const uword in_col) const
- {
- return operator()(in_row, in_col, 0);
- }
- template<typename oT>
- arma_inline
- oT&
- subview_field<oT>::operator()(const uword in_row, const uword in_col, const uword in_slice)
- {
- arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols) || (in_slice >= n_slices)), "subview_field::operator(): index out of bounds" );
-
- const uword index = (in_slice + aux_slice1)*(f.n_rows*f.n_cols) + (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
-
- return *((const_cast< field<oT>& >(f)).mem[index]);
- }
- template<typename oT>
- arma_inline
- const oT&
- subview_field<oT>::operator()(const uword in_row, const uword in_col, const uword in_slice) const
- {
- arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols) || (in_slice >= n_slices)), "subview_field::operator(): index out of bounds" );
-
- const uword index = (in_slice + aux_slice1)*(f.n_rows*f.n_cols) + (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
-
- return *(f.mem[index]);
- }
- template<typename oT>
- arma_inline
- oT&
- subview_field<oT>::at(const uword in_row, const uword in_col)
- {
- return at(in_row, in_col, 0);
- }
- template<typename oT>
- arma_inline
- const oT&
- subview_field<oT>::at(const uword in_row, const uword in_col) const
- {
- return at(in_row, in_col, 0);
- }
- template<typename oT>
- arma_inline
- oT&
- subview_field<oT>::at(const uword in_row, const uword in_col, const uword in_slice)
- {
- const uword index = (in_slice + aux_slice1)*(f.n_rows*f.n_cols) + (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
-
- return *((const_cast< field<oT>& >(f)).mem[index]);
- }
- template<typename oT>
- arma_inline
- const oT&
- subview_field<oT>::at(const uword in_row, const uword in_col, const uword in_slice) const
- {
- const uword index = (in_slice + aux_slice1)*(f.n_rows*f.n_cols) + (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
-
- return *(f.mem[index]);
- }
- template<typename oT>
- arma_inline
- bool
- subview_field<oT>::is_empty() const
- {
- return (n_elem == 0);
- }
- template<typename oT>
- inline
- bool
- subview_field<oT>::check_overlap(const subview_field<oT>& x) const
- {
- const subview_field<oT>& t = *this;
-
- if(&t.f != &x.f)
- {
- return false;
- }
- else
- {
- if( (t.n_elem == 0) || (x.n_elem == 0) )
- {
- return false;
- }
- else
- {
- const uword t_row_start = t.aux_row1;
- const uword t_row_end_p1 = t_row_start + t.n_rows;
-
- const uword t_col_start = t.aux_col1;
- const uword t_col_end_p1 = t_col_start + t.n_cols;
-
- const uword t_slice_start = t.aux_slice1;
- const uword t_slice_end_p1 = t_slice_start + t.n_slices;
-
- const uword x_row_start = x.aux_row1;
- const uword x_row_end_p1 = x_row_start + x.n_rows;
-
- const uword x_col_start = x.aux_col1;
- const uword x_col_end_p1 = x_col_start + x.n_cols;
-
- const uword x_slice_start = x.aux_slice1;
- const uword x_slice_end_p1 = x_slice_start + x.n_slices;
-
- const bool outside_rows = ( (x_row_start >= t_row_end_p1 ) || (t_row_start >= x_row_end_p1 ) );
- const bool outside_cols = ( (x_col_start >= t_col_end_p1 ) || (t_col_start >= x_col_end_p1 ) );
- const bool outside_slices = ( (x_slice_start >= t_slice_end_p1) || (t_slice_start >= x_slice_end_p1) );
-
- return ( (outside_rows == false) && (outside_cols == false) && (outside_slices == false) );
- }
- }
- }
- template<typename oT>
- inline
- void
- subview_field<oT>::print(const std::string extra_text) const
- {
- arma_extra_debug_sigprint();
-
- if(extra_text.length() != 0)
- {
- const std::streamsize orig_width = get_cout_stream().width();
-
- get_cout_stream() << extra_text << '\n';
-
- get_cout_stream().width(orig_width);
- }
-
- arma_ostream::print(get_cout_stream(), *this);
- }
- template<typename oT>
- inline
- void
- subview_field<oT>::print(std::ostream& user_stream, const std::string extra_text) const
- {
- arma_extra_debug_sigprint();
-
- if(extra_text.length() != 0)
- {
- const std::streamsize orig_width = user_stream.width();
-
- user_stream << extra_text << '\n';
-
- user_stream.width(orig_width);
- }
-
- arma_ostream::print(user_stream, *this);
- }
- template<typename oT>
- template<typename functor>
- inline
- void
- subview_field<oT>::for_each(functor F)
- {
- arma_extra_debug_sigprint();
-
- subview_field<oT>& t = *this;
-
- if(t.n_slices == 1)
- {
- for(uword col=0; col < t.n_cols; ++col)
- for(uword row=0; row < t.n_rows; ++row)
- {
- F( t.at(row,col) );
- }
- }
- else
- {
- for(uword slice=0; slice < t.n_slices; ++slice)
- for(uword col=0; col < t.n_cols; ++col )
- for(uword row=0; row < t.n_rows; ++row )
- {
- F( t.at(row,col,slice) );
- }
- }
- }
- template<typename oT>
- template<typename functor>
- inline
- void
- subview_field<oT>::for_each(functor F) const
- {
- arma_extra_debug_sigprint();
-
- const subview_field<oT>& t = *this;
-
- if(t.n_slices == 1)
- {
- for(uword col=0; col < t.n_cols; ++col)
- for(uword row=0; row < t.n_rows; ++row)
- {
- F( t.at(row,col) );
- }
- }
- else
- {
- for(uword slice=0; slice < t.n_slices; ++slice)
- for(uword col=0; col < t.n_cols; ++col )
- for(uword row=0; row < t.n_rows; ++row )
- {
- F( t.at(row,col,slice) );
- }
- }
- }
- template<typename oT>
- inline
- void
- subview_field<oT>::fill(const oT& x)
- {
- arma_extra_debug_sigprint();
-
- subview_field<oT>& t = *this;
-
- if(t.n_slices == 1)
- {
- for(uword col=0; col < t.n_cols; ++col)
- for(uword row=0; row < t.n_rows; ++row)
- {
- t.at(row,col) = x;
- }
- }
- else
- {
- for(uword slice=0; slice < t.n_slices; ++slice)
- for(uword col=0; col < t.n_cols; ++col )
- for(uword row=0; row < t.n_rows; ++row )
- {
- t.at(row,col,slice) = x;
- }
- }
- }
- //! X = Y.subfield(...)
- template<typename oT>
- inline
- void
- subview_field<oT>::extract(field<oT>& actual_out, const subview_field<oT>& in)
- {
- arma_extra_debug_sigprint();
-
- //
- const bool alias = (&actual_out == &in.f);
-
- field<oT>* tmp = (alias) ? new field<oT> : 0;
- field<oT>& out = (alias) ? (*tmp) : actual_out;
-
- //
-
- const uword n_rows = in.n_rows;
- const uword n_cols = in.n_cols;
- const uword n_slices = in.n_slices;
-
- out.set_size(n_rows, n_cols, n_slices);
-
- arma_extra_debug_print(arma_str::format("out.n_rows = %d out.n_cols = %d out.n_slices = %d in.m.n_rows = %d in.m.n_cols = %d in.m.n_slices = %d") % out.n_rows % out.n_cols % out.n_slices % in.f.n_rows % in.f.n_cols % in.f.n_slices);
-
- if(n_slices == 1)
- {
- for(uword col = 0; col < n_cols; ++col)
- for(uword row = 0; row < n_rows; ++row)
- {
- out.at(row,col) = in.at(row,col);
- }
- }
- else
- {
- for(uword slice = 0; slice < n_slices; ++slice)
- for(uword col = 0; col < n_cols; ++col )
- for(uword row = 0; row < n_rows; ++row )
- {
- out.at(row,col,slice) = in.at(row,col,slice);
- }
- }
-
- if(alias)
- {
- actual_out = out;
- delete tmp;
- }
-
- }
- //! @}
|