From a71a380cde2a254dfffa98908d532110f99f2473 Mon Sep 17 00:00:00 2001 From: Al3cLee Date: Tue, 7 Apr 2026 11:16:53 +0800 Subject: [PATCH] chore: support typst backend for docs --- docs/Project.toml | 2 + docs/make.jl | 5 +- docs/src/appendix/categories.md | 88 +++++++------------------ docs/src/appendix/symmetric_tutorial.md | 56 ++++------------ docs/src/man/fusiontrees.md | 40 +++-------- docs/src/man/symmetries.md | 4 +- docs/src/man/tensormanipulations.md | 12 +--- docs/src/man/tensors.md | 8 +-- 8 files changed, 58 insertions(+), 157 deletions(-) diff --git a/docs/Project.toml b/docs/Project.toml index 23cb822ec..7359371b7 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,6 +1,7 @@ [deps] Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" DocumenterInterLinks = "d12716ef-a0f6-4df4-a9f1-a5a34e75c656" +DocumenterTypst = "d7fd56dd-41bc-4b2d-b658-79a5840b2e09" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" SUNRepresentations = "1a50b95c-7aac-476d-a9ce-2bfc675fc617" @@ -11,6 +12,7 @@ WignerSymbols = "9f57e263-0b3d-5e2e-b1be-24f2bb48858b" [compat] Documenter = "1" DocumenterInterLinks = "1" +DocumenterTypst = "0.1" LinearAlgebra = "1" Random = "1" SUNRepresentations = "0.3" diff --git a/docs/make.jl b/docs/make.jl index e6021f55c..da3e22e52 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,6 +1,7 @@ +using Pkg + # if examples is not the current active environment, switch to it if Base.active_project() != joinpath(@__DIR__, "Project.toml") - using Pkg Pkg.activate(@__DIR__) Pkg.develop(PackageSpec(; path = joinpath(@__DIR__, ".."))) Pkg.resolve() @@ -8,6 +9,7 @@ if Base.active_project() != joinpath(@__DIR__, "Project.toml") end using Documenter +using DocumenterTypst using Random using TensorKit using TensorKit: FusionTreePair, Index2Tuple @@ -61,6 +63,7 @@ makedocs(; format = Documenter.HTML(; prettyurls = true, mathengine, assets = ["assets/custom.css"] ), + # format = DocumenterTypst.Typst(), pages = pages, pagesonly = true, plugins = [links] diff --git a/docs/src/appendix/categories.md b/docs/src/appendix/categories.md index 5a111b4fe..82c0f4814 100644 --- a/docs/src/appendix/categories.md +++ b/docs/src/appendix/categories.md @@ -27,9 +27,7 @@ To morphisms, we associate boxes with an incoming and outgoing line denoting the The flow from source to target, and thus the direction of morphism composition ``f ∘ g`` (sometimes known as the flow of time) can be chosen left to right (like the arrow in ``f:W→V``), right to left (like the composition order ``f ∘ g``, or the matrix product), bottom to top (quantum field theory convention) or top to bottom (quantum circuit convention). Throughout this manual, we stick to this latter convention (which is not very common in manuscripts on category theory): -```@raw html -composition -``` +![composition](img/diagram_morphism.svg) The direction of the arrows, which become important once we introduce duals, are also subject to convention, and are here chosen to follow the arrow in ``f:W→V``, i.e. the source comes in and the target goes out. Strangely enough, this is opposite to the most common convention. @@ -95,9 +93,7 @@ Similarly, the identity object ``I`` can be added or removed at will, and when d Note that any consistent way of inserting the associator or left or right unitor to convert a graphical representation to a diagram of compositions and tensor products of morphisms gives rise to the same result, by virtue of Mac Lane's coherence theorem. Using the horizontal direction (left to right) to stack tensor products, this gives rise to the following graphical notation for the tensor product of two morphisms, and for a general morphism ``t`` between a tensor product of objects in source and target: -```@raw html -tensorproduct -``` +![tensorproduct](img/diagram-tensorproduct.svg) Another relevant example is the category ``\mathbf{SVect}_𝕜``, which has as objects *super vector spaces* over ``𝕜``, which are vector spaces with a ``ℤ₂`` grading, i.e. they are decomposed as a direct sum ``V = V_0 ⊕ V_1``. Furthermore, the morphisms between two super vector spaces are restricted to be grading preserving, i.e. ``f∈ \mathrm{Hom}_{\mathbf{SVect}}(W,V)`` has ``f(W_0) ⊂ V_0`` and ``f(W_1) ⊂ V_1``. @@ -151,9 +147,7 @@ Indeed, it can be shown that for any category which has duals for objects ``V`` Graphically, we represent the exact pairing and snake rules as -```@raw html -left dual -``` +![left dual](img/diagram-leftdual.svg) Note that we denote the dual objects ``{}^{∨}V`` as a line ``V`` with arrows pointing in the opposite (i.e. upward) direction. This notation is related to quantum field theory, where anti-particles are (to some extent) interpreted as particles running backwards in time. @@ -161,18 +155,14 @@ This notation is related to quantum field theory, where anti-particles are (to s These exact pairings are known as the left evaluation and coevaluation, and ``{}^{∨}V`` is the left dual of ``V``. Likewise, we can also define a right dual ``V^{∨}`` of ``V`` and associated pairings, the right evaluation ``\tilde{ϵ}_V: V ⊗ V^{∨} → I`` and coevaluation ``\tilde{η}_V: I → V^{∨} ⊗ V``, satisfying -```@raw html -right dual -``` +![right dual](img/diagram-rightdual.svg) In particular, one could choose ``\tilde{ϵ}_{{}^{∨}V} = ϵ_V`` and thus define ``V`` as the right dual of ``{}^{∨}V``. While there might be other choices, this choice must at least be isomorphic, such that ``({}^{∨}V)^{∨} ≂ V``. If objects ``V`` and ``W`` have left (respectively right) duals, then for a morphism ``f ∈ \mathrm{Hom}(W,V)``, we furthermore define the left (respectively right) *transpose* ``{}^{∨}f ∈ \mathrm{Hom}({}^{∨}V, {}^{∨}W)`` (respectively ``f^{∨} ∈ \mathrm{Hom}(V^{∨}, W^{∨})``) as -```@raw html -transpose -``` +![transpose](img/diagram-transpose.svg) where on the right we also illustrate the mapping from ``t ∈ \mathrm{Hom}(W_1 ⊗ W_2 ⊗ W_3, V_1 ⊗ V_2)`` to a morphism in ``\mathrm{Hom}(I, V_1 ⊗ V_2 ⊗ {}^{∨} W_3 ⊗ {}^{∨} W_2 ⊗ {}^{∨} W_1)``. @@ -211,9 +201,7 @@ and a right trace as They are graphically represented as -```@raw html -trace -``` +![trace](img/diagram-trace.svg) and they do not need to coincide. Note that ``\mathrm{tr}_{\mathrm{l}}(f) = \mathrm{tr}_{\mathrm{r}}(f*)`` and that ``\mathrm{tr}_{\mathrm{l}/\mathrm{r}}(f∘g) = \mathrm{tr}_{\mathrm{l}/\mathrm{r}}(g∘f)``. @@ -241,15 +229,11 @@ We also have ``λ_V ∘ τ_{V,I} = ρ_{V,I}``, ``ρ_V ∘ τ_{I,V} = λ_{V}`` an The braiding isomorphism ``τ_{V,W}`` and its inverse are graphically represented as the lines ``V`` and ``W`` crossing over and under each other: -```@raw html -braiding -``` +![braiding](img/diagram-braiding.svg) such that we have -```@raw html -braiding relations -``` +![braiding relations](img/diagram-braiding2.svg) where the expression on the right hand side, ``τ_{W,V}∘τ_{V,W}`` can generically not be simplified. Hence, for general braidings, there is no unique choice to identify a tensor in ``V⊗W`` and ``W⊗V``, as the isomorphisms ``τ_{V,W}``, ``τ_{W,V}^{-1}``, ``τ_{V,W} ∘ τ_{W,V} ∘ τ_{V,W}``, … mapping from ``V⊗W`` to ``W⊗V`` can all be different. @@ -262,9 +246,7 @@ Less trivial braiding implementations arise in the context of tensors with symme The braiding of a space and a dual space also follows naturally, it is given by ``τ_{V^*,W} = λ_{W ⊗ V^*} ∘ (ϵ_V ⊗ \mathrm{id}_{W ⊗ V^*}) ∘ (\mathrm{id}_{V^*} ⊗ τ_{V,W}^{-1} ⊗ \mathrm{id}_{V^*}) ∘ (\mathrm{id}_{V^*⊗ W} ⊗ η_V) ∘ ρ_{V^* ⊗ W}^{-1}``, i.e. -```@raw html -braiding dual -``` +![braiding dual](img/diagram-braidingdual.svg) **Balanced categories** ``C`` are braided categories that come with a **twist** ``θ``, a natural transformation from the identity functor ``1_C`` to itself, such that ``θ_V ∘ f = f ∘ θ_W`` for all morphisms ``f ∈ \mathrm{Hom}(W,V)``, and for which the main requirement is that @@ -287,9 +269,7 @@ and where we omitted the necessary left and right unitors and associators. Graphically, the twists and their inverse (for which we refer to [^Turaev]) are then represented as -```@raw html -twists -``` +![twists](img/diagram-twists.svg) The graphical representation also makes it straightforward to verify that ``(θ^{\mathrm{l}}_V)^* = θ^{\mathrm{r}}_{V^*}``, ``(θ^{\mathrm{r}}_V)^* = θ^{\mathrm{l}}_{V^*}`` and ``\mathrm{tr}_{\mathrm{l}}( θ^{\mathrm{r}}_V ) = \mathrm{tr}_{\mathrm{r}}( θ^{\mathrm{l}}_V )``. @@ -309,9 +289,7 @@ Alternatively, one can start from a balanced and rigid category (e.g. with a lef or graphically -```@raw html -pivotal from twist -``` +![pivotal from twist](img/diagram-pivotalfromtwist.svg) where we have drawn ``θ`` as ``θ^{\mathrm{l}}`` on the left and as ``θ^{\mathrm{r}}`` on the right, but in this case the starting assumption was that they are one and the same, and we defined the pivotal structure so as to make it compatible with the graphical representation. This construction of the pivotal structure can than be used to define the trace, which is spherical, i.e. @@ -350,9 +328,7 @@ Finally, we will also use the term *isometry* for a morphism ``f:W→V`` which h In the graphical representation, the dagger of a morphism can be represented by mirroring the morphism around a horizontal axis, and then reversing all arrows (bringing them back to their original orientation before the mirror operation): -```@raw html -dagger -``` +![dagger](img/diagram-dagger.svg) where for completeness we have also depicted the graphical representation of the transpose, which is a very different operation. In particular, the dagger does not reverse the order of the tensor product. @@ -474,9 +450,7 @@ In the context of a unitary fusion category, on which we now focus, the correspo Graphically, we represent these relations as -```@raw html -fusion -``` +![fusion](img/diagram-fusion.svg) and also refer to the inclusion and projection maps as splitting and fusion tensor, respectively. @@ -524,18 +498,14 @@ which defines the *F-symbol*, i.e. the matrix elements of the associator Note that the left hand side represents a map in ``\mathrm{Hom}(d′,d)``, which must be zero if ``d′`` is different from ``d``, hence the ``δ_{d,d′}`` on the right hand side. In a strict category, or in the graphical notation, the associator ``α`` is omitted and these relations thus represent a unitary basis transform between the basis of inclusion maps ``X_{d,(eμν)}^{abc}`` and ``\tilde{X}_{d,(fκλ)}^{abc}``, which is also called an F-move, i.e. graphically: -```@raw html -Fmove -``` +![Fmove](img/diagram-Fmove.svg) The matrix ``F^{abc}_d`` is thus a unitary matrix. The pentagon coherence equation can also be rewritten in terms of these matrix elements, and as such yields the celebrated pentagon equation for the F-symbols. In a similar fashion, the unitors result in ``N^{a1}_{b} = N^{1a}_b = δ^{a}_b`` (where we have now written ``1`` instead of ``I`` for the unit object) and the triangle equation leads to additional relations between the F- symbols involving the unit object. In particular, if we identify ``X^{1a}_{a,1}:a→(1⊗a)`` with ``λ_a^†`` and ``X^{a1}_{a,1}:a→(a⊗1)`` with ``ρ_a^†``, the triangle equation and its collaries imply that ``[F^{1ab}_{c}]_{(11μ)}^{(cν1)} = δ^{ν}_{μ}``, and similar relations for ``F^{a1b}_c`` and ``F^{ab1}_c``, which are graphically represented as -```@raw html -Fmove1 -``` +![Fmove1](img/diagram-Fmove1.svg) In the case of group representations, i.e. the category ``\mathbf{Rep}_{\mathsf{G}}``, the splitting and fusion tensors are known as the Clebsch-Gordan coefficients, especially in the case of ``\mathsf{SU}_2``. An F-move amounts to a recoupling and the F-symbols can thus be identified with the *6j-symbols* (strictly speaking, Racah's W-symbol for ``\mathsf{SU}_2``). @@ -560,9 +530,7 @@ If ``a``and ``\bar{a}`` are distinct, we can essentially choose ``Z_{\bar{a}}`` However, for ``a=\bar{a}``, the value of ``χ_a`` cannot be changed, but must satisfy ``χ_a^2 = 1``, or thus ``χ_a = ±1``. This value is a topological invariant known as the *Frobenius-Schur indicator*. Graphically, we represent this isomorphism and its relations as -```@raw html -Zisomorphism -``` +![Zisomorphism](img/diagram-Zisomorphism.svg) We can now discuss the relation between the exact pairing and the fusion and splitting tensors. Given that the (left) coevaluation ``η_a ∈ \mathrm{Hom}(1, a⊗a^*)``, we can define the splitting tensor as @@ -578,15 +546,11 @@ Hence, both the quantum dimensions and the Frobenius-Schur indicator are encoded Hence, they do not represent new independent data. Again, the graphical representation is more enlightning: -```@raw html -ZtoF -``` +![ZtoF](img/diagram-ZtoF.svg) With these definitions, we can now also evaluate the action of the evaluation map on the splitting tensors, namely -```@raw html -splittingfusionrelation -``` +![splittingfusionrelation](img/diagram-splittingfusionrelation.svg) where again bar denotes complex conjugation in the second line, and we introduced two new families of matrices ``A^{ab}_c`` and ``B^{ab}_c``, whose entries are composed out of entries of the F-symbol, namely @@ -602,9 +566,7 @@ and Composing the left hand side of first graphical equation with its dagger, and noting that the resulting element ``f ∈ \mathrm{End}(a)`` must satisfy ``f = d_a^{-1} \mathrm{tr}(f) \mathrm{id}_a``, i.e. -```@raw html -Brelation -``` +![Brelation](img/diagram-Brelation.svg) allows to conclude that ``∑_ν [B^{ab}_c]^{ν}_{μ} \overline{[B^{ab}_c]^{ν}_{μ′}} = \delta_{μ,μ′}``, i.e. ``B^{ab}_c`` is a unitary matrix. The same result follows for ``A^{ab}_c`` in analogue fashion. @@ -640,9 +602,7 @@ We can then express ``τ_{a,b}`` in terms of its matrix elements as or graphically -```@raw html -braidingR -``` +![braidingR](img/diagram-braidingR.svg) The hexagon coherence axiom for the braiding and the associator can then be reexpressed in terms of the F-symbols and R-symbols. @@ -654,9 +614,7 @@ We can now compute the twist, which for simple objects needs to be scalars (or i or graphically -```@raw html -simpletwist -``` +![simpletwist](img/diagram-simpletwist.svg) Henceforth, we reserve ``θ_a`` for the scalar value itself. Note that ``θ_a = θ_{\bar{a}}`` as our category is spherical and thus a ribbon category, and that the defining relation of a twist implies @@ -666,9 +624,7 @@ Henceforth, we reserve ``θ_a`` for the scalar value itself. Note that ``θ_a = If ``a = \bar{a}``, we can furthermore relate the twist, the braiding and the Frobenius- Schur indicator via ``θ_a χ_a R^{aa}_1 =1``, because of -```@raw html -twistfrobeniusschur -``` +![twistfrobeniusschur](img/diagram-twistfrobeniusschur.svg) For the recurring example of ``\mathbf{Rep}_{\mathsf{G}}``, the braiding acts simply as the swap of the two vector spaces on which the representations are acting and is thus symmetric, i.e. ``τ_{b,a} ∘ τ_{a,b} = \mathrm{id}_{a⊗b}``. All the twists are simply ``θ_a = 1``. diff --git a/docs/src/appendix/symmetric_tutorial.md b/docs/src/appendix/symmetric_tutorial.md index 7eda0a35a..0854d2fed 100644 --- a/docs/src/appendix/symmetric_tutorial.md +++ b/docs/src/appendix/symmetric_tutorial.md @@ -91,9 +91,7 @@ blocks(X) Let us now return to the global ``\mathbb{Z}_2`` invariance of the Hamiltonian \eqref{eq:isingham}, and consider what this implies for its local terms ``ZZ`` and ``X``. Representing these operators as `TensorMap`s, the invariance of ``H`` under a global ``\mathbb{Z}_2`` transformation implies the following identities for the local tensors: -```@raw html -
ZZX_symm
-``` +![ZZX_symm](img/symmetric_tutorial/ZZX_symm.svg) These identitities precisely mean that these local tensors transform trivially under a tensor product representation of ``\mathbb{Z}_2``. This implies that, recalling [the introduction on symmetries](@ref ss_symmetries), in an appropriate basis for the local physical vector space, our local tensors would become block-diagonal where each so-called *matrix block* is labeled by a ``\mathbb{Z}_2`` irrep. @@ -142,9 +140,7 @@ Similarly, ``XX`` acts with a minus sign on both ``\ket{+} \otimes \ket{-}`` and Having introduced this notion of 'fusing' irreps, we can now associate a well-defined *coupled irrep* to each of the four two-site basis states, which is given by the tensor product of the two *uncoupled irreps* associated to each individual site. From the matrix elements of ``ZZ`` given above, we clearly see that this operator only maps between states in the domain and codomain that have the same coupled irrep. This means that we can associate each of these matrix elements to a so-called *fusion tree* of ``\mathbb{Z}_2`` irreps with a corresponding coefficient of 1, -```@raw html -
Z2_fusiontrees
-``` +![Z2_fusiontrees](img/symmetric_tutorial/Z2_fusiontrees.svg) This diagram should be read from top to bottom, where it represents the fusion of the two uncoupled irreps in the domain to the coupled irrep on the middle line, and the splitting of this coupled irrep to the uncoupled irreps in the codomain. From this our previous statement becomes very clear: the ``ZZ`` operator indeed consists of two distinct two-dimensional matrix blocks, each of which are labeled by the value of the *coupled irrep* on the middle line of each fusion tree. The first block corresponds to the even coupled irrep '0', and acts within the two-dimensional subspace spanned by ``\{\ket{+,+}, \ket{-,-}\}``, while the second block corresponds to the odd coupled irrep '1', and acts within the two-dimensional subspace spanned by ``\{\ket{+,-}, \ket{-,+}\}``. @@ -172,9 +168,7 @@ These can be thought of as generalization of group irreps, and appear in the con Consider a generic fusion tree of the form -```@raw html -
fusiontree
-``` +![fusiontree](img/symmetric_tutorial/fusiontree.svg) which can be used to label a subblock of a `TensorMap` corresponding to a two-site operator. This object should actually be seen as a *pair of fusion trees*. @@ -346,9 +340,7 @@ N \ket{n} &= n \ket{n} It is then a simple observation that these matrix elements are exactly captured by the following ``\mathsf{U}_1`` fusion trees with corresponding subblock values: -```@raw html -
U1_fusiontrees
-``` +![U1_fusiontrees](img/symmetric_tutorial/U1_fusiontrees.svg) This gives us all the information necessary to construct the corresponding `TensorMap`s. We follow the same steps as outlined in the previous example, starting with the construction of the physical space. @@ -404,15 +396,11 @@ This means we can represent ``a^+`` as a `TensorMap(..., V ← V ⊗ A)`, where Similarly, the decrease in occupation number when acting with ``a^-`` can be thought of as the *splitting* of an `U1Irrep(n)` into an `U1Irrep(n - 1)` and an `U1Irrep(1)`, leading to a representation in terms of a `TensorMap(. ., A ⊗ V ← V)`. Based on these observations, we can represent the matrix elements \eqref{eq:bosonopmatel} as subblocks labeled by the ``\mathsf{U}_1`` fusion trees -```@raw html -
bosonops
-``` +![bosonops](img/symmetric_tutorial/bosonops.svg) We can then combine these operators to get the appropriate Hamiltonian terms, -```@raw html -
bosonham
-``` +![bosonham](img/symmetric_tutorial/bosonham.svg) !!! note Although we have made a suggestive distinction between the 'left' and 'right' versions of the operators ``a_L^\pm`` and ``a_R^\pm``, one can actually be obtained from the other by permuting the physical and auxiliary indices of the corresponding `TensorMap`s. @@ -551,9 +539,7 @@ c_1^- c_2^+ \ket{1, 0} = c_1^- c_2^+ c_1^+ \ket{0, 0} = - c_2^+ c_1^- c_1^+ \ket Once we have these matrix elements the hard part is done, and we can straightforwardly associate these to the following ``f\mathbb{Z}_2`` fusion trees with corresponding reduced tensor elements, -```@raw html -
fZ2_fusiontrees
-``` +![fZ2_fusiontrees](img/symmetric_tutorial/fZ2_fusiontrees.svg) Given this information, we can go through the same procedure again to construct ``c^+ c^-``, ``c^- c^+`` and ``N`` operators as `TensorMap`s over ``f\mathbb{Z}_2``-graded vector spaces. @@ -643,9 +629,7 @@ Finally, we show how the more intuitive approach can be used to obtain an elegan Let us recall some basics of representation theory first. Consider a group ``G`` and a corresponding representation space ``V``, such that every element ``g \in G`` can be realized as a unitary operator ``U_g : V \to V``. Let ``h`` be a `TensorMap` whose domain and codomain are given by the tensor product of two of these representation spaces. By definition, the statement that '``h`` is symmetric under ``G``' means that -```@raw html -
symmetric_tensor
-``` +![symmetric_tensor](img/symmetric_tutorial/symmetric_tensor.svg) for every ``g \in G``. If we label the irreducible representations of ``G`` by ``l``, then any representation space can be decomposed into a direct sum of irreducible representations, ``V = \bigoplus_l V^{(l)}``, in such a way that ``U_g`` is block-diagonal where each matrix block is labeled by a particular irrep ``l``. For each irrep space ``V^{(l)}`` we can define an orthonormal basis labeled as ``\ket{l, m}``, where the auxiliary label ``m`` can take ``\text{dim}\left( V^{(l)} \right)`` different values. @@ -663,15 +647,11 @@ This set of coefficients, which can be interpreted as a ``\text{dim}\left( V^{(l These recoupling coefficients turn out to be essential to the structure of symmetric tensors, which can be best understood in the context of the [Wigner-Eckart theorem](https://en.wikipedia.org/wiki/Wigner%E2%80%93Eckart_theorem). This theorem implies that for any [`TensorMap` ``h`` that is symmetric under ``G``](@ref ss_symmetries), its matrix elements in the tensor product irrep basis are given by the product of Clebsch-Gordan coefficients which characterize the coupling of the basis states in the domain and codomain, and a so-called *reduced tensor element* which only depends on the irrep labels. Concretely, the matrix element ``\bra{l_1,m_1} \otimes \bra{l_2,m_2} h \ket{l_3,m_3} \otimes \ket{l_4,m_4}`` is given by -```@raw html -
wignereckart
-``` +![wignereckart](img/symmetric_tutorial/wignereckart.svg) Here, the sum runs over all possible irreps ``k`` in the fusion product ``l_3 \otimes l_4`` and over all basis states ``\ket{k,n}`` of ``V^{(k)}``. The reduced tensor elements ``h_{\text{red}}`` are independent of the basis state labels and only depend on the irrep labels themselves. Each reduced tensor element should be interpreted as being labeled by an irrep fusion tree, -```@raw html -
anotherfusiontree
-``` +![anotherfusiontree](img/symmetric_tutorial/anotherfusiontree.svg) The fusion tree itself in turn implies the Clebsch-Gordan coefficients ``C^{k}_{l_1,l_2}`` and conjugate coefficients ``{C^{\dagger}}_{k}^{l_1,l_2}`` encode the splitting (decomposition) of the coupled basis state ``\ket{k,n}`` to the codomain basis states ``\ket{l_1,m_1} \otimes \ket{l_2,m_2}`` and the coupling of the domain basis states ``\ket{l_3,m_3} \otimes \ket{l_4,m_4}`` to the coupled basis state ``\ket{k,n}`` respectively. The Wigner-Eckart theorem dictates that this structure in terms of Clebsch-Gordan coefficients is necessary to ensure that the corresponding tensor is symmetric. @@ -728,9 +708,7 @@ Given the matrix elements of the operator in the irrep basis, this can in genera A simpler way to achieve the same thing is to make use of the fact that the [Clebsch-Gordan tensors form a complete orthonormal basis](https://en.wikipedia.org/wiki/Clebsch%E2%80%93Gordan_coefficients#Orthogonality_relations) on the coupled space. Indeed, by projecting out the appropriate Clebsch-Gordan coefficients and using their orthogonality relations, we can construct a diagonal operator on each coupled irrep space ``V^{(k)}``. Each of these diagonal operators is proportional to the identity, where the proportionality factor is precisely the reduced tensor element associated to the corresponding irrep fusion tree. -```@raw html -
none2symm
-``` +![none2symm](img/symmetric_tutorial/none2symm.svg) This procedure works for any group symmetry, and all we need are matrix elements of the operator in the irrep basis and the Clebsch-Gordan coefficients. In the following, we demonstrate this explicit procedure for the particular example of ``G = \mathsf{SU}_2``. @@ -882,9 +860,7 @@ In particular, we have for each irrep ``l`` ``` It then follows from Eq. \eqref{eq:casimir_decomp} that the reduced tensor elements of the exchange interaction are completely determined by the eigenvalue of the quadratic Casimir on the uncoupled and coupled irreps. Indeed, to each fusion tree we can associate a well-defined value -```@raw html -
SU2_fusiontrees
-``` +![SU2_fusiontrees](img/symmetric_tutorial/SU2_fusiontrees.svg) This gives us all we need to directly construct the exchange interaction as a symmetric `TensorMap`, ```@example symmetric_tutorial V = SU2Space(1 => 1) @@ -948,9 +924,7 @@ For any ``N``, the [quadratic Casimir](https://en.wikipedia.org/wiki/Casimir_ele ``` commutes with all ``\mathsf{SU}_N`` generators, meaning it has a well defined eigenvalue in each irrep. This observation then immediately given the reduced tensor elements of the exchange interaction as -```@raw html -
SUN_fusiontrees
-``` +![SUN_fusiontrees](img/symmetric_tutorial/SUN_fusiontrees.svg) Using these to directly construct the corresponding symmetric `TensorMap` is much simpler than going through the explicit projection procedure using Clebsch-Gordan coefficients. For the particular example of ``\mathsf{SU}_3``, the generators are given by ``T^k = \frac{1}{2} \lambda^k`` , where ``\lambda^k`` are the [Gell-Mann matrices](https://en.wikipedia.org/wiki/Clebsch%E2%80%93Gordan_coefficients_for_SU(3)#Generators_of_the_Lie_algebra). @@ -1018,9 +992,7 @@ which favors neighboring anyons fusing to the vacuum can be constructed as a `Te V = Vect[FibonacciAnyon](:τ => 1) ``` and assigning the following nonzero subblock value to the two-site fusion trees -```@raw html -
Fib_fusiontrees
-``` +![Fib_fusiontrees](img/symmetric_tutorial/Fib_fusiontrees.svg) This allows us to define this, at first sight, exotic and complicated Hamiltonian in a few simple lines of code, ```@example symmetric_tutorial h = ones(V ⊗ V ← V ⊗ V) diff --git a/docs/src/man/fusiontrees.md b/docs/src/man/fusiontrees.md index 57fc7aa3b..15c2d5ceb 100644 --- a/docs/src/man/fusiontrees.md +++ b/docs/src/man/fusiontrees.md @@ -31,9 +31,7 @@ Hence, these last two sections can safely be skipped. To couple or fuse the different sectors together into a single block sector, we can sequentially fuse together two sectors into a single coupled sector, which is then fused with the next uncoupled sector, using the splitting tensors ``X_{a,b}^{c,μ} : R_c → R_a ⊗ R_b`` and their adjoints. This amounts to the canonical choice of our tensor product, and for a given tensor mapping from ``(((W_1 ⊗ W_2) ⊗ W_3) ⊗ … )⊗ W_{N_2})`` to ``(((V_1 ⊗ V_2) ⊗ V_3) ⊗ … )⊗ V_{N_1})``, the corresponding fusion and splitting trees take the form -```@raw html -double fusion tree -``` +![double fusion tree](img/tree-simple.svg) for the specific case ``N_1 = 4`` and ``N_2 = 3``. We can separate this tree into the fusing part ``(b_1 ⊗ b_2) ⊗ b_3 → c`` and the splitting part ``c→(((a_1 ⊗ a_2) ⊗ a_3) ⊗ a_4)``. @@ -50,9 +48,7 @@ This distinction is however important, when certain uncoupled sectors in the fus We use the isomorphisms ``Z_a : R_a^* → R_{\bar{a}}`` and its adjoint ``Z_a^† : R_{\bar{a}} → R_a^*``, as introduced in the section on [topological data of a fusion category](@ref ss_topologicalfusion), to build fusion and splitting trees that take the distinction between irreps and their conjugates into account. Hence, in the previous example, if e.g. the first and third space in the codomain and the second space in the domain of the tensor were dual spaces, the actual pair of splitting and fusion tree would look as -```@raw html -extended double fusion tree -``` +![extended double fusion tree](img/tree-extended.svg) The presence of these isomorphisms will be important when we start to bend lines, to move uncoupled sectors from the incoming to the outgoing part of the fusion-splitting tree. Note that we can still represent the fusion tree as the adjoint of a corresponding splitting tree, because we also use the adjoint of the ``Z`` isomorphisms in the splitting part, and the ``Z`` isomorphism in the fusion part. @@ -105,9 +101,7 @@ The first operation we discuss is an elementary braid of two neighbouring sector Because these two sectors do not appear on the same fusion vertex, some recoupling is necessary. The following represents two different ways to compute the result of such a braid as a linear combination of new fusion trees in canonical order: -```@raw html -artin braid -``` +![artin braid](img/tree-artinbraid.svg) While the upper path is the most intuitive, it requires two recouplings or F-moves (one forward and one reverse). On the other hand, the lower path requires only one (reverse) F- move, and two R-moves. @@ -129,9 +123,7 @@ The permutation is decomposed into swaps between neighbouring sectors, and when This interface does not allow to specify the most general braid, and in particular will never wind one line around another, but can be used as a more general building block for arbitrary braids than the elementary Artin generators. A graphical example makes this probably more clear, i.e for `levels = (1, 2, 3, 4, 5)` and `permutation = (5, 3, 1, 4, 2)`, the corresponding braid is given by -```@raw html -braid interface -``` +![braid interface](img/tree-braidinterface.svg) that is, the first sector or space goes to position 3, and crosses over all other lines, because it has the lowest level (i.e. think of level as depth in the third dimension), and so forth. We sketch this operation both as a general braid on the left hand side, and as a particular composition of Artin braids on the right hand side. @@ -145,9 +137,7 @@ Other manipulations which are sometimes needed are * [`insertat(f1::FusionTree{I, N₁}, i::Int, f2::FusionTree{I, N₂})`](@ref TensorKit.insertat) : inserts a fusion tree `f2` at the `i`th uncoupled sector of fusion tree `f1` (this requires that the coupled sector `f2` matches with the `i`th uncoupled sector of `f1`, and that `!f1.isdual[i]`, i.e. that there is no ``Z``-isomorphism on the `i`th line of `f1`), and recouple this into a linear combination of trees in canonical order, with `N₁ + N₂ - 1` uncoupled sectors, i.e. diagrammatically for `i = 3` -```@raw html -insertat -``` +![insertat](img/tree-insertat.svg) * [`split(f::FusionTree{I, N}, M::Int)`](@ref TensorKit.split) : splits a fusion tree `f` into two trees `f1` and `f2`, such that `f1` has the first `M` uncoupled sectors of `f`, and `f2` the remaining `N - M`. This function is type stable if `M` is a compile time constant. @@ -155,9 +145,7 @@ Other manipulations which are sometimes needed are `split` is the inverse of `join`: `f == join(split(f, M)...)` holds for all valid `M`. Diagrammatically, for `M = 4`, the function `split` returns -```@raw html -split -``` +![split](img/tree-split.svg) * [`join(f₁::FusionTree{I, N₁}, f₂::FusionTree{I, N₂})`](@ref TensorKit.join) : connects the coupled sector of `f₁` to the first uncoupled sector of `f₂`, producing a single tree with `N₁ + N₂ - 1` uncoupled sectors. Requires `f₁.coupled == f₂.uncoupled[1]` and `!f₂.isdual[1]`. @@ -167,9 +155,7 @@ Other manipulations which are sometimes needed are This is a simple application of `insertat`. Diagrammatically, this operation is represented as: -```@raw html -merge -``` +![merge](img/tree-merge.svg) ## Manipulations on a splitting - fusion tree pair @@ -205,9 +191,7 @@ We now discuss how to actually bend lines, and thus, move sectors from the incom Hereby, we exploit the relations between the (co)evaluation (exact pairing) and the fusion tensors, discussed in [topological data of a fusion category](@ref ss_topologicalfusion). The main ingredient that we need is summarized in -```@raw html -line bending -``` +![line bending](img/tree-linebending.svg) We will only need the B-symbol and not the A-symbol. Applying the left evaluation on the second sector of a splitting tensor thus yields a linear combination of fusion tensors (when `FusionStyle(I) == GenericFusion()`, or just a scalar times the corresponding fusion tensor otherwise), with corresponding ``Z`` ismorphism. @@ -217,9 +201,7 @@ However, we have to be careful if we bend a line on which a ``Z`` isomorphism (o Indeed, it is exactly for this operation that we explicitly need to take the presence of these isomorphisms into account. Indeed, we obtain the relation -```@raw html -dual line bending -``` +![dual line bending](img/tree-linebending2.svg) Hence, bending an `isdual` sector from the splitting tree to the fusion tree yields an additional Frobenius-Schur factor, and of course leads to a normal sector (which is no longer `isdual` and does thus not come with a ``Z``-isomorphism) on the fusion side. We again use the adjoint of this relation to bend an `isdual` sector from the fusion tree to the splitting tree. @@ -233,9 +215,7 @@ This return values are correctly inferred if `N` is a compile time constant. Graphically, for `N₁ = 4`, `N₂ = 3`, `N = 2` and some particular choice of `isdual` in both the fusion and splitting tree: -```@raw html -repartition -``` +![repartition](img/tree-repartition.svg) The result is returned as a `Pair`: for a `FusionTreePair` input, this is a `Pair{FusionTreePair, <:Number}`; for a `FusionTreeBlock` input, a `Pair{FusionTreeBlock, Matrix}`. Note that the summation is only over the ``κ_j`` labels, such that, in the case of `FusionStyle(I) isa UniqueFusion`, the linear combination simplifies to a single term with a scalar coefficient. diff --git a/docs/src/man/symmetries.md b/docs/src/man/symmetries.md index 21145b41b..0ee9c9e4d 100644 --- a/docs/src/man/symmetries.md +++ b/docs/src/man/symmetries.md @@ -95,9 +95,7 @@ Note that there are no multiplicity labels in that particular F-symbol as ``N^{a There is a graphical representation associated with the fusion tensors and their manipulations, which we summarize here: -```@raw html -summary -``` +![summary](img/tree-summary.svg) We refer to the appendix on [category theory](@ref s_categories), and in particular the section on [topological data of a unitary fusion category](@ref ss_topologicalfusion) for further details. diff --git a/docs/src/man/tensormanipulations.md b/docs/src/man/tensormanipulations.md index 15285fd78..697db9311 100644 --- a/docs/src/man/tensormanipulations.md +++ b/docs/src/man/tensormanipulations.md @@ -117,9 +117,7 @@ Another operation that belongs under index manipulations is taking the `transpos Note that `transpose(t)` is not simply equal to reshuffling domain and codomain with `braid(t, (1:(N₁+N₂)...), reverse(domainind(tsrc)), reverse(codomainind(tsrc))))`. Indeed, the graphical representation (where we draw the codomain and domain as a single object), makes clear that this introduces an additional (inverse) twist, which is then compensated in the `transpose` implementation. -```@raw html -transpose -``` +![transpose](img/tensor-transpose.svg) In categorical language, the reason for this extra twist is that we use the left coevaluation ``η``, but the right evaluation ``\tilde{ϵ}``, when repartitioning the indices between domain and codomain. @@ -247,9 +245,7 @@ As a consequence, the diagram, or the morphism it represents, is completely spec If we also compose the resulting morphisms with coevaluations so that it has a trivial domain, we just have one type of unconnected lines, henceforth called open indices. We sketch such a rearrangement in the following picture -```@raw html -tensor unitary -``` +![tensor unitary](img/tensor-bosoniccontraction.svg) Hence, we can now specify such a tensor diagram, henceforth called a tensor contraction or also tensor network, using a one-dimensional syntax that mimicks [abstract index notation](https://en.wikipedia.org/wiki/Abstract_index_notation) and specifies which indices are connected by the evaluation map using Einstein's summation conventation. Indeed, for `BraidingStyle(I) == Bosonic()`, such a tensor contraction can take the same format as if all tensors were just multi-dimensional arrays. @@ -299,9 +295,7 @@ Firstly, the order of the tensors appearing on the right hand side is irrelevant As the latter is trivial, it can be omitted, and we just use the same rules to evaluate the newly ordered tensor network. For the particular case of matrix-matrix multiplication, which also captures more general settings by appropriotely combining spaces into a single line, we indeed find -```@raw html -tensor contraction reorder -``` +![tensor contraction reorder](img/tensor-contractionreorder.svg) or thus, the following two lines of code yield the same result ```julia diff --git a/docs/src/man/tensors.md b/docs/src/man/tensors.md index 2921e5f1b..574ca3466 100644 --- a/docs/src/man/tensors.md +++ b/docs/src/man/tensors.md @@ -84,9 +84,7 @@ However, in this case the basis transform to the block diagonal representation i Indeed, let us denote the fusion trees `f₁ ∈ fusiontrees((a1, …, aN₁), c)` as ``X^{a_1, …, a_{N₁}}_{c,α}`` where ``α = (e_1, …, e_{N_1-2}; μ₁, …, μ_{N_1-1})`` is a collective label for the internal sectors `e` and the vertex degeneracy labels `μ` of a generic fusion tree, as discussed in the [corresponding section](@ref ss_fusiontrees). The tensor is then represented as -```@raw html -tensor storage -``` +![tensor storage](img/tensor-storage.svg) In this diagram, we have indicated how the tensor map can be rewritten in terms of a block diagonal matrix with a unitary matrix on its left and another unitary matrix (if domain and codomain are different) on its right. So the left and right matrices should actually have been drawn as squares. @@ -102,9 +100,7 @@ Similarly, the dashed vertical lines define the border between regions of differ To understand this better, we need to understand the basis transformation, e.g. on the left (codomain) side. In more detail, it is given by -```@raw html -tensor unitary -``` +![tensor unitary](img/tensor-unitary.svg) Indeed, remembering that ``V_i = ⨁_{a_i} R_{a_i} ⊗ ℂ^{n_{a_i}}`` with ``R_{a_i}`` the representation space on which irrep ``a_i`` acts (with dimension ``\mathrm{dim}(a_i)``), we find