summaryrefslogtreecommitdiff
path: root/stereographic.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'stereographic.hpp')
-rw-r--r--stereographic.hpp26
1 files changed, 15 insertions, 11 deletions
diff --git a/stereographic.hpp b/stereographic.hpp
index 638923f..2dfa735 100644
--- a/stereographic.hpp
+++ b/stereographic.hpp
@@ -4,9 +4,10 @@
#include "p-spin.hpp"
-Vector stereographicToEuclidean(const Vector& ζ) {
+template <class Scalar>
+Vector<Scalar> stereographicToEuclidean(const Vector<Scalar>& ζ) {
unsigned N = ζ.size() + 1;
- Vector z(N);
+ Vector<Scalar> z(N);
Scalar a = ζ.transpose() * ζ;
Scalar b = 2 * sqrt(N) / (1.0 + a);
@@ -20,9 +21,10 @@ Vector stereographicToEuclidean(const Vector& ζ) {
return b * z;
}
-Vector euclideanToStereographic(const Vector& z) {
+template <class Scalar>
+Vector<Scalar> euclideanToStereographic(const Vector<Scalar>& z) {
unsigned N = z.size();
- Vector ζ(N - 1);
+ Vector<Scalar> ζ(N - 1);
for (unsigned i = 0; i < N - 1; i++) {
ζ(i) = z(i);
@@ -31,9 +33,10 @@ Vector euclideanToStereographic(const Vector& z) {
return ζ / (sqrt(N) - z(N - 1));
}
-Matrix stereographicJacobian(const Vector& ζ) {
+template <class Scalar>
+Matrix<Scalar> stereographicJacobian(const Vector<Scalar>& ζ) {
unsigned N = ζ.size();
- Matrix J(N, N + 1);
+ Matrix<Scalar> J(N, N + 1);
Scalar b = 1.0 + (Scalar)(ζ.transpose() * ζ);
@@ -52,15 +55,16 @@ Matrix stereographicJacobian(const Vector& ζ) {
return 4 * sqrt(N + 1) * J / pow(b, 2);
}
-std::tuple<Scalar, Vector, Matrix> stereographicHamGradHess(const Tensor& J, const Vector& ζ, const Vector& z) {
+template <class Scalar, int p>
+std::tuple<Scalar, Vector<Scalar>, Matrix<Scalar>> stereographicHamGradHess(const Tensor<Scalar, p>& J, const Vector<Scalar>& ζ, const Vector<Scalar>& z) {
auto [hamiltonian, gradZ, hessZ] = hamGradHess(J, z);
- Matrix jacobian = stereographicJacobian(ζ);
+ Matrix<Scalar> jacobian = stereographicJacobian(ζ);
- Matrix metric = jacobian * jacobian.adjoint();
+ Matrix<Scalar> metric = jacobian * jacobian.adjoint();
// The metric is Hermitian and positive definite, so a Cholesky decomposition can be used.
- Vector grad = metric.llt().solve(jacobian) * gradZ;
- Matrix hess = jacobian * hessZ * jacobian.transpose();
+ Vector<Scalar> grad = metric.llt().solve(jacobian) * gradZ;
+ Matrix<Scalar> hess = jacobian * hessZ * jacobian.transpose();
return {hamiltonian, grad, hess};
}