From 897df7986e9cafcfa0c5f60a424d5a452dceca07 Mon Sep 17 00:00:00 2001 From: Jaron Kent-Dobias Date: Mon, 8 Nov 2021 17:37:53 +0100 Subject: Progress towards minimizer for real models. --- dynamics.hpp | 84 +++++++++++++++++++++++++++++++++++++++++++++--------------- langevin.cpp | 14 +++++++++- 2 files changed, 76 insertions(+), 22 deletions(-) diff --git a/dynamics.hpp b/dynamics.hpp index 0597f35..639803b 100644 --- a/dynamics.hpp +++ b/dynamics.hpp @@ -44,8 +44,45 @@ std::tuple> gradientDescent(const Tensor& J, con return {W, z}; } +template +Vector findMinimum(const Tensor& J, const Vector& z0, Real ε) { + Vector z = z0; + Real λ = 10; + + auto [H, dH, ddH] = hamGradHess(J, 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(); + + while (g.norm() / z.size() > ε && λ < 1e8) { + Vector dz = (M + λ * Matrix::Identity(z.size(), z.size())).partialPivLu().solve(g); + dz -= z.dot(dz) * z / (Real)z.size(); + Vector zNew = normalize(z - dz); + + auto [HNew, dHNew, ddHNew] = hamGradHess(J, zNew); + + if (HNew <= H * 1.01) { + z = zNew; + H = HNew; + dH = dHNew; + 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(); + + λ /= 1.001; + } else { + λ *= 1.5; + } + + std::cout << "error : " << H << " " << g.norm() / z.size() << " " << λ << std::endl; + } + + return z; +} + template -Vector findSaddle(const Tensor& J, const Vector& z0, Real ε, Real δW = 2, Real γ0 = 1, Real δγ = 2) { +Vector findSaddle(const Tensor& J, const Vector& z0, Real ε) { Vector z = z0; Vector dH; @@ -53,33 +90,21 @@ Vector findSaddle(const Tensor& J, const Vector& z0, std::tie(std::ignore, dH, ddH) = hamGradHess(J, z); Scalar zz = z.transpose() * z; - Vector ż = zDot(z, dH) + z * (zz - (Real)z.size()); - Matrix dż = dzDot(z, dH) + Matrix::Identity(z.size(), z.size()) * (zz - (Real)z.size()) + 2.0 * z * z.transpose(); - Matrix dżc = dzDotConjugate(z, dH, ddH); - - Vector b(2 * z.size()); - Matrix M(2 * z.size(), 2 * z.size()); + 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(); - b << ż.conjugate(), ż; - M << dż.conjugate(), dżc, dżc.conjugate(), dż; - - while (ż.norm() > ε) { - Vector dz = M.partialPivLu().solve(b).tail(z.size()); + while (g.norm() / z.size() > ε) { + Vector dz = M.partialPivLu().solve(g); dz -= z.conjugate().dot(dz) / z.squaredNorm() * z.conjugate(); z = normalize(z - dz); - std::cout << "error : " << z.transpose() * z << " "<< ż.norm() << " " << dz.norm() << std::endl; - getchar(); - std::tie(std::ignore, dH, ddH) = hamGradHess(J, z); - zz = z.transpose() * z; - ż = zDot(z, dH) + z * (zz - (Real)z.size()); - dż = dzDot(z, dH) + Matrix::Identity(z.size(), z.size()) * (zz - (Real)z.size()) + 2.0 * z * z.transpose(); - dżc = dzDotConjugate(z, dH, ddH); + std::cout << "error : " << g.norm() / z.size() << std::endl; - b << ż.conjugate(), ż; - M << dż.conjugate(), dżc, dżc.conjugate(), dż; + 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(); } return z; @@ -120,6 +145,23 @@ std::tuple> metropolis(const Tensor& J, const Ve return {E, z}; } +template +Vector randomMinimum(const Tensor& J, Distribution d, Generator& r, Real ε) { + Vector zSaddle; + bool foundSaddle = false; + + while (!foundSaddle) { + Vector z0 = normalize(randomVector(J.dimension(0), d, r.engine())); + + try { + zSaddle = findMinimum(J, z0, ε); + foundSaddle = true; + } catch (std::exception& e) {} + } + + return zSaddle; +} + template Vector randomSaddle(const Tensor& J, Distribution d, Generator& r, Real ε) { Vector zSaddle; diff --git a/langevin.cpp b/langevin.cpp index adb5212..a775774 100644 --- a/langevin.cpp +++ b/langevin.cpp @@ -5,6 +5,7 @@ #include #include "Eigen/src/Eigenvalues/ComplexEigenSolver.h" +#include "Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h" #include "complex_normal.hpp" #include "p-spin.hpp" #include "dynamics.hpp" @@ -139,6 +140,16 @@ int main(int argc, char* argv[]) { Rng r; + Tensor ReJ = generateCouplings(N, std::normal_distribution(0, σ), r.engine()); + + std::normal_distribution Red(0, 1); + + Vector zMin = randomMinimum(ReJ, Red, r, ε); + auto [Hr, dHr, ddHr] = hamGradHess(ReJ, zMin); + Eigen::EigenSolver> eigenS(ddHr - ((ddHr * zMin) * zMin.transpose()) / (Real)zMin.size()); + std::cout << eigenS.eigenvalues().transpose() << std::endl; + getchar(); + complex_normal_distribution d(0, 1, 0); ComplexTensor J = generateCouplings(N, complex_normal_distribution(0, σ, κ), r.engine()); @@ -161,6 +172,7 @@ int main(int argc, char* argv[]) { zSaddleNext = findSaddle(J, z0, ε); Real saddleDistance = (zSaddleNext - zSaddle).norm(); if (saddleDistance / N > 1e-2) { + std::cout << saddleDistance << std::endl; foundSaddle = true; } } catch (std::exception& e) {} @@ -222,7 +234,7 @@ int main(int argc, char* argv[]) { */ Cord test(J, zSaddle, zSaddleNext, 5); - test.relaxNewton(J, 20, 1, 1e4); + test.relaxNewton(J, 25, 1, 1e4); std::cout << test.z0.transpose() << std::endl; std::cout << test.z1.transpose() << std::endl; -- cgit v1.2.3-54-g00ecf