t3toolbox.manifold.orthogonal_gauge_projection#

t3toolbox.manifold.orthogonal_gauge_projection(variation: t3toolbox.basis_coordinates_format.T3Variation | t3toolbox.OLD_uniform.UniformT3Variation, orthogonal_base: t3toolbox.basis_coordinates_format.T3Base | t3toolbox.OLD_uniform.UniformT3Base, use_jax: bool = False) t3toolbox.basis_coordinates_format.T3Variation | t3toolbox.OLD_uniform.UniformT3Variation#

Makes tangent variation gauged via orthogonal projection. Changes tangent vector.

Gauge condition:
  • All variation Tucker cores Vi are orthogonal to the corresponding base Tucker cores Ui:

    Ui @ Vi.T = 0 for i=1,…,d

  • All but the last variation TT-cores H are left-perpendicular to the corresponding base left TT-cores L:

    einsum(‘iaj,iak->jk’, Hi, Li) = 0 for i=1,…,d-1

Parameters:
  • variation (T3Variation,) – The variation which will become gauged.

  • orthogonal_base (T3Base,) – The base representations. Must be orthogonal for the operation to work properly.

  • xnp – Linear algebra backend. Default: np (numpy)

Returns:

Projected variation satisfying Gauge condition. Represents different tangent vector than original variation.

Return type:

T3Variation

See also

T3Base, T3Variation, t3_oblique_gauge_projection

Examples

>>> import numpy as np
>>> import t3toolbox.tucker_tensor_train as t3
>>> import t3toolbox.manifold as t3m
>>> import t3toolbox.common as 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)
>>> variation = t3m.tangent_randn(base, apply_gauge_projection=False)
>>> proj_variation = t3m.orthogonal_gauge_projection(variation, base) # Make gauged via orthogonal projection
>>> (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
3.512073125137391e-15
>>> print(np.linalg.norm(np.einsum('iaj,iak->jk', H1, L1))) # Gauge condition for TT-backend 1
1.5807940730805242e-15
>>> v_minus_p_dot_p = cw.corewise_dot(cw.corewise_sub(variation, proj_variation), proj_variation)
>>> print(v_minus_p_dot_p) # Projection is orthogonal w.r.t. corewise dot
-4.995303314442243e-18

Uniform example:

>>> import numpy as np
>>> import t3toolbox.tucker_tensor_train as t3
>>> import t3toolbox.manifold as t3m
>>> import t3toolbox.common as common
>>> import t3toolbox.orthogonalization as orth
>>> import t3toolbox.corewise as cw
>>> import t3toolbox.uniform as ut3
>>> p = t3.t3_corewise_randn(((14,15,16), (4,5,6), (1,3,2,1)))
>>> base, dummy_var = orth.orthogonal_representations(p)
>>> _, uniform_base, masks = ut3.bv_to_ubv(dummy_var, base)
>>> uniform_var = t3m.tangent_randn(uniform_base, masks=masks, apply_gauge_projection=False)
>>> proj_var = t3m.orthogonal_gauge_projection(uniform_var, uniform_base)
>>> UU, LL, RR, OO = uniform_base
>>> proj_tucker_var, proj_tt_var = proj_var
>>> print(np.linalg.norm(np.einsum('dio,djo->dij', proj_tucker_var, UU)))
6.860678066865219e-15
>>> print(np.linalg.norm(np.einsum('diaj,diak->djk', proj_tt_var[:-1], LL[:-1]))) # first var tt cores are left-orthogonal to base
2.0607190172353126e-15
>>> ip = cw.corewise_dot(cw.corewise_sub(uniform_var, proj_var), proj_var)
>>> print(ip) # Projection is orthogonal w.r.t. corewise dot
4.496403249731884e-14