From bcc5c327016a3d188a9bdcb0069cc63b0bb8163f Mon Sep 17 00:00:00 2001 From: Jaron Kent-Dobias Date: Tue, 9 Nov 2021 15:41:56 +0100 Subject: Moved some repeated code into the pSpinModel class. --- p-spin.hpp | 109 ++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 64 insertions(+), 45 deletions(-) (limited to 'p-spin.hpp') diff --git a/p-spin.hpp b/p-spin.hpp index 7a49bca..544abf1 100644 --- a/p-spin.hpp +++ b/p-spin.hpp @@ -12,73 +12,92 @@ Vector normalize(const Eigen::MatrixBase& z) return z * sqrt((Real)z.size() / (typename Derived::Scalar)(z.transpose() * z)); } -template -std::tuple, Tensor> hamGradTensorHelper(const Vector& z, const Tensor& J) { - Tensor J3(z.size(), z.size(), z.size());; - J3.setZero(); - Matrix Jz = Eigen::Map>(J.data(), z.size(), z.size()); - - return {Jz, J3}; -} +template +class pSpinModel { +private: + std::tuple, Tensor> hamGradTensorHelper(const Vector& z, const Tensor& J) const { + Tensor J3(z.size(), z.size(), z.size());; + J3.setZero(); + Matrix Jz = Eigen::Map>(J.data(), z.size(), z.size()); -template -std::tuple, Tensor> hamGradTensorHelper(const Vector& z, const Tensor& J) { - Tensor J3 = contractDown(J, z); - Tensor zT = Eigen::TensorMap>(z.data(), {z.size()}); - Tensor J3zT = J3.contract(zT, ip00); - Matrix Jz = Eigen::Map>(J3zT.data(), z.size(), z.size()); + return {Jz, J3}; + } - return {Jz, J3}; -} + template + std::tuple, Tensor> hamGradTensorHelper(const Vector& z, const Tensor& J) const { + Tensor J3 = contractDown(J, z); + Tensor zT = Eigen::TensorMap>(z.data(), {z.size()}); + Tensor J3zT = J3.contract(zT, ip00); + Matrix Jz = Eigen::Map>(J3zT.data(), z.size(), z.size()); -template -std::tuple, Matrix, Tensor> hamGradHessHelper(const Vector& z, const Tensor& J, const Tensor& ...Js) { - auto [Jz, J3] = hamGradTensorHelper(z, J); - - Vector Jzz = Jz * z; - Scalar Jzzz = Jzz.transpose() * z; - - Real pBang = factorial(p); - - Tensor dddH = ((p - 2) * (p - 1) * p / pBang) * J3; - Matrix ddH = ((p - 1) * p / pBang) * Jz; - Vector dH = (p / pBang) * Jzz; - Scalar H = Jzzz / pBang; - - if constexpr (sizeof...(Js) > 0) { - auto [Hs, dHs, ddHs, dddHs] = hamGradHessHelper(z, Js...); - H += Hs; - dH += dHs; - ddH += ddHs; - dddH += dddHs; + return {Jz, J3}; } - return {H, dH, ddH, dddH}; -} + template + std::tuple, Matrix, Tensor> hamGradHessHelper(const Vector& z, const Tensor& J, const Tensor& ...Js) const { + auto [Jz, J3] = hamGradTensorHelper(z, J); + + Vector Jzz = Jz * z; + Scalar Jzzz = Jzz.transpose() * z; + + Real pBang = factorial(p); + + Tensor dddH = ((p - 2) * (p - 1) * p / pBang) * J3; + Matrix ddH = ((p - 1) * p / pBang) * Jz; + Vector dH = (p / pBang) * Jzz; + Scalar H = Jzzz / pBang; + + if constexpr (sizeof...(Js) > 0) { + auto [Hs, dHs, ddHs, dddHs] = hamGradHessHelper(z, Js...); + H += Hs; + dH += dHs; + ddH += ddHs; + dddH += dddHs; + } + + return {H, dH, ddH, dddH}; + } -template -class pSpinModel { public: std::tuple...> Js; + pSpinModel() {} + + pSpinModel(const std::tuple...>& Js) : Js(Js) {} + + template + pSpinModel(unsigned N, Generator& r, T... μs) { + Js = std::make_tuple(μs * generateRealPSpinCouplings(N, r)...); + } + unsigned dimension() const { return std::get<0>(Js).dimension(0); } template pSpinModel cast() const { - pSpinModel M; - M.Js = std::apply( + return std::apply( [] (const Tensor& ...Ks) -> std::tuple...> { return std::make_tuple(Ks.template cast()...); }, Js - ); + ); + } + + template + pSpinModel& operator*=(T x) { + std::tuple...> newJs = std::apply( + [x] (const Tensor& ...Ks) -> std::tuple...> { + return std::make_tuple((x * Ks)...); + }, Js + ); + + Js = newJs; - return M; + return *this; } std::tuple, Matrix, Tensor> hamGradHess(const Vector& z) const { - return std::apply([&z](const Tensor& ...Ks) -> std::tuple, Matrix, Tensor> { return hamGradHessHelper(z, Ks...); }, Js); + return std::apply([&z, this](const Tensor& ...Ks) -> std::tuple, Matrix, Tensor> { return hamGradHessHelper(z, Ks...); }, Js); } Scalar getHamiltonian(const Vector& z) const { -- cgit v1.2.3-54-g00ecf