From 4ef7461eded758cdab5f8dc063f06176310e0760 Mon Sep 17 00:00:00 2001 From: Jaron Kent-Dobias Date: Tue, 5 Jan 2021 11:51:07 +0100 Subject: Refactor in preparation to resume using the stereographic library for Newton's method. --- langevin.cpp | 39 +-------------------------------------- p-spin.hpp | 43 +++++++++++++++++++++++++++++++++++++++++++ stereographic.hpp | 6 ++++-- 3 files changed, 48 insertions(+), 40 deletions(-) create mode 100644 p-spin.hpp diff --git a/langevin.cpp b/langevin.cpp index 1a0e104..e4b6c8d 100644 --- a/langevin.cpp +++ b/langevin.cpp @@ -4,22 +4,11 @@ #include #include -#include -#include - #include "pcg-cpp/include/pcg_random.hpp" #include "randutils/randutils.hpp" #include "complex_normal.hpp" -#include "tensor.hpp" - -#define PSPIN_P 3 -const unsigned p = PSPIN_P; // polynomial degree of Hamiltonian - -using Scalar = std::complex; -using Vector = Eigen::VectorXcd; -using Matrix = Eigen::MatrixXcd; -using Tensor = Eigen::Tensor; +#include "p-spin.hpp" using Rng = randutils::random_generator; @@ -36,32 +25,6 @@ Vector initializeVector(unsigned N, double a, Rng& r) { return z; } -std::tuple hamGradHess(const Tensor& J, const Vector& z) { - Matrix Jz = contractDown(J, z); // Contracts J into p - 2 copies of z. - Vector Jzz = Jz * z; - - double f = factorial(p); - - Matrix hessian = ((p - 1) * p / f) * Jz; - Vector gradient = (p / f) * Jzz; - Scalar hamiltonian = (1 / f) * Jzz.dot(z); - - return {hamiltonian, gradient, hessian}; -} - -std::tuple WdW(const Tensor& J, const Vector& z) { - Vector gradient; - Matrix hessian; - std::tie(std::ignore, gradient, hessian) = hamGradHess(J, z); - - Vector projectedGradient = gradient - (gradient.dot(z) / (double)z.size()) * z; - - double W = projectedGradient.cwiseAbs2().sum(); - Vector dW = hessian.conjugate() * projectedGradient; - - return {W, dW}; -} - Vector langevin(const Tensor& J, const Vector& z0, double T, double γ0, std::function quit, Rng& r) { Vector z = z0; diff --git a/p-spin.hpp b/p-spin.hpp new file mode 100644 index 0000000..1ed4d8e --- /dev/null +++ b/p-spin.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include +#include + +#include "pcg-cpp/include/pcg_random.hpp" +#include "randutils/randutils.hpp" + +#include "tensor.hpp" + +#define PSPIN_P 3 +const unsigned p = PSPIN_P; // polynomial degree of Hamiltonian + +using Scalar = std::complex; +using Vector = Eigen::VectorXcd; +using Matrix = Eigen::MatrixXcd; +using Tensor = Eigen::Tensor; + +std::tuple hamGradHess(const Tensor& J, const Vector& z) { + Matrix Jz = contractDown(J, z); // Contracts J into p - 2 copies of z. + Vector Jzz = Jz * z; + + double f = factorial(p); + + Matrix hessian = ((p - 1) * p / f) * Jz; + Vector gradient = (p / f) * Jzz; + Scalar hamiltonian = (1 / f) * Jzz.dot(z); + + return {hamiltonian, gradient, hessian}; +} + +std::tuple WdW(const Tensor& J, const Vector& z) { + Vector gradient; + Matrix hessian; + std::tie(std::ignore, gradient, hessian) = hamGradHess(J, z); + + Vector projectedGradient = gradient - (gradient.dot(z) / (double)z.size()) * z; + + double W = projectedGradient.cwiseAbs2().sum(); + Vector dW = hessian.conjugate() * projectedGradient; + + return {W, dW}; +} diff --git a/stereographic.hpp b/stereographic.hpp index 7dd871c..4109bc7 100644 --- a/stereographic.hpp +++ b/stereographic.hpp @@ -1,3 +1,6 @@ +#include + +#include "p-spin.hpp" Vector stereographicToEuclidean(const Vector& ζ) { unsigned N = ζ.size() + 1; @@ -67,8 +70,7 @@ Matrix stereographicMetric(const Vector& ζ) { return g; } -std::tuple, Vector, Matrix> stereographicHamGradHess(const Tensor3& J, - const Vector& ζ) { +std::tuple stereographicHamGradHess(const Tensor& J, const Vector& ζ) { Vector grad; Matrix hess; -- cgit v1.2.3-70-g09d2