1#ifndef TENSOR_INTERFACE_ARRAY_IMPL_H_
2#define TENSOR_INTERFACE_ARRAY_IMPL_H_
14template <
typename T,
T... Nums>
15void print(seq::iseq<T, Nums...> seq)
17 std::array<T,
sizeof...(Nums)> s = {Nums...};
19 for(
auto x : s) { std::cout << x <<
" "; }
20 std::cout << std::endl;
25template <
typename Index, Index oldVal, Index newVal,
typename S>
26using seq_replace = seq::insert<seq::index_of<oldVal, S>, newVal, seq::remove<oldVal, S>>;
30 template <
typename element_t, std::size_t N,
size_t... Is>
31 static nda::internal::tuple_of_n<element_t, N>
as_tuple(std::array<element_t, N>
const& arr, std::index_sequence<Is...>)
33 return std::make_tuple(arr[Is]...);
36 template <
typename element_t, std::
size_t N>
37 static nda::internal::tuple_of_n<element_t, N>
as_tuple(std::array<element_t, N>
const& arr)
39 return as_tuple(arr, std::make_index_sequence<N>{});
43 template <
typename Scalar, std::
size_t Rank>
44 using TType = nda::dense_array<Scalar, Rank>;
45 template <
typename Scalar, std::
size_t Rank>
46 using cTType =
const nda::dense_array<Scalar, Rank>;
48 template <
typename Scalar, std::
size_t Rank>
49 using MapTType = nda::dense_array_ref<Scalar, Rank>;
50 template <
typename Scalar, std::
size_t Rank>
51 using cMapTType = nda::const_dense_array_ref<Scalar, Rank>;
57 template <
typename Scalar, std::
size_t Rank>
63 template <
typename Scalar, std::
size_t Rank>
71 template <
typename Scalar, std::
size_t Rank>
81 template <
typename Scalar, std::
size_t Rank>
87 template <
typename Scalar, std::
size_t Rank>
94 template <
typename Scalar, std::
size_t Rank>
97 T.for_each_value([](Scalar& d) { d = 0.; });
100 template <
typename Scalar, std::
size_t Rank>
103 T.for_each_value([](Scalar& d) { d = random::threadSafeRandUniform<Scalar, Scalar>(-1., 1.); });
106 template <
typename Scalar, std::
size_t Rank>
109 T.for_each_value([val](Scalar& d) { d = val; });
112 template <
typename Scalar,
int Rank>
118 template <
typename Scalar,
int Rank>
121 if constexpr(Rank == 0) {
129 template <
typename Scalar,
int Rank>
135 template <
typename Scalar,
int Rank>
142 template <
typename Scalar, std::
size_t Rank>
145 std::array<Indextype, Rank> out;
146 auto tmp = nda::internal::tuple_to_array<nda::dim<>>(T.shape().dims());
147 for(std::size_t d = 0; d < Rank; d++) { out[d] = tmp[d].extent(); }
152 template <
typename Scalar, std::
size_t Rank>
155 std::array<Indextype, 2 * Rank> tmp_dims;
156 std::array<Indextype, Rank> out_dims;
157 auto dim1 = dimensions<Scalar, Rank>(T1);
158 auto dim2 = dimensions<Scalar, Rank>(T2);
159 for(std::size_t i = 0; i < Rank; i++) {
160 tmp_dims[i] = dim2[i];
161 tmp_dims[i + Rank] = dim1[i];
162 out_dims[i] = dim1[i] * dim2[i];
166 tmp = contract<Scalar, Rank, Rank>(T2, T1);
170 if constexpr(Rank == 1) {
171 res = reshape<Scalar, 2 * Rank, Rank>(shuffle<Scalar, 2 * Rank>(tmp, seq::make<Indextype, 2>{}), out_dims);
173 seq::zip<seq::make<Indextype, Rank>, seq::make<Indextype, Rank, Rank>> shuffle_dims{};
174 res = reshape<Scalar, 2 * Rank, Rank>(shuffle<Scalar, 2 * Rank>(tmp, shuffle_dims), out_dims);
223 template <
typename Scalar, std::size_t Rank,
Indextype... Is,
typename Expr1,
typename Expr2>
224 static void addScale_helper(
const Expr1& src, Expr2& dst,
const Scalar& scale, seq::iseq<Indextype, Is...> S)
226 nda::ein_reduce(nda::ein<Is...>(dst) += nda::ein<>(scale) * nda::ein<Is...>(src));
229 template <
typename Scalar, std::
size_t Rank,
typename Expr1,
typename Expr2>
230 static void addScale(
const Expr1& src, Expr2& dst,
const Scalar& scale)
232 return addScale_helper<Scalar, Rank>(src, dst, scale, seq::make<Indextype, Rank>());
239 seq::iseq<Indextype, Is1...> S1,
240 seq::iseq<Indextype, Is2...> S2,
241 seq::iseq<Indextype, Ist...> St)
243 return nda::make_ein_sum<Scalar, Ist...>(nda::ein<Is1...>(T1) * nda::ein<Is2...>(T2));
246 template <
typename Scalar, std::size_t Rank1, std::size_t Rank2,
Indextype... Is>
249 static_assert(
sizeof...(Is) % 2 == 0);
250 constexpr Indextype Ncon =
sizeof...(Is) / 2;
251 static_assert(Ncon <= 4,
"Contractions of more than 4 legs is currently not implemented for ArrayTensorLib");
252 static_assert(Rank1 + Rank2 >= Ncon);
257 using seq1 = seq::make<Indextype, Rank1i>;
258 using seq2 = seq::make<Indextype, Rank2i, Rank1i>;
259 using seqC = seq::iseq<
Indextype, Is...>;
261 if constexpr(Ncon == 0) {
262 return contract_helper<Scalar, Rank1, Rank2>(T1, T2, seq1{}, seq2{}, seq::concat<seq1, seq2>{});
266 using rem_seq1 = seq::remove<seq::at<0, seqC>, seq1>;
267 using rem_seq2 = seq::remove<seq::at<1, seqC> + Rank1i, seq2>;
268 if constexpr(Ncon == 1) {
269 return contract_helper<Scalar, Rank1, Rank2>(T1, T2, mod_seq1{}, mod_seq2{}, seq::concat<rem_seq1, rem_seq2>{});
273 using rem_seq11 = seq::remove<seq::at<2, seqC>, rem_seq1>;
274 using rem_seq22 = seq::remove<seq::at<3, seqC> + Rank1i, rem_seq2>;
275 if constexpr(Ncon == 2) {
276 return contract_helper<Scalar, Rank1, Rank2>(T1, T2, mod_seq11{}, mod_seq22{}, seq::concat<rem_seq11, rem_seq22>{});
280 using rem_seq111 = seq::remove<seq::at<4, seqC>, rem_seq11>;
281 using rem_seq222 = seq::remove<seq::at<5, seqC> + Rank1i, rem_seq22>;
282 if constexpr(Ncon == 3) {
283 return contract_helper<Scalar, Rank1, Rank2>(T1, T2, mod_seq111{}, mod_seq222{}, seq::concat<rem_seq111, rem_seq222>{});
287 using rem_seq1111 = seq::remove<seq::at<6, seqC>, rem_seq111>;
288 using rem_seq2222 = seq::remove<seq::at<7, seqC> + Rank1i, rem_seq222>;
289 if constexpr(Ncon == 4) {
290 return contract_helper<Scalar, Rank1, Rank2>(
291 T1, T2, mod_seq1111{}, mod_seq2222{}, seq::concat<rem_seq1111, rem_seq2222>{});
303 return nda::transpose<p...>(T);
306 template <
typename Scalar, std::size_t Rank,
Indextype... p>
309 static_assert(Rank ==
sizeof...(p));
310 std::array<Indextype, Rank> perm = {p...};
311 std::array<Indextype, Rank> dims;
312 for(std::size_t r = 0; r < Rank; r++) { dims[r] = T.shape().dim(perm[r]).extent(); }
314 nda::dense_shape<Rank> shp(
as_tuple(dims));
315 return make_copy(nda::transpose<p...>(T), shp);
318 template <
typename Scalar, std::size_t Rank,
Indextype... p>
321 static_assert(Rank ==
sizeof...(p));
322 std::array<Indextype, Rank> perm = {p...};
323 std::array<Indextype, Rank> dims;
324 for(std::size_t r = 0; r < Rank; r++) { dims[r] = T.shape().dim(perm[r]).extent(); }
326 nda::dense_shape<Rank> shp(
as_tuple(dims));
327 return make_copy(nda::transpose<p...>(T), shp);
330 template <
typename Scalar, std::size_t Rank,
Indextype... p>
333 static_assert(Rank ==
sizeof...(p));
334 std::array<Indextype, Rank> perm = {p...};
335 std::array<Indextype, Rank> dims;
336 for(std::size_t r = 0; r < Rank; r++) { dims[r] = T.shape().dim(perm[r]).extent(); }
338 nda::dense_shape<Rank> shp(
as_tuple(dims));
339 return make_copy(nda::transpose<p...>(T), shp);
342 template <
typename Scalar, std::size_t Rank,
Indextype... p>
345 static_assert(Rank ==
sizeof...(p));
346 return nda::transpose<p...>(T);
349 template <
typename Scalar, std::
size_t Rank1, std::
size_t Rank2>
353 return construct<Scalar, Rank2>(map);
357 template <
typename Scalar, std::
size_t Rank1, std::
size_t Rank2>
360 std::array<nda::interval<>, Rank1> slices;
361 for(std::size_t r = 0; r < Rank1; r++) { slices[r] = nda::interval<>(offsets[r], extents[r]); }
365 template <
typename Scalar, std::
size_t Rank1, std::
size_t Rank2>
367 const std::array<Indextype, Rank2>& offsets,
368 const std::array<Indextype, Rank2>& extents,
372 std::array<nda::interval<>, Rank1> slices;
373 for(std::size_t r = 0; r < Rank1; r++) { slices[r] = nda::interval<>(offsets[r], extents[r]); }
374 nda::dense_shape<Rank1> new_s(
as_tuple(slices));
381 template <
typename Scalar, std::
size_t Rank1, std::
size_t Rank2>
388 template <
typename Scalar,
int Rank>
391 std::stringstream ss;
@ T
Definition: functions.hpp:35
XpedWorld & getUniverse()
Definition: Mpi.hpp:49
void print(seq::iseq< T, Nums... > seq)
Definition: TensorInterface_Array_impl.hpp:15
seq::insert< seq::index_of< oldVal, S >, newVal, seq::remove< oldVal, S > > seq_replace
Definition: TensorInterface_Array_impl.hpp:26
int Indextype
Definition: PlainInterface_Cyclops_impl.cpp:10
Definition: TensorInterface_Array_impl.hpp:29
static std::array< Indextype, Rank > dimensions(const TType< Scalar, Rank > &T)
Definition: TensorInterface_Array_impl.hpp:143
static auto shuffle_view(const Expr &T)
Definition: TensorInterface_Array_impl.hpp:300
nda::dense_array< Scalar, Rank > TType
Definition: TensorInterface_Array_impl.hpp:44
static Scalar * get_raw_data(TType< Scalar, Rank > &T)
Definition: TensorInterface_Array_impl.hpp:136
const nda::dense_array< Scalar, Rank > cTType
Definition: TensorInterface_Array_impl.hpp:46
static void addScale_helper(const Expr1 &src, Expr2 &dst, const Scalar &scale, seq::iseq< Indextype, Is... > S)
Definition: TensorInterface_Array_impl.hpp:224
static cTType< Scalar, Rank > construct(const cMapTType< Scalar, Rank > &map)
Definition: TensorInterface_Array_impl.hpp:72
static auto contract_helper(const TType< Scalar, Rank1 > &T1, const TType< Scalar, Rank2 > &T2, seq::iseq< Indextype, Is1... > S1, seq::iseq< Indextype, Is2... > S2, seq::iseq< Indextype, Ist... > St)
Definition: TensorInterface_Array_impl.hpp:237
static TType< Scalar, Rank > construct(const MapTType< Scalar, Rank > &map)
Definition: TensorInterface_Array_impl.hpp:64
static nda::internal::tuple_of_n< element_t, N > as_tuple(std::array< element_t, N > const &arr, std::index_sequence< Is... >)
Definition: TensorInterface_Array_impl.hpp:31
static void setZero(TType< Scalar, Rank > &T)
Definition: TensorInterface_Array_impl.hpp:95
static TType< Scalar, Rank > shuffle(const TType< Scalar, Rank > &T)
Definition: TensorInterface_Array_impl.hpp:307
nda::index_t Indextype
Definition: TensorInterface_Array_impl.hpp:54
static TType< Scalar, Rank > shuffle(const TType< Scalar, Rank > &T, seq::iseq< Indextype, p... > s)
Definition: TensorInterface_Array_impl.hpp:331
static auto reshape(TType< Scalar, Rank1 > &T, const std::array< Indextype, Rank2 > &dims)
Definition: TensorInterface_Array_impl.hpp:382
static nda::internal::tuple_of_n< element_t, N > as_tuple(std::array< element_t, N > const &arr)
Definition: TensorInterface_Array_impl.hpp:37
static auto slice(TType< Scalar, Rank1 > &T, const std::array< Indextype, Rank2 > &offsets, const std::array< Indextype, Rank2 > &extents)
Definition: TensorInterface_Array_impl.hpp:358
static void setConstant(TType< Scalar, Rank > &T, const Scalar &val)
Definition: TensorInterface_Array_impl.hpp:107
nda::dense_array_ref< Scalar, Rank > MapTType
Definition: TensorInterface_Array_impl.hpp:49
static MapTType< Scalar, Rank > Map(Scalar *data, const std::array< Indextype, Rank > &dims)
Definition: TensorInterface_Array_impl.hpp:88
static std::string print(const TType< Scalar, Rank > &T)
Definition: TensorInterface_Array_impl.hpp:389
static Scalar getVal(const TType< Scalar, Rank > &T, const std::array< Indextype, Rank > &index)
Definition: TensorInterface_Array_impl.hpp:119
static TType< Scalar, Rank > construct(const std::array< Indextype, Rank > &dims, mpi::XpedWorld &world=mpi::getUniverse())
Definition: TensorInterface_Array_impl.hpp:58
static auto shuffle_view(const cMapTType< Scalar, Rank > &T, seq::iseq< Indextype, p... > s)
Definition: TensorInterface_Array_impl.hpp:343
static void setVal(TType< Scalar, Rank > &T, const std::array< Indextype, Rank > &index, const Scalar &val)
Definition: TensorInterface_Array_impl.hpp:113
static void addScale(const Expr1 &src, Expr2 &dst, const Scalar &scale)
Definition: TensorInterface_Array_impl.hpp:230
static const Scalar * get_raw_data(const TType< Scalar, Rank > &T)
Definition: TensorInterface_Array_impl.hpp:130
static void setRandom(TType< Scalar, Rank > &T)
Definition: TensorInterface_Array_impl.hpp:101
static TType< Scalar, Rank > shuffle(const cMapTType< Scalar, Rank > &T)
Definition: TensorInterface_Array_impl.hpp:319
static TType< Scalar, Rank > tensorProd(const TType< Scalar, Rank > &T1, const TType< Scalar, Rank > &T2)
Definition: TensorInterface_Array_impl.hpp:153
static TType< Scalar, Rank1+Rank2 - sizeof...(Is)> contract(const TType< Scalar, Rank1 > &T1, const TType< Scalar, Rank2 > &T2)
Definition: TensorInterface_Array_impl.hpp:247
static cMapTType< Scalar, Rank > cMap(const Scalar *data, const std::array< Indextype, Rank > &dims)
Definition: TensorInterface_Array_impl.hpp:82
static TType< Scalar, Rank2 > reshape(const TType< Scalar, Rank1 > &T, const std::array< Indextype, Rank2 > &dims)
Definition: TensorInterface_Array_impl.hpp:350
nda::const_dense_array_ref< Scalar, Rank > cMapTType
Definition: TensorInterface_Array_impl.hpp:51
static void setSubTensor(TType< Scalar, Rank1 > &T, const std::array< Indextype, Rank2 > &offsets, const std::array< Indextype, Rank2 > &extents, const TType< Scalar, Rank1 > &S)
Definition: TensorInterface_Array_impl.hpp:366