From 7bf6e952b53699977f5091a78f0f9f48f7b359c5 Mon Sep 17 00:00:00 2001 From: Jaron Kent-Dobias Date: Tue, 9 Nov 2021 10:13:59 +0100 Subject: Generalized code to easily allow mixed p-spins. --- dynamics.hpp | 50 ++++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 22 deletions(-) (limited to 'dynamics.hpp') diff --git a/dynamics.hpp b/dynamics.hpp index 7d04b1a..36b2dfa 100644 --- a/dynamics.hpp +++ b/dynamics.hpp @@ -6,22 +6,28 @@ #include "p-spin.hpp" -template -Vector findMinimum(const Tensor& J, const Vector& z0, Real ε) { +template +Vector findMinimum(const pSpinModel& M, const Vector& z0, Real ε) { Vector z = z0; Real λ = 10; - auto [H, dH, ddH] = hamGradHess(J, z); + Real H; + Vector dH; + Matrix ddH; + std::tie(H, dH, ddH, std::ignore) = M.hamGradHess(z); Vector g = dH - z.dot(dH) * z / (Real)z.size(); - Matrix M = ddH - (dH * z.transpose() + z.dot(dH) * Matrix::Identity(z.size(), z.size()) + (ddH * z) * z.transpose()) / (Real)z.size() + 2.0 * z * z.transpose(); + Matrix m = ddH - (dH * z.transpose() + z.dot(dH) * Matrix::Identity(z.size(), z.size()) + (ddH * z) * z.transpose()) / (Real)z.size() + 2.0 * z * z.transpose(); while (g.norm() / z.size() > ε && λ < 1e8) { - Vector dz = (M + λ * (Matrix)abs(M.diagonal().array()).matrix().asDiagonal()).partialPivLu().solve(g); + Vector dz = (m + λ * (Matrix)abs(m.diagonal().array()).matrix().asDiagonal()).partialPivLu().solve(g); dz -= z.dot(dz) * z / (Real)z.size(); Vector zNew = normalize(z - dz); - auto [HNew, dHNew, ddHNew] = hamGradHess(J, zNew); + Real HNew; + Vector dHNew; + Matrix ddHNew; + std::tie(HNew, dHNew, ddHNew, std::ignore) = M.hamGradHess(zNew); if (HNew * 1.0001 <= H) { z = zNew; @@ -30,7 +36,7 @@ Vector findMinimum(const Tensor& J, const Vector& z0, Real ddH = ddHNew; g = dH - z.dot(dH) * z / (Real)z.size(); - M = ddH - (dH * z.transpose() + z.dot(dH) * Matrix::Identity(z.size(), z.size()) + (ddH * z) * z.transpose()) / (Real)z.size() + 2.0 * z * z.transpose(); + m = ddH - (dH * z.transpose() + z.dot(dH) * Matrix::Identity(z.size(), z.size()) + (ddH * z) * z.transpose()) / (Real)z.size() + 2.0 * z * z.transpose(); λ /= 2; } else { @@ -41,28 +47,28 @@ Vector findMinimum(const Tensor& J, const Vector& z0, Real return z; } -template -Vector findSaddle(const Tensor& J, const Vector& z0, Real ε) { +template +Vector findSaddle(const pSpinModel& M, const Vector& z0, Real ε) { Vector z = z0; Vector dH; Matrix ddH; - std::tie(std::ignore, dH, ddH) = hamGradHess(J, z); + std::tie(std::ignore, dH, ddH, std::ignore) = M.hamGradHess(z); Scalar zz = z.transpose() * z; Vector g = dH - (z.transpose() * dH) * z / (Real)z.size() + z * (zz - (Real)z.size()); - Matrix M = ddH - (dH * z.transpose() + (z.transpose() * dH) * Matrix::Identity(z.size(), z.size()) + (ddH * z) * z.transpose()) / (Real)z.size() + Matrix::Identity(z.size(), z.size()) * (zz - (Real)z.size()) + 2.0 * z * z.transpose(); + Matrix m = ddH - (dH * z.transpose() + (z.transpose() * dH) * Matrix::Identity(z.size(), z.size()) + (ddH * z) * z.transpose()) / (Real)z.size() + Matrix::Identity(z.size(), z.size()) * (zz - (Real)z.size()) + 2.0 * z * z.transpose(); while (g.norm() / z.size() > ε) { - Vector dz = M.partialPivLu().solve(g); + Vector dz = m.partialPivLu().solve(g); dz -= z.conjugate().dot(dz) / z.squaredNorm() * z.conjugate(); z = normalize(z - dz); - std::tie(std::ignore, dH, ddH) = hamGradHess(J, z); + std::tie(std::ignore, dH, ddH, std::ignore) = M.hamGradHess(z); zz = z.transpose() * z; g = dH - (z.transpose() * dH) * z / (Real)z.size() + z * (zz - (Real)z.size()); - M = ddH - (dH * z.transpose() + (z.transpose() * dH) * Matrix::Identity(z.size(), z.size()) + (ddH * z) * z.transpose()) / (Real)z.size() + Matrix::Identity(z.size(), z.size()) * (zz - (Real)z.size()) + 2.0 * z * z.transpose(); + m = ddH - (dH * z.transpose() + (z.transpose() * dH) * Matrix::Identity(z.size(), z.size()) + (ddH * z) * z.transpose()) / (Real)z.size() + Matrix::Identity(z.size(), z.size()) * (zz - (Real)z.size()) + 2.0 * z * z.transpose(); } return z; @@ -79,16 +85,16 @@ Vector randomVector(unsigned N, Distribution d, Generator& r) { return z; } -template -Vector randomMinimum(const Tensor& J, Distribution d, Generator& r, Real ε) { +template +Vector randomMinimum(const pSpinModel& M, Distribution d, Generator& r, Real ε) { Vector zSaddle; bool foundSaddle = false; while (!foundSaddle) { - Vector z0 = normalize(randomVector(J.dimension(0), d, r.engine())); + Vector z0 = normalize(randomVector(M.dimension(), d, r.engine())); try { - zSaddle = findMinimum(J, z0, ε); + zSaddle = findMinimum(M, z0, ε); foundSaddle = true; } catch (std::exception& e) {} } @@ -96,16 +102,16 @@ Vector randomMinimum(const Tensor& J, Distribution d, Generator& return zSaddle; } -template -Vector randomSaddle(const Tensor& J, Distribution d, Generator& r, Real ε) { +template +Vector randomSaddle(const pSpinModel& M, Distribution d, Generator& r, Real ε) { Vector zSaddle; bool foundSaddle = false; while (!foundSaddle) { - Vector z0 = normalize(randomVector(J.dimension(0), d, r.engine())); + Vector z0 = normalize(randomVector(M.dimension(), d, r.engine())); try { - zSaddle = findSaddle(J, z0, ε); + zSaddle = findSaddle(M, z0, ε); foundSaddle = true; } catch (std::exception& e) {} } -- cgit v1.2.3-54-g00ecf