mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Added support for fixed sized tensors.
Improved support for tensor expressions.
This commit is contained in:
212
unsupported/Eigen/CXX11/src/Tensor/TensorDimensions.h
Normal file
212
unsupported/Eigen/CXX11/src/Tensor/TensorDimensions.h
Normal file
@@ -0,0 +1,212 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef EIGEN_CXX11_TENSOR_TENSOR_DIMENSIONS_H
|
||||
#define EIGEN_CXX11_TENSOR_TENSOR_DIMENSIONS_H
|
||||
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
/** \internal
|
||||
*
|
||||
* \class TensorDimensions
|
||||
* \ingroup CXX11_Tensor_Module
|
||||
*
|
||||
* \brief Set of classes used to encode and store the dimensions of a Tensor.
|
||||
*
|
||||
* The Sizes class encodes as part of the type the number of dimensions and the
|
||||
* sizes corresponding to each dimension. It uses no storage space since it is
|
||||
* entirely known at compile time.
|
||||
* The DSizes class is its dynamic sibling: the number of dimensions is known
|
||||
* at compile time but the sizes are set during execution.
|
||||
*
|
||||
* \sa Tensor
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// Boiler plate code
|
||||
namespace internal {
|
||||
|
||||
template<std::size_t n, typename Dimension> struct dget {
|
||||
static const std::size_t value = internal::get<n, typename Dimension::Base>::value;
|
||||
};
|
||||
|
||||
|
||||
template<typename Index, std::size_t NumIndices, std::size_t n, bool RowMajor>
|
||||
struct fixed_size_tensor_index_linearization_helper
|
||||
{
|
||||
template <typename Dimensions>
|
||||
static inline Index run(array<Index, NumIndices> const& indices,
|
||||
const Dimensions& dimensions)
|
||||
{
|
||||
return array_get<RowMajor ? n : (NumIndices - n - 1)>(indices) +
|
||||
dget<RowMajor ? n : (NumIndices - n - 1), Dimensions>::value *
|
||||
fixed_size_tensor_index_linearization_helper<Index, NumIndices, n - 1, RowMajor>::run(indices, dimensions);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Index, std::size_t NumIndices, bool RowMajor>
|
||||
struct fixed_size_tensor_index_linearization_helper<Index, NumIndices, 0, RowMajor>
|
||||
{
|
||||
template <typename Dimensions>
|
||||
static inline Index run(array<Index, NumIndices> const& indices,
|
||||
const Dimensions&)
|
||||
{
|
||||
return array_get<RowMajor ? 0 : NumIndices - 1>(indices);
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
|
||||
// Fixed size
|
||||
#ifndef EIGEN_EMULATE_CXX11_META_H
|
||||
template <typename std::size_t... Indices>
|
||||
struct Sizes : internal::numeric_list<std::size_t, Indices...> {
|
||||
typedef internal::numeric_list<std::size_t, Indices...> Base;
|
||||
static const std::size_t total_size = internal::arg_prod(Indices...);
|
||||
|
||||
static std::size_t TotalSize() {
|
||||
return internal::arg_prod(Indices...);
|
||||
}
|
||||
|
||||
Sizes() { }
|
||||
template <typename DenseIndex>
|
||||
explicit Sizes(const array<DenseIndex, Base::count>&/* indices*/) {
|
||||
// todo: add assertion
|
||||
}
|
||||
#ifdef EIGEN_HAS_VARIADIC_TEMPLATES
|
||||
explicit Sizes(std::initializer_list<std::size_t>/* l*/) {
|
||||
// todo: add assertion
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T> Sizes& operator = (const T&/* other*/) {
|
||||
// add assertion failure if the size of other is different
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename DenseIndex>
|
||||
size_t IndexOfColMajor(const array<DenseIndex, Base::count>& indices) const {
|
||||
return internal::fixed_size_tensor_index_linearization_helper<DenseIndex, Base::count, Base::count - 1, false>::run(indices, *static_cast<const Base*>(this));
|
||||
}
|
||||
template <typename DenseIndex>
|
||||
size_t IndexOfRowMajor(const array<DenseIndex, Base::count>& indices) const {
|
||||
return internal::fixed_size_tensor_index_linearization_helper<DenseIndex, Base::count, Base::count - 1, true>::run(indices, *static_cast<const Base*>(this));
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template <std::size_t n>
|
||||
struct non_zero_size {
|
||||
typedef internal::type2val<std::size_t, n> type;
|
||||
};
|
||||
template <>
|
||||
struct non_zero_size<0> {
|
||||
typedef internal::null_type type;
|
||||
};
|
||||
|
||||
template <std::size_t V1=0, std::size_t V2=0, std::size_t V3=0, std::size_t V4=0, std::size_t V5=0> struct Sizes {
|
||||
typedef typename internal::make_type_list<typename non_zero_size<V1>::type, typename non_zero_size<V2>::type, typename non_zero_size<V3>::type, typename non_zero_size<V4>::type, typename non_zero_size<V5>::type >::type Base;
|
||||
static const size_t count = Base::count;
|
||||
static const std::size_t total_size = internal::arg_prod<Base>::value;
|
||||
|
||||
static const size_t TotalSize() {
|
||||
return internal::arg_prod<Base>::value;
|
||||
}
|
||||
|
||||
Sizes() { }
|
||||
template <typename DenseIndex>
|
||||
explicit Sizes(const array<DenseIndex, Base::count>& indices) {
|
||||
// todo: add assertion
|
||||
}
|
||||
#ifdef EIGEN_HAS_VARIADIC_TEMPLATES
|
||||
explicit Sizes(std::initializer_list<std::size_t> l) {
|
||||
// todo: add assertion
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T> Sizes& operator = (const T& other) {
|
||||
// to do: check the size of other
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename DenseIndex>
|
||||
size_t IndexOfColMajor(const array<DenseIndex, Base::count>& indices) const {
|
||||
return internal::fixed_size_tensor_index_linearization_helper<DenseIndex, Base::count, Base::count - 1, false>::run(indices, *this);
|
||||
}
|
||||
template <typename DenseIndex>
|
||||
size_t IndexOfRowMajor(const array<DenseIndex, Base::count>& indices) const {
|
||||
return internal::fixed_size_tensor_index_linearization_helper<DenseIndex, Base::count, Base::count - 1, true>::run(indices, *this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// Boiler plate
|
||||
namespace internal {
|
||||
template<typename Index, std::size_t NumIndices, std::size_t n, bool RowMajor>
|
||||
struct tensor_index_linearization_helper
|
||||
{
|
||||
static inline Index run(array<Index, NumIndices> const& indices, array<Index, NumIndices> const& dimensions)
|
||||
{
|
||||
return array_get<RowMajor ? n : (NumIndices - n - 1)>(indices) +
|
||||
array_get<RowMajor ? n : (NumIndices - n - 1)>(dimensions) *
|
||||
tensor_index_linearization_helper<Index, NumIndices, n - 1, RowMajor>::run(indices, dimensions);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Index, std::size_t NumIndices, bool RowMajor>
|
||||
struct tensor_index_linearization_helper<Index, NumIndices, 0, RowMajor>
|
||||
{
|
||||
static inline Index run(array<Index, NumIndices> const& indices, array<Index, NumIndices> const&)
|
||||
{
|
||||
return array_get<RowMajor ? 0 : NumIndices - 1>(indices);
|
||||
}
|
||||
};
|
||||
} // end namespace internal
|
||||
|
||||
|
||||
|
||||
// Dynamic size
|
||||
template <typename DenseIndex, std::size_t NumDims>
|
||||
struct DSizes : array<DenseIndex, NumDims> {
|
||||
typedef array<DenseIndex, NumDims> Base;
|
||||
|
||||
size_t TotalSize() const {
|
||||
return internal::array_prod(*static_cast<const Base*>(this));
|
||||
}
|
||||
|
||||
DSizes() { }
|
||||
#ifdef EIGEN_HAS_VARIADIC_TEMPLATES
|
||||
// explicit DSizes(std::initializer_list<DenseIndex> l) : Base(l) { }
|
||||
#endif
|
||||
explicit DSizes(const array<DenseIndex, NumDims>& a) : Base(a) { }
|
||||
|
||||
DSizes& operator = (const array<DenseIndex, NumDims>& other) {
|
||||
*static_cast<Base*>(this) = other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// A constexpr would be so much better here
|
||||
size_t IndexOfColMajor(const array<DenseIndex, NumDims>& indices) const {
|
||||
return internal::tensor_index_linearization_helper<DenseIndex, NumDims, NumDims - 1, false>::run(indices, *static_cast<const Base*>(this));
|
||||
}
|
||||
size_t IndexOfRowMajor(const array<DenseIndex, NumDims>& indices) const {
|
||||
return internal::tensor_index_linearization_helper<DenseIndex, NumDims, NumDims - 1, true>::run(indices, *static_cast<const Base*>(this));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_CXX11_TENSOR_TENSOR_DIMENSIONS_H
|
||||
Reference in New Issue
Block a user