<jupyter_start><jupyter_text>Vectorisation testsDot product is already tested in DotTest Distance<jupyter_code>import numpy as np
import matplotlib.pyplot as plt
from matplotlib import collections, lines, markers, path, patches
from mpl_toolkits.mplot3d import Axes3D
%matplotlib inline
from geometry import dot, get_metric
def distance(u, v, geometry="spherical"):
    '''
        Calculate distance on the manifold between two pts
        Inputs: u, v: two vectors, represented as np.arrays
        Outputs: distance, a 1-D real number
    '''
    dotprod = dot(u,v,geometry)
#    if np.abs(dotprod) > 1:
#        print("distance: {}.{} = {:.3g}".format(u, v, dotprod))

    if geometry == "spherical":
        return np.arccos(dotprod)
    elif geometry == "hyperbolic":
        return np.arccosh(-dotprod)
    elif geometry == "euclidean":
        return np.sqrt(dot(u-v, u-v, geometry))
    else:
        print("geometry = {} is not a valid option! Try 'spherical' or 'hyperbolic'".format(geometry))
alpha = 0.1
beta = 1.1
a = np.array([[np.sinh(alpha), np.cosh(alpha)]]).T
b = np.array([[np.sinh(beta), np.cosh(beta)]]).T
print(a)
print(b)
distance(a, b, geometry="hyperbolic")
c = np.array([[-1, 0],[0, 1]]).dot(a)
d = np.array([[-1, 0],[0, 1]]).dot(b)
print(c)
print(d)
print(distance(a, c, geometry="hyperbolic"))
print(distance(a, d, geometry="hyperbolic"))
print(distance(b, c, geometry="hyperbolic"))
print(distance(b, d, geometry="hyperbolic"))
ab = np.hstack([a, b])
print(ab)
cd = np.hstack([c, d])
print(cd)
distance(ab, cd, geometry="hyperbolic")
distance(a, cd, geometry="hyperbolic")
def frechet_diff_vectorised(p_eval, points, geometry="spherical"):
    '''
        Calculates the differential to enable a gradient descent algorithm to find 
        the Karcher/Fréchet mean of a set of points.
        Inputs:
            p_eval: Point at which to evaluate the derivative (usually a guess at 
                    the mean). (d+1)-dimensional vector, expressed in ambient space
                    coordinates.
            points: List of points which the derivative is calculate w.r.t. to. 
                    (d+1)-dimensional vector, expressed in ambient space
                    coordinates.
            geometry: string specifying which metric and distance function to use.
        Outputs:
            Derivative: (d+1)-dimensional vector, expressed in ambient space
                        coordinates.
        Note: should vectorise to remove loop over points.
    '''
    metric = get_metric(p_eval.shape[0], geometry)
#    update = np.zeros([p_eval.shape[0], 1])
    coeffs = -2.*distance(p_eval, points, geometry)
    print("numerator = ",coeffs)
    if geometry == "spherical":
        coeffs /= np.sqrt(1.-dot(p_eval, points, geometry)**2)+ 1.e-10
    elif geometry == "hyperbolic":
        coeffs /= np.sqrt(dot(p_eval, points, geometry)**2-1.)+ 1.e-10
    print("coeffs =",coeffs)
    print("points =", points)
    print("coeffs*points = ", coeffs*points)
    return np.atleast_2d(np.sum(coeffs*points, axis=1)).T

frechet_diff_vectorised(a, cd, geometry="hyperbolic")
def frechet_diff(p_eval, points, geometry="spherical"):
    '''
        Calculates the differential to enable a gradient descent algorithm to find 
        the Karcher/Fréchet mean of a set of points.
        Inputs:
            p_eval: Point at which to evaluate the derivative (usually a guess at 
                    the mean). (d+1)-dimensional vector, expressed in ambient space
                    coordinates.
            points: List of points which the derivative is calculate w.r.t. to. 
                    (d+1)-dimensional vector, expressed in ambient space
                    coordinates.
            geometry: string specifying which metric and distance function to use.
        Outputs:
            Derivative: (d+1)-dimensional vector, expressed in ambient space
                        coordinates.
        Note: should vectorise to remove loop over points.
    '''
    metric = get_metric(p_eval.shape[0], geometry)
    update = np.zeros([p_eval.shape[0], 1])
#    print("frechet_diff: p_eval = {}, points = {}".format(p_eval, points))
    for xi in points:
        if np.array_equal(p_eval,xi):
           continue
#        print("frechet_diff: xi =", xi)
        coeff = -2.*distance(p_eval, xi, geometry)
        print("numerator =", coeff)
        if geometry == "spherical":
            coeff /= np.sqrt(1.-dot(p_eval, xi, geometry)**2)+ 1.e-10
        elif geometry == "hyperbolic":
            coeff /= np.sqrt(dot(p_eval, xi, geometry)**2-1.)
        print("frechet_diff: coeff =", coeff)
        print("coeffs*point = ",coeff*xi)
#        update += coeff*metric.dot(xi)
        update += coeff*xi
    
    print("frechet_diff: update = {}".format(update))
    return update
frechet_diff(a, [c,d], geometry="hyperbolic")
frechet_diff_vectorised(a, [c,d], geometry="hyperbolic")<jupyter_output>coeffs =  [[[-1.63320482]
  [-2.35552805]]]
StarcoderdataJupyterStructuredCleanDedup