#ifndef BLOCK_INDEXING_H #define BLOCK_INDEXING_H //----------------------------------------------------------------------------------------------------------// // Block indexing //----------------------------------------------------------------------------------------------------------// // Calls scalar indexing so they are fully bounds checked. template FASTOR_INLINE Tensor::value> operator()(const iseq& idx) { static_assert(1==dimension_t::value, "INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); Tensor::value> out; FASTOR_INDEX counter = 0; for (FASTOR_INDEX i=F; ioperator()(i); counter++; } return out; } template FASTOR_INLINE Tensor::value,range_detector::value> operator()(iseq, iseq) { static_assert(2==dimension_t::value, "INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); Tensor::value,range_detector::value> out; FASTOR_INDEX counter_i = 0; for (FASTOR_INDEX i=F0; ioperator()(i,j); counter_j++; } counter_i++; } return out; } template FASTOR_INLINE Tensor::value,range_detector::value,range_detector::value> operator()(iseq, iseq, iseq) const { static_assert(3==dimension_t::value, "INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); Tensor::value, range_detector::value, range_detector::value> out; FASTOR_INDEX counter_i = 0; for (FASTOR_INDEX i=F0; ioperator()(i,j,k); counter_k++; } counter_j++; } counter_i++; } return out; } template FASTOR_INLINE Tensor::value, range_detector::value, range_detector::value, range_detector::value> operator ()(iseq, iseq, iseq, iseq) { static_assert(4==dimension_t::value, "INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); Tensor::value, range_detector::value, range_detector::value, range_detector::value> out; FASTOR_INDEX counter_i = 0; for (FASTOR_INDEX i=F0; ioperator()(i,j,k,l); counter_l++; } counter_k++; } counter_j++; } counter_i++; } return out; } //----------------------------------------------------------------------------------------------------------// //----------------------------------------------------------------------------------------------------------// FASTOR_INLINE TensorViewExpr,1> operator()(seq _s) { static_assert(dimension_t::value==1,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorViewExpr,1>(*this,_s); } FASTOR_INLINE TensorViewExpr,2> operator()(seq _s0, seq _s1) { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorViewExpr,2>(*this,_s0,_s1); } template FASTOR_INLINE TensorViewExpr,2> operator()(fseq _s0, seq _s1) { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorViewExpr,2>(*this,_s0,_s1); } template FASTOR_INLINE TensorViewExpr,2> operator()(seq _s0, fseq _s1) { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorViewExpr,2>(*this,_s0,_s1); } template::value,bool>::type=0> FASTOR_INLINE TensorViewExpr,2> operator()(seq _s0, Int num) { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorViewExpr,2>(*this,_s0,seq(num)); } template::value,bool>::type=0> FASTOR_INLINE TensorViewExpr,2> operator()(Int num, seq _s1) { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorViewExpr,2>(*this,seq(num),_s1); } template && !is_fixed_sequence_pack_v,bool> = false> FASTOR_INLINE TensorViewExpr,sizeof...(Seq)> operator()(Seq ... _seqs) { static_assert(dimension_t::value==sizeof...(Seq),"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorViewExpr,sizeof...(Seq)>(*this, {_seqs...}); } template,bool> = false> FASTOR_INLINE TensorFixedViewExprnD,Fseq...> operator()(Fseq... ) { static_assert(dimension_t::value==sizeof...(Fseq),"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorFixedViewExprnD,Fseq...>(*this); } // if fseq == fall - then just return a reference to the tensor template, get_value<1,Rest...>::value>::type>::value == get_value<1,Rest...>::value, bool>::type =0> FASTOR_INLINE Tensor& operator()(fseq) { static_assert(dimension_t::value==1,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return (*this); } // if fseq != fall - return a view template, get_value<1,Rest...>::value>::type>::value != get_value<1,Rest...>::value, bool>::type =0> FASTOR_INLINE TensorFixedViewExpr1D, typename to_positive,pack_prod::value>::type,1> operator()(fseq) { static_assert(dimension_t::value==1,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorFixedViewExpr1D, typename to_positive,pack_prod::value>::type,1>(*this); } // if fseq == fall - then just return a reference to the tensor template,get_value<1,Rest...>::value>::type>::value == get_value<1,Rest...>::value && internal::fseq_range_detector,get_value<2,Rest...>::value>::type>::value == get_value<2,Rest...>::value, bool>::type =0> FASTOR_INLINE Tensor& operator()(fseq, fseq) { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return (*this); } // if fseq != fall - return a view template,get_value<1,Rest...>::value>::type>::value != get_value<1,Rest...>::value || internal::fseq_range_detector,get_value<2,Rest...>::value>::type>::value != get_value<2,Rest...>::value, bool>::type =0> FASTOR_INLINE TensorFixedViewExpr2D, typename to_positive,get_value<1,Rest...>::value>::type, typename to_positive,get_value<2,Rest...>::value>::type,2> operator()(fseq, fseq) { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorFixedViewExpr2D, typename to_positive,get_value<1,Rest...>::value>::type, typename to_positive,get_value<2,Rest...>::value>::type,2>(*this); } template::value,bool>::type=0> FASTOR_INLINE TensorViewExpr,2> operator()(fseq _s, Int num) { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorViewExpr,2>(*this,seq(_s),seq(num)); } template::value,bool>::type=0> FASTOR_INLINE TensorViewExpr,2> operator()(Int num, fseq _s) { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorViewExpr,2>(*this,seq(num),seq(_s)); } // Selecting a row and returning a TensorMap - does not seem to speed up the code //----------------------------------------------------------------------------------------------------------// // template::value && // internal::fseq_range_detector, // get_value<2,Rest...>::value>::type>::value != get_value<2,Rest...>::value,bool>::type=0> // FASTOR_INLINE TensorViewExpr,2> operator()(Int num, fseq _s) { // static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); // return TensorViewExpr,2>(*this,seq(num),seq(_s)); // } // // Selecting a row from a 2D tensor returns a TensorMap // template::value && // internal::fseq_range_detector, // get_value<2,Rest...>::value>::type>::value == get_value<2,Rest...>::value,bool>::type=0> // FASTOR_INLINE TensorMap::value> operator()(Int num, fseq _s) { // static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); // constexpr FASTOR_INDEX N = get_value<2,Rest...>::value; // return TensorMap(&_data[num*N]); // } //----------------------------------------------------------------------------------------------------------// template::value,bool>::type=0> FASTOR_INLINE TensorRandomViewExpr,Tensor,1> operator()(const Tensor &_it) { static_assert(dimension_t::value==1,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorRandomViewExpr,Tensor,1>(*this,_it); } template::value,bool>::type=0> FASTOR_INLINE TensorRandomViewExpr,Tensor,sizeof...(Rest)> operator()(const Tensor &_it) { static_assert(dimension_t::value==sizeof...(IterSizes),"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorRandomViewExpr,Tensor,sizeof...(Rest)>(*this,_it); } template::value && std::is_integral::value,bool>::type=0> FASTOR_INLINE TensorRandomViewExpr,Tensor,2> operator()(const Tensor &_it0, const Tensor &_it1) { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); Tensor tmp_it; constexpr int NCols = get_value<2,Rest...>::value; for (FASTOR_INDEX i = 0; i,Tensor,2>(*this,tmp_it); } template::value && std::is_integral::value,bool>::type=0> FASTOR_INLINE TensorRandomViewExpr,Tensor,2> operator()(const Tensor &_it0, Int1 num) { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); Tensor tmp_it; constexpr int NCols = get_value<2,Rest...>::value; for (FASTOR_INDEX i = 0; i,Tensor,2>(*this,tmp_it); } template::value && std::is_integral::value,bool>::type=0> FASTOR_INLINE TensorRandomViewExpr,Tensor,2> operator()(Int1 num, const Tensor &_it0) { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); Tensor tmp_it; constexpr int NCols = get_value<2,Rest...>::value; for (FASTOR_INDEX i = 0; i,Tensor,2>(*this,tmp_it); } template::value,bool>::type=0> FASTOR_INLINE TensorRandomViewExpr,Tensor,get_value<2,Rest...>::value>::type::Size>,2> operator()(const Tensor &_it0, fseq) { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); constexpr int NCols = get_value<2,Rest...>::value; using _seq = typename to_positive,NCols>::type; constexpr int ColSize = _seq::Size; Tensor tmp_it; for (FASTOR_INDEX i = 0; i,Tensor,get_value<2,Rest...>::value>::type::Size>,2> (*this,tmp_it); } template::value,bool>::type=0> FASTOR_INLINE TensorRandomViewExpr,Tensor,get_value<1,Rest...>::value>::type::Size,N>,2> operator()(fseq, const Tensor &_it0) { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); constexpr int NRows = get_value<1,Rest...>::value; constexpr int NCols = get_value<2,Rest...>::value; using _seq = typename to_positive,NRows>::type; constexpr int RowSize = _seq::Size; Tensor tmp_it; for (FASTOR_INDEX i = 0; i,Tensor,get_value<1,Rest...>::value>::type::Size,N>,2> (*this,tmp_it); } //----------------------------------------------------------------------------------------------------------// // Filter views FASTOR_INLINE TensorFilterViewExpr,Tensor,sizeof...(Rest)> operator()(const Tensor &_fl) { return TensorFilterViewExpr,Tensor,sizeof...(Rest)>(*this,_fl); } FASTOR_INLINE TensorFilterViewExpr,TensorMap,sizeof...(Rest)> operator()(const TensorMap &_fl) { return TensorFilterViewExpr,TensorMap,sizeof...(Rest)>(*this,_fl); } //----------------------------------------------------------------------------------------------------------// FASTOR_INLINE TensorConstViewExpr,1> operator()(seq _s) const { static_assert(dimension_t::value==1,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorConstViewExpr,1>(*this,_s); } FASTOR_INLINE TensorConstViewExpr,2> operator()(seq _s0, seq _s1) const { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorConstViewExpr,2>(*this,_s0,_s1); } template::value,bool>::type=0> FASTOR_INLINE TensorConstViewExpr,2> operator()(seq _s0, Int num) const { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorConstViewExpr,2>(*this,_s0,seq(num)); } template::value,bool>::type=0> FASTOR_INLINE TensorConstViewExpr,2> operator()(Int num, seq _s1) const { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorConstViewExpr,2>(*this,seq(num),_s1); } template && !is_fixed_sequence_pack_v,bool> = false> FASTOR_INLINE TensorConstViewExpr,sizeof...(Seq)> operator()(Seq ... _seqs) const { static_assert(dimension_t::value==sizeof...(Seq),"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorConstViewExpr,sizeof...(Seq)>(*this, {_seqs...}); } template,bool> = false> FASTOR_INLINE TensorConstFixedViewExprnD,Fseq...> operator()(Fseq... ) const { static_assert(dimension_t::value==sizeof...(Fseq),"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorConstFixedViewExprnD,Fseq...>(*this); } template FASTOR_INLINE TensorConstFixedViewExpr1D, typename to_positive,pack_prod::value>::type,1> operator()(fseq) const { static_assert(dimension_t::value==1,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorConstFixedViewExpr1D, typename to_positive,pack_prod::value>::type,1>(*this); } template FASTOR_INLINE TensorConstFixedViewExpr2D, typename to_positive,get_value<1,Rest...>::value>::type, typename to_positive,get_value<2,Rest...>::value>::type,2> operator()(fseq, fseq) const { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorConstFixedViewExpr2D, typename to_positive,get_value<1,Rest...>::value>::type, typename to_positive,get_value<2,Rest...>::value>::type,2>(*this); } template::value,bool>::type=0> FASTOR_INLINE TensorConstViewExpr,2> operator()(fseq _s, Int num) const { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorConstViewExpr,2>(*this,seq(_s),seq(num)); } template::value,bool>::type=0> FASTOR_INLINE TensorConstViewExpr,2> operator()(Int num, fseq _s) const { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorConstViewExpr,2>(*this,seq(num),seq(_s)); } template::value,bool>::type=0> FASTOR_INLINE TensorConstRandomViewExpr,Tensor,1> operator()(const Tensor &_it) const { static_assert(dimension_t::value==1,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorConstRandomViewExpr,Tensor,1>(*this,_it); } template::value,bool>::type=0> FASTOR_INLINE TensorConstRandomViewExpr,Tensor,sizeof...(Rest)> operator()(const Tensor &_it) const { static_assert(dimension_t::value==sizeof...(IterSizes),"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); return TensorConstRandomViewExpr,Tensor,sizeof...(Rest)>(*this,_it); } template::value && std::is_integral::value,bool>::type=0> FASTOR_INLINE TensorConstRandomViewExpr,Tensor,2> operator()(const Tensor &_it0, const Tensor &_it1) const { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); Tensor tmp_it; constexpr int NCols = get_value<2,Rest...>::value; for (FASTOR_INDEX i = 0; i,Tensor,2>(*this,tmp_it); } template::value && std::is_integral::value,bool>::type=0> FASTOR_INLINE TensorConstRandomViewExpr,Tensor,2> operator()(const Tensor &_it0, Int1 num) const { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); Tensor tmp_it; constexpr int NCols = get_value<2,Rest...>::value; for (FASTOR_INDEX i = 0; i,Tensor,2>(*this,tmp_it); } template::value && std::is_integral::value,bool>::type=0> FASTOR_INLINE TensorConstRandomViewExpr,Tensor,2> operator()(Int1 num, const Tensor &_it0) const { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); Tensor tmp_it; constexpr int NCols = get_value<2,Rest...>::value; for (FASTOR_INDEX i = 0; i,Tensor,2>(*this,tmp_it); } template::value,bool>::type=0> FASTOR_INLINE TensorConstRandomViewExpr,Tensor,get_value<2,Rest...>::value>::type::Size>,2> operator()(const Tensor &_it0, fseq) const { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); constexpr int NCols = get_value<2,Rest...>::value; using _seq = typename to_positive,NCols>::type; constexpr int ColSize = _seq::Size; Tensor tmp_it; for (FASTOR_INDEX i = 0; i,Tensor,get_value<2,Rest...>::value>::type::Size>,2> (*this,tmp_it); } template::value,bool>::type=0> FASTOR_INLINE TensorConstRandomViewExpr,Tensor,get_value<1,Rest...>::value>::type::Size,N>,2> operator()(fseq, const Tensor &_it0) const { static_assert(dimension_t::value==2,"INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS"); constexpr int NRows = get_value<1,Rest...>::value; constexpr int NCols = get_value<2,Rest...>::value; using _seq = typename to_positive,NRows>::type; constexpr int RowSize = _seq::Size; Tensor tmp_it; for (FASTOR_INDEX i = 0; i,Tensor,get_value<1,Rest...>::value>::type::Size,N>,2> (*this,tmp_it); } //----------------------------------------------------------------------------------------------------------// //----------------------------------------------------------------------------------------------------------// #endif // BLOCK_INDEXING_H