From c60430fc1c5d90ae06d1fd019257474c8f395bef Mon Sep 17 00:00:00 2001 From: Jaron Kent-Dobias Date: Fri, 5 Nov 2021 17:31:10 +0100 Subject: Lots of progress towards Hessian implementation. --- p-spin.hpp | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'p-spin.hpp') diff --git a/p-spin.hpp b/p-spin.hpp index e5cd195..50da209 100644 --- a/p-spin.hpp +++ b/p-spin.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include "types.hpp" #include "tensor.hpp" @@ -104,3 +105,41 @@ Matrix dzDotConjugate(const Vector& z, const Vector& dH, Matrix::Identity(ddH.rows(), ddH.cols()) - z.conjugate() * z.transpose() / z² ); } + +template +Tensor ddzDot(const Vector& z, const Vector& dH) { + Tensor zT = Eigen::TensorMap>(z.data(), {z.size()}); + Tensor dHT = Eigen::TensorMap>(dH.data(), {dH.size()}); + + Eigen::array, 0> ei = {}; + + Scalar z² = z.squaredNorm(); + + return - zT.conjugate().contract(dHT.conjugate(), ei).contract(zT.conjugate(), ei) / pow(z², 2) + - dHT.conjugate().contract(zT.conjugate(), ei).contract(zT.conjugate(), ei) / pow(z², 2) + + zT.conjugate().contract(zT.conjugate(), ei).contract(zT.conjugate(), ei) * (2.0 * dH.dot(z) / pow(z², 3)); +} + +template +Tensor ddzDotConjugate(const Vector& z, const Vector& dH, const Matrix& ddH, const Tensor& dddH) { + Tensor zT = Eigen::TensorMap>(z.data(), {z.size()}); + Tensor dHT = Eigen::TensorMap>(dH.data(), {dH.size()}); + Tensor ddHT = Eigen::TensorMap>(ddH.data(), {z.size(), z.size()}); + + Matrix I = Matrix::Identity(z.size(), z.size()); + Tensor IT = Eigen::TensorMap>(I.data(), {z.size(), z.size()}); + + Eigen::array, 0> ei = {}; + Eigen::array, 1> ip00 = {Eigen::IndexPair(0, 0)}; + + Scalar z² = z.squaredNorm(); + + return - dddH + dddH.contract(zT.conjugate(), ip00).contract(zT, ei) / z² + + IT.contract(ddHT.contract(zT.conjugate(), ip00), ei).shuffle((std::array){0, 2, 1}) / z² + + ddHT.contract(zT.conjugate(), ip00).contract(IT, ei) / z² + - zT.conjugate().contract(ddHT.contract(zT.conjugate(), ip00), ei).contract(zT, ei) / pow(z², 2) + - zT.conjugate().contract(IT, ei) * (z.dot(dH) / pow(z², 2)) + - IT.contract(zT.conjugate(), ei).shuffle((std::array){0, 2, 1}) * (z.dot(dH) / pow(z², 2)) + - ddHT.contract(zT.conjugate(), ip00).contract(zT.conjugate(), ei).contract(zT, ei) / pow(z², 2) + + zT.conjugate().contract(zT.conjugate(), ei).contract(zT, ei) * (2.0 * z.dot(dH) / pow(z², 3)); +} -- cgit v1.2.3-54-g00ecf