def tangProj(m, z): # preshapes '''Orthogonally project z onto tangent space at m (considering the ambient space)''' if np.abs(her(m, z)) < 1e-2: return z ta = theta(z, m) v_proj = exp(1j * ta) * (z - her(m, z) * m) return v_proj
def d_P(z, w): # preshapes '''Partial distance between [z] and [w] min_{theta} ||e^{i theta} z - w||''' aux = 2 * np.abs(her(z, w)) if aux > 2: # same possibility as for d_F return 0.0 return sqrt(2 - aux)
def d_F(z, w): # preshapes '''Full distance between [z] and [w] min_{alpha,theta} ||alpha e^{i theta} z - w|| = || w - P_z w || = ||z - P_w z|| \in [0,1] ''' aux = np.abs(her(z, w))**2 if aux > 1: # due to numerical approximations, but mathematically should be <= 1 return 0.0 return sqrt(1 - aux)
def proj_S(D_c): # columns of D_c are general configurations in C^N '''converts non-zero columns of D_c to preshapes, by projecting them on the subspace rthogonal to u {d | u.T.conj() Phi d = 0)} and then normalizing them. Those which are zero are left as they are. ''' from settings import uu J = D_c.shape[1] for j in range(J): d = D_c[:, j] no = norm(d) if no > 1e-8: orth_d = her(uu, d) * uu d = d - orth_d d = d / norm(d) D_c[:, j] = d return D_c
def theta(z, w): # preshapes '''Computes the optimal angle theta(z,w) = arg(z* Phi w) solution to min_{theta} ||e^{i theta} z - w||''' return np.angle(her(z, w))
def rho(z, w): # preshapes '''Geodesic distance between [z] and [w]. ''' aux = np.abs(her(z, w)) if aux > 1: # happens sometimes due to numerical errors aux = 1 return arccos(aux)