From 92c319247fae9d8be3f3291d6fa64266224ef61c Mon Sep 17 00:00:00 2001 From: Jaron Kent-Dobias Date: Tue, 2 Apr 2024 17:24:14 +0200 Subject: Added tensor support. --- tensor.hpp | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 tensor.hpp (limited to 'tensor.hpp') diff --git a/tensor.hpp b/tensor.hpp new file mode 100644 index 0000000..58c2434 --- /dev/null +++ b/tensor.hpp @@ -0,0 +1,108 @@ +#pragma once + +#include +#include + +#include + +#include "types.hpp" +#include "factorial.hpp" + +using Vector = Eigen::Matrix; + +using Matrix = Eigen::Matrix; + +template +using Tensor = Eigen::Tensor; + +template +using constTensor = Eigen::Tensor; + +template +Tensor

initializeJHelper(unsigned N, unsigned M, std::index_sequence) { + std::array Ns; + std::fill_n(Ns.begin(), p, N); + Ns[p-1] = M; + return Tensor

(std::get(Ns)...); +} + +template +Tensor

initializeJ(unsigned N, unsigned M) { + return initializeJHelper

(N, M, std::make_index_sequence

()); +} + +template +void setJHelper(Tensor

& J, const std::array& ind, Real val, std::index_sequence) { + J(std::get(ind)...) = val; +} + +template +void setJ(Tensor

& J, std::array ind, Real val) { + setJHelper

(J, ind, val, std::make_index_sequence

()); +} + +template +Real getJHelper(const Tensor

& J, const std::array& ind, std::index_sequence) { + return J(std::get(ind)...); +} + +template +Real getJ(const Tensor

& J, const std::array& ind) { + return getJHelper

(J, ind, std::make_index_sequence

()); +} + +template +void iterateOverHelper(Tensor

& J, + std::function&, std::array)>& f, + unsigned l, std::array is) { + if (l == 0) { + f(J, is); + } else { + for (unsigned i = 0; i < J.dimension(p - l); i++) { + std::array js = is; + js[p - l] = i; + iterateOverHelper

(J, f, l - 1, js); + } + } +} + +template +void iterateOver(Tensor

& J, std::function&, std::array)>& f) { + std::array is; + iterateOverHelper

(J, f, p, is); +} + +template +Tensor

generateCouplings(unsigned N, unsigned M, Distribution d, Generator& r) { + Tensor

J = initializeJ

(N, M); + + std::function&, std::array)> setRandom = + [&d, &r] (Tensor

& JJ, std::array ind) { + setJ

(JJ, ind, d(r)); + }; + + iterateOver

(J, setRandom); + + return J; +} + +template +Tensor

generateRealPSpinCouplings(unsigned N, unsigned M, Generator& r) { + Real σp = sqrt(factorial(p-1) / ((Real)2 * pow(N, p - 1))); + + return generateCouplings

(N, M, std::normal_distribution(0, σp), r); +} + +Tensor<3> contractDown(const Tensor<3>& J, const Vector& z) { + return J; +} + +const std::array, 1> ip00 = {Eigen::IndexPair(0, 0)}; +const std::array, 1> ip20 = {Eigen::IndexPair(2, 0)}; + +template +Tensor<3> contractDown(const Tensor& J, const Vector& z) { + Tensor<1> zT = Eigen::TensorMap>(z.data(), {z.size()}); + Tensor Jz = J.contract(zT, ip00); + return contractDown(Jz, z); +} -- cgit v1.2.3-70-g09d2