Consider an $n$-dimensional vector $v$ in Cartesian coordinates. Then, using hyper-spherical coordinates, we can write the direction of $v$ using $n-1$ angles $\theta=(\theta_1,\ldots,\theta_{n-1})$. (Ignoring the radius $r$).
Now, suppose I have an angular orientation $\phi=(\phi_1,\ldots,\phi_{n-1})$. I want to perturb it towards $\theta$. In other words, I want to compute: $$ \psi = \phi + \epsilon\tilde{\theta} $$ where $\epsilon$ is a small number much less than 1.
I want to find $ \tilde{\theta} $ such that $\psi$ moves closer to $\theta$ than $\phi$ is.
I thought that setting $\tilde{\theta}=\theta$ or $\tilde{\theta}=\theta-\phi$ would make sense, but it's not working!
NB: I want to find $\tilde{\theta}$. I cannot change any of the other quantities or work in a different coordinate system (e.g. say, do everything in Cartesian coordinates).
EDIT: It appears that the mistake I made was that linearly interpolating the angles (i.e. spherical coordinates) independently.
Indeed, what I think I need is the great circle equation on the $n$-sphere or hyper-sphere. I can then take its derivative to get an initial bearing/heading that points in the direction of the shortest distance to reach
In other words, I need information about the geodesic from one point to another in hyper-spherical coordinates. I can then compute the tangent vector to the geodesic at the initial point, and set that equal to $\tilde{\theta}$.
This is very similar to spherical geometry and navigation, for which much literature exists (e.g. here).
I would be happy with approximations rather than exact solutions, since many perturbations will be occurring. I don't want to solve the geodesic equation over and over again on the hyper-sphere.
A few somewhat related links: [1], [2], [3]
A few somewhat related questions: [1], [2], [3], [4]
Here is a set of code that reproduces my problem, or at least illustrates it, in 5D.
I am trying to perturb $\phi=(0,0,0,0)$ (equivalent to $(1,0,0,0,0)$ in Cartesian coordinates) towards $v=(0,-1,0,0,0)$ i.e. closer to $\theta$. But I end up tilting it in the opposite direction!
import numpy as np
from math import sin, cos
np.set_printoptions(precision=4)
n = 5
def theta(x):
x = np.array(x)
toFill = np.array([0.0]*(n-1))
r_array = np.sqrt( np.array( [ sum( [xj**2 for xj in x[i+1:]] ) for i in range(0,n-1) ] ) )
for k in range(0,n-2):
toFill[k] = np.arctan2( r_array[k] , x[k] )
toFill[n-2] = 2 * np.arctan2( x[n-1] , ( x[n-2] + np.sqrt(x[n-1]**2 + x[n-2]**2) ) )
return toFill
def cartesian(theta):
toFill = np.array([0.0] * n)
s0, s1 = sin(theta[0]), sin(theta[1])
toFill[0] = cos(theta[0])
toFill[1] = s0 * cos(theta[1])
toFill[2] = s0 * s1 * cos(theta[2])
toFill[3] = s0 * s1 * sin(theta[2]) * cos(theta[3])
toFill[4] = s0 * s1 * sin(theta[2]) * sin(theta[3])
return toFill
##
angularState = np.array([0.0] * (n-1))
vector = np.array([0.0, -1.0, 0.0, 0.0, 0.0])
print("Cartesian Vector: " + str(vector))
angle = theta(vector)
print("Angle (as direction): " + str(angle))
reconvertedVector = cartesian(angle)
print("Cartesian Vector reconverted: " + str(reconvertedVector))
angularPerturbation = cartesian(angle * 0.01)
print("Cartesian Vector of angular perturbation: " + str(angularPerturbation))
perturbedAngle = angularState + (angle * 0.01)
print("Perturbed angle: " + str(perturbedAngle))
perturbedDirection = cartesian(perturbedAngle)
print("Perturbed direction: " + str(perturbedDirection))