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 +++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 21 deletions(-) (limited to 'dynamics.hpp') 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; -- cgit v1.2.3-54-g00ecf