Skip to content

Commit

Permalink
remove difference between strides and slices.
Browse files Browse the repository at this point in the history
  • Loading branch information
bassoy committed Dec 11, 2022
1 parent a43ac47 commit 87ee607
Show file tree
Hide file tree
Showing 6 changed files with 256 additions and 369 deletions.
131 changes: 28 additions & 103 deletions include/boost/numeric/ublas/tensor/span.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,6 @@

#include "concepts.hpp"

namespace boost::numeric::ublas::tag{

struct sliced {};
struct strided {};

} // namespace boost::numeric::ublas::tag


namespace boost::numeric::ublas {

Expand All @@ -43,21 +36,17 @@ namespace boost::numeric::ublas {
*/


//template<class unsigned_type>
//class span;

//using offsets = std::vector<std::ptrdiff_t>;

template<class span_tag, class unsigned_type>
class span;


static constexpr inline std::size_t max = std::numeric_limits<std::size_t>::max();

template<>
class span<tag::strided, std::size_t>
template<integral unsigned_type>
class span
{
public:
using span_tag = tag::strided;
using value_type = std::size_t;
using value_type = unsigned_type;

static constexpr inline value_type max = std::numeric_limits<value_type>::max();


// covers the complete range of one dimension
// e.g. a(:)
Expand Down Expand Up @@ -92,6 +81,13 @@ class span<tag::strided, std::size_t>
}
}

// covers a linear range of one dimension
// e.g. a(1:n)
span(value_type f, value_type l)
: span(f,1,l)
{
}

// covers only one index of one dimension
// e.g. a(1) or a(end)
span(value_type n)
Expand Down Expand Up @@ -142,105 +138,34 @@ class span<tag::strided, std::size_t>
value_type first_, last_ , step_, size_;
};

using strided_span = span<tag::strided, std::size_t>;

} // namespace


/////////////

namespace boost::numeric::ublas {

template<>
class span<tag::sliced, std::size_t> :
private span<tag::strided, std::size_t>
{
using super_type = span<tag::strided,std::size_t>;
public:
using span_tag = tag::sliced;
using value_type = typename super_type::value_type;
constexpr explicit span()
: super_type()
{
}

span(value_type f, value_type l)
: super_type(f, value_type(1), l )
{
}

span(value_type n)
: super_type(n)
{
}

span(span const& other)
: super_type(other)
{
}

inline span& operator=(const span &other)
{
super_type::operator=(other);
return *this;
}

~span() = default;

inline value_type operator[] (std::size_t idx) const
{
return super_type::operator [](idx);
}

inline auto first() const {return super_type::first(); }
inline auto last () const {return super_type::last (); }
inline auto step () const {return super_type::step (); }
inline auto size () const {return super_type::size (); }

inline span operator()(const span &rhs) const
{
auto const& lhs = *this;
return span( rhs.first_ + lhs.first_, rhs.last_ + lhs.first_ );
}
};

using sliced_span = span<tag::sliced, std::size_t>;


template<integral unsigned_type_left, integral unsigned_type_right>
inline auto ran(unsigned_type_left f, unsigned_type_right l)
{
return sliced_span(f,l);
}

template<integral unsigned_type_left, integral unsigned_type_middle, integral unsigned_type_right>
inline auto ran(unsigned_type_left f, unsigned_type_middle s, unsigned_type_right l)
{
return strided_span(f,s,l);
}
using sspan = span<std::size_t>;

} // namespace


template <class span_tag, class unsigned_type>
std::ostream& operator<< (std::ostream& out, boost::numeric::ublas::span<span_tag,unsigned_type> const& s)
template <boost::numeric::ublas::integral unsigned_type>
std::ostream& operator<< (std::ostream& out, boost::numeric::ublas::span<unsigned_type> const& s)
{
return out << "[" << s.first() << ":" << s.step() << ":" << s.last() << "]" << std::endl;
}

template<class span_tag_lhs, class span_tag_rhs, class unsigned_type>
template<
boost::numeric::ublas::integral unsigned_type_lhs,
boost::numeric::ublas::integral unsigned_type_rhs>
inline bool operator==(
boost::numeric::ublas::span<span_tag_lhs,unsigned_type> const& lhs,
boost::numeric::ublas::span<span_tag_rhs,unsigned_type> const& rhs)
boost::numeric::ublas::span<unsigned_type_lhs> const& lhs,
boost::numeric::ublas::span<unsigned_type_rhs> const& rhs)
{
return lhs.first() == rhs.first() && lhs.last() == rhs.last() && lhs.step() == rhs.step();
}


