Tatooine
contracted_static_tensor.h
Go to the documentation of this file.
1#ifndef TATOOINE_EINSTEIN_NOTATION_CONTRACTED_STATIC_TENSOR_H
2#define TATOOINE_EINSTEIN_NOTATION_CONTRACTED_STATIC_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>
23 static auto constexpr size() {
24 auto s = std::size_t{};
25 (
26 [&] {
27 if constexpr (IndexedTensors::template contains<E>()) {
28 s = IndexedTensors::template size<E>();
29 }
30 }(),
31 ...);
32 return s;
33 }
34
35 private:
36 std::tuple<IndexedTensors...> m_tensors;
37
38 public:
39 contracted_static_tensor(IndexedTensors... tensors) : m_tensors{tensors...} {}
40
41 template <std::size_t I>
42 auto at() const {
43 return std::get<I>(m_tensors);
44 }
45 template <std::size_t I>
46 auto at() {
47 return std::get<I>(m_tensors);
48 }
49 constexpr auto num_tensors() { return sizeof...(IndexedTensors); }
50 //----------------------------------------------------------------------------
51 template <std::size_t... ContractedIndexSequence,
52 std::size_t... ContractedTensorsSequence>
53 requires free_indices::empty
55 std::index_sequence<ContractedIndexSequence...> /*seq*/,
56 std::index_sequence<ContractedTensorsSequence...> /*seq*/) const {
57 using map_t = std::map<std::size_t, std::size_t>;
59 contracted_static_tensor<IndexedTensors...>;
60 using contracted_indices =
62
63 auto const contracted_indices_map = map_t{map_t::value_type{
64 contracted_indices::template at<ContractedIndexSequence>::get(),
65 ContractedIndexSequence,
66 }...};
67 auto const tensor_index_maps = std::tuple{IndexedTensors::index_map()...};
68 auto index_arrays =
69 std::tuple{std::array<std::size_t, IndexedTensors::rank()>{}...};
70 auto acc = value_type{};
71
73 [&](auto const... contracted_indices) {
74 // setup indices of single tensors for contracted indices
75 {
76 auto const contracted_index_array =
77 std::array{contracted_indices...};
78 (
79 [&] {
80 auto& index_array =
81 std::get<ContractedTensorsSequence>(index_arrays);
82 auto const& tensor_index_map =
83 std::get<ContractedTensorsSequence>(tensor_index_maps);
84 auto index_arr_it = begin(index_array);
85 auto tensor_index_map_it = begin(tensor_index_map);
86
87 for (; tensor_index_map_it != end(tensor_index_map);
88 ++tensor_index_map_it, ++index_arr_it) {
89 if (contracted_indices_map.contains(*tensor_index_map_it)) {
90 *index_arr_it =
91 contracted_index_array[contracted_indices_map.at(
92 *tensor_index_map_it)];
93 }
94 }
95 }(),
96 ...);
97 }
98
99 acc += (at<ContractedTensorsSequence>().tensor()(std::get<ContractedTensorsSequence>(index_arrays)) * ...);
100 },
101 size<typename contracted_indices::template at<
102 ContractedIndexSequence>>()...);
103 return acc;
104 }
105 //----------------------------------------------------------------------------
106 operator value_type() const {
107 if constexpr (free_indices::empty) {
108 return to_scalar(std::make_index_sequence<contracted_indices::size>{},
109 std::make_index_sequence<sizeof...(IndexedTensors)>{});
110 } else {
111 return value_type(0) / value_type(0);
112 }
113 }
114};
115//==============================================================================
116} // namespace tatooine::einstein_notation
117//==============================================================================
118#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_static_tensor.h:9
auto at() const
Definition: contracted_static_tensor.h:42
type_list_at< indices_per_tensor, I > indices_of_tensor
Definition: contracted_static_tensor.h:14
tatooine::einstein_notation::free_indices< IndexedTensors... > free_indices
Definition: contracted_static_tensor.h:16
auto at()
Definition: contracted_static_tensor.h:46
static auto constexpr size()
Definition: contracted_static_tensor.h:23
common_type< typename IndexedTensors::tensor_type::value_type... > value_type
Definition: contracted_static_tensor.h:11
contracted_static_tensor(IndexedTensors... tensors)
Definition: contracted_static_tensor.h:39
constexpr auto num_tensors()
Definition: contracted_static_tensor.h:49
std::tuple< IndexedTensors... > m_tensors
Definition: contracted_static_tensor.h:36
::empty auto to_scalar(std::index_sequence< ContractedIndexSequence... >, std::index_sequence< ContractedTensorsSequence... >) const
Definition: contracted_static_tensor.h:54
static auto constexpr rank()
Definition: contracted_static_tensor.h:20
tatooine::einstein_notation::contracted_indices< IndexedTensors... > contracted_indices
Definition: contracted_static_tensor.h:18
An empty struct that holds types.
Definition: type_list.h:248