t3toolbox.manifold.oblique_gauge_projection#
- t3toolbox.manifold.oblique_gauge_projection(variation: t3toolbox.basis_coordinates_format.T3Variation, orthogonal_base: t3toolbox.basis_coordinates_format.T3Base, use_jax: bool = False) t3toolbox.basis_coordinates_format.T3Variation#
Makes variations left-perpendicular while preserving tangent vector.
- Straightforward generalization of the method from:
Holtz, Sebastian, Thorsten Rohwedder, and Reinhold Schneider. “On manifolds of tensors of fixed TT-rank.” Numerische Mathematik 120.4 (2012): 701-731.
- Parameters:
variation (T3Variation,) – The variation that we wish to make gauged
orthogonal_base (T3Base,) – Orthogonal representations of the base point on the manifold. If non-orthogonal, this method doesn’t work properly.
xnp – Linear algebra backend. Default: np (numpy)
- Returns:
Projected variation satisfying Gauge condition. Represents the same tangent vector as the original variation.
- Return type:
T3Variation
See also
T3Base,T3Variation,orthogonal_gauge_projectionExamples
>>> import numpy as np >>> import t3toolbox.tucker_tensor_train as t3 >>> import t3toolbox.manifold as t3m >>> import t3toolbox.orthogonalization as orth >>> p = t3.t3_corewise_randn(((14,15,16), (4,5,6), (1,3,2,1))) >>> base, _ = orth.orthogonal_representations(p) >>> variation = t3m.tangent_randn(base) >>> proj_variation = t3m.oblique_gauge_projection(variation, base) # Make gauged via oblique projection >>> v_dense = t3m.tangent_to_dense(variation, base) >>> proj_v_dense = t3m.tangent_to_dense(proj_variation, base) >>> print(np.linalg.norm(v_dense - proj_v_dense)) # Zero since projection preserves represented tangent vector 3.4398319441148304e-15 >>> (U0,U1,U2), (L0,L1,L2), _, _ = base >>> ((V0,V1,V2), (H0,H1,H2)) = proj_variation >>> print(np.linalg.norm(V1 @ U1.T)) # Gauge condition for Tucker backend 1 2.931519226677228e-15 >>> print(np.linalg.norm(np.einsum('iaj,iak->jk', H1, L1))) # Gauge condition for TT-backend 1 6.99005312491287e-16
With minimal ranks, orthogonal bases, and gauged variations, the corewise dot product faithfully represents the Hilbert-Schmidt inner product on the ambient space:
>>> import numpy as np >>> import t3toolbox.tucker_tensor_train as t3 >>> import t3toolbox.manifold as t3m >>> import t3toolbox.common >>> import t3toolbox.orthogonalization as orth >>> import t3toolbox.corewise as cw >>> p = t3.t3_corewise_randn(((14,15,16), (4,5,6), (1,3,2,1))) >>> base, _ = orth.orthogonal_representations(p) >>> u = t3m.tangent_randn(base, apply_gauge_projection=False) >>> v = t3m.tangent_randn(base, apply_gauge_projection=False) >>> bad_u_inner_v = cw.corewise_dot(u, v) # u and v are ungauged, so this will not give the right answer >>> u_dense = t3m.tangent_to_dense(u, base) >>> v_dense = t3m.tangent_to_dense(v, base) >>> u_inner_v_true = np.sum(u_dense * v_dense) >>> print(np.abs(bad_u_inner_v - u_inner_v_true)) # error nonzero because we didn't respect gauge 6.21838915941413 >>> u_gauged = t3m.oblique_gauge_projection(u, base) # make them gauged and try again >>> v_gauged = t3m.oblique_gauge_projection(v, base) >>> u_inner_v = cw.corewise_dot(u_gauged, v_gauged) >>> print(np.abs(u_inner_v - u_inner_v_true)) # Now the error is numerical zero 0.0