Tatooine
contracted_dynamic_tensor.h
Go to the documentation of this file.
1#ifndef TATOOINE_EINSTEIN_NOTATION_CONTRACTED_DYNAMIC_TENSOR_H
2#define TATOOINE_EINSTEIN_NOTATION_CONTRACTED_DYNAMIC_TENSOR_H
3//==============================================================================
5//==============================================================================
7//==============================================================================
8template <typename... IndexedTensors>
10 using value_type =
11 common_type<typename IndexedTensors::tensor_type::value_type...>;
12 using indices_per_tensor = type_list<typename IndexedTensors::indices...>;
13 template <std::size_t I>
19 //----------------------------------------------------------------------------
20 static auto constexpr rank() { return free_indices::size; }
21 //----------------------------------------------------------------------------
22 template <typename E, std::size_t ...Is>
23 auto constexpr dimension(std::index_sequence<Is...>/*seq*/) const {
24 std::size_t s = 0;
25 (
26 [&](auto const& indexed_tensor) {
27 if constexpr (IndexedTensors::template contains<E>()) {
28 s = indexed_tensor.template dimension<E>();
29 }
30 }(at<Is>()),
31 ...);
32 return s;
33 }
34 //----------------------------------------------------------------------------
35 template <typename E>
36 auto constexpr dimension() const {
37 return dimension<E>(std::make_index_sequence<sizeof...(IndexedTensors)>{});
38 }
39
40 private:
41 std::tuple<IndexedTensors...> m_tensors;
42
43 public:
44 contracted_dynamic_tensor(IndexedTensors... tensors) : m_tensors{tensors...} {}
45
46 template <std::size_t I>
47 auto at() const {
48 return std::get<I>(m_tensors);
49 }
50 template <std::size_t I>
51 auto at() {
52 return std::get<I>(m_tensors);
53 }
54 constexpr auto num_tensors() { return sizeof...(IndexedTensors); }
55
56 template <std::size_t... ContractedIndexSequence,
57 std::size_t... ContractedTensorsSequence>
58 requires free_indices::empty auto to_scalar(
59 std::index_sequence<ContractedIndexSequence...> /*seq*/,
60 std::index_sequence<ContractedTensorsSequence...> /*seq*/) const {
61 using map_t = std::map<std::size_t, std::size_t>;
64
65 auto const contracted_indices_map = map_t{map_t::value_type{
66 contracted_indices::template at<ContractedIndexSequence>::get(),
67 ContractedIndexSequence,
68 }...};
69 auto const tensor_index_maps = std::tuple{IndexedTensors::index_map()...};
70 auto index_arrays =
71 std::tuple{make_array<std::size_t, IndexedTensors::rank()>()...};
72 value_type acc = 0;
73
75 [&](auto const... contracted_indices) {
76 // setup indices of single tensors for contracted indices
77 {
78 auto const contracted_index_array =
79 std::array{contracted_indices...};
80 (
81 [&] {
82 auto& index_array =
83 std::get<ContractedTensorsSequence>(index_arrays);
84 auto const& tensor_index_map =
85 std::get<ContractedTensorsSequence>(tensor_index_maps);
86 auto index_arr_it = begin(index_array);
87 auto tensor_index_map_it = begin(tensor_index_map);
88
89 for (; tensor_index_map_it != end(tensor_index_map);
90 ++tensor_index_map_it, ++index_arr_it) {
91 if (contracted_indices_map.contains(*tensor_index_map_it)) {
92 *index_arr_it =
93 contracted_index_array[contracted_indices_map.at(
94 *tensor_index_map_it)];
95 }
96 }
97 }(),
98 ...);
99 }
100
101 acc += (at<ContractedTensorsSequence>().tensor()(
102 std::get<ContractedTensorsSequence>(index_arrays)) *
103 ...);
104 },
105 contracted_dynamic_tensor::template dimension<
106 typename contracted_indices::template at<
107 ContractedIndexSequence>>()...);
108 return acc;
109 }
110 //----------------------------------------------------------------------------
111 operator value_type() const {
112 if constexpr (free_indices::empty) {
113 return to_scalar(std::make_index_sequence<contracted_indices::dimension>{},
114 std::make_index_sequence<sizeof...(IndexedTensors)>{});
115 } else {
116 return value_type(0) / value_type(0);
117 }
118 }
119};
120//==============================================================================
121} // namespace tatooine::einstein_notation
122//==============================================================================
123#endif
typename type_list_at_impl< TypeList, I >::type type_list_at
Access to the Ith element of TypeList.
Definition: type_list.h:56
Definition: added_contracted_dynamic_tensor.h:4
static auto constexpr s
Definition: index.h:23
typename contracted_indices_aux< indexed_tensors_to_index_list< Indices... > >::type contracted_indices
Definition: type_traits.h:90
typename free_indices_aux< indexed_tensors_to_index_list< Indices... > >::type free_indices
Definition: type_traits.h:59
typename common_type_impl< Ts... >::type common_type
Definition: common_type.h:23
auto begin(Range &&range)
Definition: iterator_facade.h:318
auto end(Range &&range)
Definition: iterator_facade.h:322
constexpr auto for_loop(Iteration &&iteration, execution_policy::sequential_t, Ranges(&&... ranges)[2]) -> void
Use this function for creating a sequential nested loop.
Definition: for_loop.h:336
Definition: contracted_dynamic_tensor.h:9
type_list_at< indices_per_tensor, I > indices_of_tensor
Definition: contracted_dynamic_tensor.h:14
common_type< typename IndexedTensors::tensor_type::value_type... > value_type
Definition: contracted_dynamic_tensor.h:11
static auto constexpr rank()
Definition: contracted_dynamic_tensor.h:20
::empty auto to_scalar(std::index_sequence< ContractedIndexSequence... >, std::index_sequence< ContractedTensorsSequence... >) const
Definition: contracted_dynamic_tensor.h:58
contracted_dynamic_tensor(IndexedTensors... tensors)
Definition: contracted_dynamic_tensor.h:44
auto constexpr dimension() const
Definition: contracted_dynamic_tensor.h:36
auto at()
Definition: contracted_dynamic_tensor.h:51
auto at() const
Definition: contracted_dynamic_tensor.h:47
std::tuple< IndexedTensors... > m_tensors
Definition: contracted_dynamic_tensor.h:41
auto constexpr dimension(std::index_sequence< Is... >) const
Definition: contracted_dynamic_tensor.h:23
tatooine::einstein_notation::contracted_indices< IndexedTensors... > contracted_indices
Definition: contracted_dynamic_tensor.h:18
tatooine::einstein_notation::free_indices< IndexedTensors... > free_indices
Definition: contracted_dynamic_tensor.h:16
constexpr auto num_tensors()
Definition: contracted_dynamic_tensor.h:54
An empty struct that holds types.
Definition: type_list.h:248