Skip to content

Instantly share code, notes, and snippets.

@amitsingh19975
Last active May 31, 2019 16:30
Show Gist options
  • Save amitsingh19975/7509505b6979cecba4c65a62d95f7449 to your computer and use it in GitHub Desktop.
Save amitsingh19975/7509505b6979cecba4c65a62d95f7449 to your computer and use it in GitHub Desktop.
#include <boost/numeric/ublas/functional.hpp>
#include <boost/numeric/ublas/tensor/extents.hpp>
#include <boost/numeric/ublas/tensor/extents_helper.hpp>
#include <boost/numeric/ublas/tensor/strides.hpp>
#include <complex>
#include <iostream>
#include <type_traits>
namespace boost::numeric::ublas {
using first_order = column_major;
using last_order = row_major;
} // namespace boost::numeric::ublas
namespace boost::numeric::ublas::detail {
template <class E, class __layout> struct basic_extent_layout;
template <class S>
struct basic_extent_layout<basic_extents_impl<0, S>, last_order>
: basic_extents_impl<0, S> {
static_assert(is_basic_shape_v<S>, "Not a basic shape");
using impl = basic_extents_impl<0, S>;
using index_type = ptrdiff_t;
constexpr auto at(int k) const noexcept { return impl::at(k); }
constexpr auto rank() const noexcept { return impl::Rank; }
constexpr auto product(int k) const noexcept { return impl::product(k); }
constexpr auto stride(int k) const noexcept {
return impl::next::product(k + 1);
}
constexpr basic_extent_layout() noexcept = default;
constexpr basic_extent_layout(basic_extent_layout const &other) noexcept =
default;
constexpr basic_extent_layout &
operator=(basic_extent_layout const &other) noexcept = default;
template <typename... IndexType>
explicit constexpr basic_extent_layout(ptrdiff_t extent,
IndexType... DynamicExtents) noexcept
: impl(extent, DynamicExtents...) {}
template <typename Iterator>
constexpr basic_extent_layout(Iterator begin, Iterator end,
iterator_tag) noexcept
: impl(begin, end, iterator_tag{}) {}
private:
template <class E>
static constexpr auto access(E const &, index_type sum) noexcept {
return sum;
}
template <class E, class... IndexType>
static constexpr auto access(E const &e, index_type sum, index_type i_el,
IndexType const &... idxs) noexcept {
return basic_extent_layout::access((typename E::next const &)e,
sum * e.N + i_el, idxs...);
}
public:
constexpr auto operator()() const noexcept { return 0; }
template <class... IndexType>
constexpr auto operator()(IndexType const &... idxs) const noexcept {
return basic_extent_layout::access((typename impl::next const &)*this,
idxs...);
}
};
template <class S>
struct basic_extent_layout<basic_extents_impl<0, S>, first_order>
: basic_extents_impl<0, S> {
static_assert(is_basic_shape_v<S>, "Not a basic shape");
using impl = basic_extents_impl<0, S>;
using index_type = ptrdiff_t;
constexpr auto at(int k) const noexcept { return impl::at(k); }
constexpr auto rank() const noexcept { return impl::Rank; }
constexpr auto product(int k) const noexcept { return impl::product(k); }
constexpr basic_extent_layout() noexcept = default;
constexpr basic_extent_layout(basic_extent_layout const &other) noexcept =
default;
constexpr basic_extent_layout &
operator=(basic_extent_layout const &other) noexcept = default;
template <typename... IndexType>
explicit constexpr basic_extent_layout(ptrdiff_t extent,
IndexType... DynamicExtents) noexcept
: impl(extent, DynamicExtents...) {}
template <typename Iterator>
constexpr basic_extent_layout(Iterator begin, Iterator end,
iterator_tag) noexcept
: impl(begin, end, iterator_tag{}) {}
private:
template <class E>
static constexpr index_type stride(E const &e, index_type k) noexcept {
return k ? (e.N * stride((typename E::next const &)e, k - 1)) : index_type{1};
}
template <class E> static constexpr auto access(E const &) noexcept {
return 0;
}
template <class E, class... IndexType>
static constexpr auto access(E const &e, index_type i_el,
IndexType const &... idxs) noexcept {
return i_el + e.N * basic_extent_layout::access((typename E::next const &)e,
idxs...);
}
public:
constexpr auto stride(index_type k) const noexcept {
return stride((impl const &)*this, k);
}
constexpr auto operator()() const noexcept { return 0; }
template <class... IndexType>
constexpr auto operator()(IndexType const &... idxs) const noexcept {
return basic_extent_layout::access((impl const &)*this, idxs...);
}
};
template<ptrdiff_t R, ptrdiff_t... E>
using extents = boost::numeric::ublas::detail::basic_extents_impl<0,boost::numeric::ublas::detail::make_basic_shape_t<R,E...>>;
int main(int argc, char const *argv[]) {
using e = extents<5,2,3,tensor::dynamic_extent,tensor::dynamic_extent,1>;
using first_order_lay = tensor::detail::basic_extent_layout<e,tensor::first_order>;
using last_order_lay = tensor::detail::basic_extent_layout<e,tensor::last_order>;
first_order_lay f(3,4);
last_order_lay l(3,5);
for(auto i = 0; i < f.size(); i++){
cout<<f.stride(i)<<'\n'; //1 2 6 18 72
}
for(auto i = 0; i < f.size(); i++){
cout<<l.stride(i)<<'\n'; //45 15 5 1 1
}
cout<<f(1,3,4)<<'\n';
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment