diff options
author | Jaron Kent-Dobias <jaron@kent-dobias.com> | 2021-01-05 11:51:07 +0100 |
---|---|---|
committer | Jaron Kent-Dobias <jaron@kent-dobias.com> | 2021-01-05 11:51:07 +0100 |
commit | 4ef7461eded758cdab5f8dc063f06176310e0760 (patch) | |
tree | d76d0b6761031c8f0e6f63710f822af6a180acc3 /p-spin.hpp | |
parent | 29f28945a5de06d88b65865e932a0a53ada0ff2f (diff) | |
download | code-4ef7461eded758cdab5f8dc063f06176310e0760.tar.gz code-4ef7461eded758cdab5f8dc063f06176310e0760.tar.bz2 code-4ef7461eded758cdab5f8dc063f06176310e0760.zip |
Refactor in preparation to resume using the stereographic library for Newton's method.
Diffstat (limited to 'p-spin.hpp')
-rw-r--r-- | p-spin.hpp | 43 |
1 files changed, 43 insertions, 0 deletions
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 <eigen3/Eigen/Core> +#include <eigen3/unsupported/Eigen/CXX11/Tensor> + +#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<double>; +using Vector = Eigen::VectorXcd; +using Matrix = Eigen::MatrixXcd; +using Tensor = Eigen::Tensor<Scalar, PSPIN_P>; + +std::tuple<Scalar, Vector, Matrix> 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<double, Vector> 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}; +} |