template<class span_tag_lhs, class span_tag_rhs, class unsigned_type>
template<
boost::numeric::ublas::integral unsigned_type_lhs,
boost::numeric::ublas::integral unsigned_type_rhs>
inline bool operator!=(
boost::numeric::ublas::span<span_tag_lhs,unsigned_type> const& lhs,
boost::numeric::ublas::span<span_tag_rhs,unsigned_type> const& rhs)
boost::numeric::ublas::span<unsigned_type_lhs> const& lhs,
boost::numeric::ublas::span<unsigned_type_rhs> const& rhs)
{
return lhs.first() != rhs.first() || lhs.last() != rhs.last() || lhs.step() != rhs.step();
}
Expand Down
64 changes: 30 additions & 34 deletions include/boost/numeric/ublas/tensor/subtensor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,9 @@ namespace boost::numeric::ublas {

/** @brief A view of a dense tensor of values of type \c T.
*
* @tparam T type of the objects stored in the tensor (like int, double, complex,...)
* @tparam F
* @tparam A The type of the storage array of the tensor. Default is \c unbounded_array<T>. \c <bounded_array<T> and \c std::vector<T> can also be used
* @tparam T tensor type
*/
template<class S, class T>
template<class T>
class subtensor;


Expand All @@ -48,22 +46,20 @@ class subtensor;
* @tparam A The type of the storage array of the tensor. Default is \c unbounded_array<T>. \c <bounded_array<T> and \c std::vector<T> can also be used
*/
template<class T, class F>
class subtensor <tag::sliced, tensor_dynamic<T,F>>
class subtensor <tensor_dynamic<T,F>>
: public detail::tensor_expression<
subtensor<tag::sliced,tensor_dynamic<T,F>> ,
subtensor<tag::sliced,tensor_dynamic<T,F>> >
subtensor<tensor_dynamic<T,F>> ,
subtensor<tensor_dynamic<T,F>> >
{

static_assert( std::is_same<F,layout::first_order>::value || std::is_same<F,layout::last_order >::value,
"boost::numeric::tensor template class only supports first- or last-order storage formats.");

using tensor_type = tensor_dynamic<T,F>;
using self_type = subtensor<tag::sliced, tensor_type>;
using self_type = subtensor<tensor_type>;
public:

using domain_tag = tag::sliced;

using span_type = span<domain_tag,std::size_t>;
using span_type = sspan;

template<class derived_type>
using tensor_expression_type = detail::tensor_expression<self_type,derived_type>;
Expand Down Expand Up @@ -116,23 +112,23 @@ class subtensor <tag::sliced, tensor_dynamic<T,F>>
*/
BOOST_UBLAS_INLINE
subtensor (tensor_type& t)
: super_type ()
, spans_ ()
, extents_ (t.extents())
, strides_ (t.strides())
, span_strides_ (t.strides())
, data_ (t.data())
: super_type ()
, spans_ ()
, extents_ (t.extents())
, strides_ (t.strides())
, span_strides_ (t.strides())
, data_ (t.data())
{
}

template<typename ... span_types>
subtensor(tensor_type& t, span_types&& ... spans)
: super_type ()
, spans_ (detail::generate_span_vector<span_type>(t.extents(),std::forward<span_types>(spans)...))
, extents_ (detail::to_extents(spans_))
, strides_ (ublas::to_strides(extents_,layout_type{}))
, span_strides_ (detail::to_span_strides(t.strides(),spans_))
, data_ {t.data() + detail::to_offset(t.strides(), spans_)}
subtensor(tensor_type& t, span_types&& ... spans)
: super_type ()
, spans_ (detail::generate_vector<span_type>(t.extents(),std::forward<span_types>(spans)...))
, extents_ (detail::to_extents(spans_))
, strides_ (ublas::to_strides(extents_,layout_type{}))
, span_strides_ (detail::to_span_strides(t.strides(),spans_))
, data_ {t.data() + detail::to_offset(t.strides(), spans_)}
{
// if( m == nullptr)
// throw std::length_error("Error in tensor_view<T>::tensor_view : multi_array_type is nullptr.");
Expand All @@ -145,16 +141,16 @@ class subtensor <tag::sliced, tensor_dynamic<T,F>>
*
* @note is similar to a handle to a tensor
*/
explicit
subtensor (tensor_type const& t)
: super_type ()
, spans_ ()
, extents_ (t.extents())
, strides_ (t.strides())
, span_strides_ (t.strides())
, data_ (t.data())
{
}
explicit
subtensor (tensor_type const& t)
: super_type ()
, spans_ ()
, extents_ (t.extents())
, strides_ (t.strides())
, span_strides_ (t.strides())
, data_ (t.data())
{
}



Expand Down
Loading

0 comments on commit 87ee607

Please sign in to comment.