T3Frame ======= .. toctree:: :hidden: /autoapi/t3toolbox/frame_variations_format/T3Frame.d /autoapi/t3toolbox/frame_variations_format/T3Frame.shape /autoapi/t3toolbox/frame_variations_format/T3Frame.up_ranks /autoapi/t3toolbox/frame_variations_format/T3Frame.down_ranks /autoapi/t3toolbox/frame_variations_format/T3Frame.left_ranks /autoapi/t3toolbox/frame_variations_format/T3Frame.right_ranks /autoapi/t3toolbox/frame_variations_format/T3Frame.stack_shape /autoapi/t3toolbox/frame_variations_format/T3Frame.structure /autoapi/t3toolbox/frame_variations_format/T3Frame.variation_shapes /autoapi/t3toolbox/frame_variations_format/T3Frame.data /autoapi/t3toolbox/frame_variations_format/T3Frame.to_jax /autoapi/t3toolbox/frame_variations_format/T3Frame.to_numpy /autoapi/t3toolbox/frame_variations_format/T3Frame.copy /autoapi/t3toolbox/frame_variations_format/T3Frame.contains_jax /autoapi/t3toolbox/frame_variations_format/T3Frame.size /autoapi/t3toolbox/frame_variations_format/T3Frame.data_size /autoapi/t3toolbox/frame_variations_format/T3Frame.__repr__ /autoapi/t3toolbox/frame_variations_format/T3Frame.orthogonality_residual /autoapi/t3toolbox/frame_variations_format/T3Frame.is_orthogonal /autoapi/t3toolbox/frame_variations_format/T3Frame.minimal_ranks /autoapi/t3toolbox/frame_variations_format/T3Frame.has_minimal_ranks /autoapi/t3toolbox/frame_variations_format/T3Frame.has_numerically_minimal_ranks /autoapi/t3toolbox/frame_variations_format/T3Frame.validate /autoapi/t3toolbox/frame_variations_format/T3Frame.__post_init__ /autoapi/t3toolbox/frame_variations_format/T3Frame.unstack /autoapi/t3toolbox/frame_variations_format/T3Frame.stack /autoapi/t3toolbox/frame_variations_format/T3Frame.from_t3 /autoapi/t3toolbox/frame_variations_format/T3Frame.random_orthogonal /autoapi/t3toolbox/frame_variations_format/T3Frame.random_orthogonal_like /autoapi/t3toolbox/frame_variations_format/T3Frame.save /autoapi/t3toolbox/frame_variations_format/T3Frame.load /autoapi/t3toolbox/frame_variations_format/T3Frame.reverse /autoapi/t3toolbox/frame_variations_format/T3Frame.to_t3 /autoapi/t3toolbox/frame_variations_format/T3Frame.to_dense /autoapi/t3toolbox/frame_variations_format/T3Frame.orthogonalize /autoapi/t3toolbox/frame_variations_format/T3Frame.is_consistent /autoapi/t3toolbox/frame_variations_format/T3Frame.allclose .. py:class:: t3toolbox.frame_variations_format.T3Frame Frame for frame-variations representation of TuckerTensorTrains Often, one works with TuckerTensorTrains of the following forms:: 1--(H0)--R1---R2---1 1---L0--(H1)--R2---1 1---L0---L1--(H2)--1 | | | | | | | | | U0 U1 U2 U0 U1 U2 U0 U1 U2 | | | | | | | | | 1---D0---R1---R2---1 1---L0---D1---R2---1 1---L0---L1---D2---1 | | | | | | | | | (V0) U1 U2 U0 (V1) U2 U0 U1 (V2) | | | | | | | | | In each of these, there is a special "variation" core, indicated by parentheses (X), surrounded by "frame" cores. The components of T3Frame are the "frame cores": - up_tucker_cores = (U0, ..., U(d-1)), elm_shape=(nUi, Ni) - down_tt_cores = (D0, ..., D(d-1)), elm_shape=(rLi, nDi, rR(i+1)) - left_tt_cores = (L0, ..., L(d-1)), elm_shape=(rLi, ni, rL(i+1)) - right_tt_cores = (R0, ..., R(d-1)), elm_shape=(rRi, ni, rR(i+1)) The components of T3Variations are the "variation cores": - tucker_variations = (V0, ..., V(d-1)), elm_shape=(nDi, Ni) - tt_variations = (H0, ..., H(d-1)), elm_shape=(rLi, nUi, rRi) Note that Ld and R0 are not used in these diagrams. (Why keep them, then? They hold the base point as one extra variation term so the frame remembers where it is attached, and they give every family a uniform length d for code reuse / off-by-one safety. See ``docs/frame_variations.md`` for the full rationale, and for how the gauged variations act as coordinates -- which is what the weighted-layer metric ``T3FrameWeights`` reweights.) The edge ranks are shown in the following diagrams:: rL0 rL1 rR2 rR(d-1) rRd 1 ------ L0 ----- (H1) ----- ... ------ R(d-1) ------ 1 | | | | nU0 | nU1 | nU(d-1) | | | U0 U1 Ud | | | | N0 | N1 | N(d-1) | | | and:: rL0 rL1 rR2 rR(d-1) rRd 1 ------ L0 ------ D1 ------ ... ------ R(d-1) ------ 1 | | | | nU0 | nO1 | nU(d-1) | | | U0 (V1) Ud | | | | N0 | N1 | N(d-1) | | | A tangent vector can be written as the sum of all the tensor diagrams above. In this case, the frame cores are representations of the point where the tangent space attaches to the manifold, and the variation cores define the tangent vector with respect to the frame. Often, it is desirable for the frame cores to be **orthogonal** as follows: - up_tucker_cores = (U0,...,U(d-1)), orthogonal: U_ia U_ja = delta_ij - down_tt_cores = (O0,...,O(d-1)), outer-orthogonal O_aib O_ajb = delta_ij - left_tt_cores = (L0,...,L(d-1)), left-orthogonal: L_abi L_abj = delta_ij - right_tt_cores = (R0,...,R(d-1)), right-orthogonal R_ibc R_jbc = delta_ij Often, it is desirable for the variations to satisfy the following **Gauge conditions**: - U_ia V_ja = 0 (all V) - L_abi H_abj = 0 (all but the last H) If these conditions are satisfied, then one can do "dumb" corewise linear algebra (add, scale, dot product, etc) with the variations, and those core faithfully correspond to linear algebra with the N1 x ... x Nd tangent vectors represented by the variations. The orthogonal representations (45)-(46) and gauge conditions (48)-(49) are defined in Appendix A.3 of Alger, Christierson, Chen & Ghattas (2026), "Tucker Tensor Train Taylor Series" (arXiv:2603.21141). .. seealso:: :py:obj:`T3Variations`, :py:obj:`check_t3_frame`, :py:obj:`t3_orthogonal_representations`, :py:obj:`oblique_gauge_projection` .. rubric:: Examples >>> import numpy as np >>> import t3toolbox.frame_variations_format as bvf >>> ss = (2, 3) # frame/core stack C, shared by every core >>> up_tucker_cores = (np.ones(ss+(10, 14)), np.ones(ss+(11, 15)), np.ones(ss+(12, 16))) >>> down_tt_cores = (np.ones(ss+(1, 9, 4)), np.ones(ss+(2, 8, 5)), np.ones(ss+(3, 7, 1))) >>> left_tt_cores = (np.ones(ss+(1, 10, 2)), np.ones(ss+(2, 11, 3)), np.ones(ss+(3, 12, 5))) >>> right_tt_cores = (np.ones(ss+(2, 10, 4)), np.ones(ss+(4, 11, 5)), np.ones(ss+(5, 12, 1))) >>> frame = bvf.T3Frame(up_tucker_cores, down_tt_cores, left_tt_cores, right_tt_cores) >>> print(frame.structure) # (shape, up_ranks, down_ranks, left_ranks, right_ranks, stack_shape) ((14, 15, 16), (10, 11, 12), (9, 8, 7), (1, 2, 3, 5), (2, 4, 5, 1), (2, 3)) >>> print(frame.variation_shapes) # the (tucker, tt) holes a fitting T3Variations must fill (((9, 14), (8, 15), (7, 16)), ((1, 10, 4), (2, 11, 5), (3, 12, 1))) .. py:attribute:: up_tucker_cores :type: t3toolbox.backend.common.typ.Tuple[t3toolbox.backend.common.NDArray, Ellipsis] .. py:attribute:: down_tt_cores :type: t3toolbox.backend.common.typ.Tuple[t3toolbox.backend.common.NDArray, Ellipsis] .. py:attribute:: left_tt_cores :type: t3toolbox.backend.common.typ.Tuple[t3toolbox.backend.common.NDArray, Ellipsis] .. py:attribute:: right_tt_cores :type: t3toolbox.backend.common.typ.Tuple[t3toolbox.backend.common.NDArray, Ellipsis] Methods ------- .. autoapisummary:: t3toolbox.frame_variations_format.T3Frame.d t3toolbox.frame_variations_format.T3Frame.shape t3toolbox.frame_variations_format.T3Frame.up_ranks t3toolbox.frame_variations_format.T3Frame.down_ranks t3toolbox.frame_variations_format.T3Frame.left_ranks t3toolbox.frame_variations_format.T3Frame.right_ranks t3toolbox.frame_variations_format.T3Frame.stack_shape t3toolbox.frame_variations_format.T3Frame.structure t3toolbox.frame_variations_format.T3Frame.variation_shapes t3toolbox.frame_variations_format.T3Frame.data t3toolbox.frame_variations_format.T3Frame.to_jax t3toolbox.frame_variations_format.T3Frame.to_numpy t3toolbox.frame_variations_format.T3Frame.copy t3toolbox.frame_variations_format.T3Frame.contains_jax t3toolbox.frame_variations_format.T3Frame.size t3toolbox.frame_variations_format.T3Frame.data_size t3toolbox.frame_variations_format.T3Frame.__repr__ t3toolbox.frame_variations_format.T3Frame.orthogonality_residual t3toolbox.frame_variations_format.T3Frame.is_orthogonal t3toolbox.frame_variations_format.T3Frame.minimal_ranks t3toolbox.frame_variations_format.T3Frame.has_minimal_ranks t3toolbox.frame_variations_format.T3Frame.has_numerically_minimal_ranks t3toolbox.frame_variations_format.T3Frame.validate t3toolbox.frame_variations_format.T3Frame.__post_init__ t3toolbox.frame_variations_format.T3Frame.unstack t3toolbox.frame_variations_format.T3Frame.stack t3toolbox.frame_variations_format.T3Frame.from_t3 t3toolbox.frame_variations_format.T3Frame.random_orthogonal t3toolbox.frame_variations_format.T3Frame.random_orthogonal_like t3toolbox.frame_variations_format.T3Frame.save t3toolbox.frame_variations_format.T3Frame.load t3toolbox.frame_variations_format.T3Frame.reverse t3toolbox.frame_variations_format.T3Frame.to_t3 t3toolbox.frame_variations_format.T3Frame.to_dense t3toolbox.frame_variations_format.T3Frame.orthogonalize t3toolbox.frame_variations_format.T3Frame.is_consistent t3toolbox.frame_variations_format.T3Frame.allclose