diff --git a/README.md b/README.md index e4ae5d4e2..4f85fbdab 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ breaking changes: 3. The constructors for creating tensors with randomly initialised data, of the form `TensorMap(randn, T, codomain ← domain)`, are being replaced with `randn(T, codomain ← domain)`. Hence, we overload the methods `rand` and `randn` from - Base (actually, Random, and also `Random.randexp`) and mimick the `Array` constructors, + Base (actually, Random, and also `Random.randexp`) and mimic the `Array` constructors, relying on the fact that we use spaces instead of integers to characterise the tensor structure. As with integer-based `rand` and `randn`, a custom random number generator from the `Random` module can be passed as the first argument, and the scalar type `T` is @@ -134,7 +134,7 @@ Major non-breaking changes include: To export `TensorMap` data from TensorKit.jl v0.12.7 or earlier, you should first export the data there in a format that is explicit about how tensor data is associated with the -structural part of the tensor, i.e. the splitting and fusion tree pairs. Therefore, on the +structural part of the tensor, i.e. the splitting and fusion tree pairs. Therefore, on the older version of TensorKit.jl, use the following code to save the data ```julia diff --git a/docs/src/appendix/symmetric_tutorial.md b/docs/src/appendix/symmetric_tutorial.md index 5aa4cc923..0c0b45413 100644 --- a/docs/src/appendix/symmetric_tutorial.md +++ b/docs/src/appendix/symmetric_tutorial.md @@ -241,11 +241,11 @@ dim(V, Z2Irrep(1)) Given this physical space, we can initialize the ``ZZ`` operator as an empty `TensorMap` with the appropriate structure. ```@example symmetric_tutorial ZZ = zeros(ComplexF64, V ⊗ V ← V ⊗ V) -``` +``` To assess the underlying structure of a symmetric tensor, it is often useful to inspect its [`subblocks`](@ref subblocks), ```@example symmetric_tutorial subblocks(ZZ) -``` +``` While all entries are zero, we see that all eight valid fusion trees with two incoming irreps and two outgoing irreps [of the type above](fusiontree) are listed with their corresponding subblock data. Each of these subblocks is an array of shape ``(1, 1, 1, 1)`` since each irrep occurring in the space ``V`` has degeneracy 1. Using the [`fusiontrees`](@ref) method and the fact that we can index a `TensorMap` using a splitting/fusion tree pair, we can now fill in the nonzero subblocks of the operator by observing that the ``ZZ`` operator flips the irreps of the uncoupled charges in the domain with respect to the codomain, as shown in the diagrams above. @@ -652,7 +652,7 @@ For each irrep space ``V^{(l)}`` we can define an orthonormal basis labeled as ` Since we know that tensors are multilinear maps over tensor product spaces, it is natural to consider the tensor product of representation spaces in more detail. [From the representation theory of groups](https://en.wikipedia.org/wiki/Tensor_product_of_representations#Clebsch%E2%80%93Gordan_theory), it is known that the product of two irreps can in turn be decomposed into a direct sum of irreps, ``V^{(l_1)} \otimes V^{(l_2)} \cong \bigoplus_{k} V^{(k)}``. -The precise nature of this decomposition, also refered to as the *Clebsch-Gordan problem*, is given by the so-called *Clebsch-Gordan coefficients*, which we will denote as ``C^{k}_{l_1,l_2}``. +The precise nature of this decomposition, also referred to as the *Clebsch-Gordan problem*, is given by the so-called *Clebsch-Gordan coefficients*, which we will denote as ``C^{k}_{l_1,l_2}``. This set of coefficients, which can be interpreted as a ``\text{dim}\left( V^{(l_1)} \right) \times \text{dim}\left( V^{(l_2)} \right) \times \text{dim}\left( V^{(k)} \right)`` array, encodes how a basis state ``\ket{k,n} \in V^{(k)}`` corresponding to some term in the direct sum can be decomposed into a linear combination of basis vectors ``\ket{l_1,m_1} \otimes \ket{l_2,m_2}`` of the tensor product space: ```math \begin{equation} @@ -790,7 +790,7 @@ In our current case of a spin-``1`` physical space, we have ``l_1 = l_2 = l_3 = The reduced tensor element for a given ``k`` can be implemented in the following way: ```@example symmetric_tutorial function get_reduced_element(k::SU2Irrep) - # construct Clebsch-Gordan coefficients for coupling 1 ⊗ 1 to k + # construct Clebsch-Gordan coefficients for coupling 1 ⊗ 1 to k f = fusiontensor(SU2Irrep(1), SU2Irrep(1), k)[:, :, :, 1] # project out diagonal matrix on coupled irrep space @tensor reduced_matrix[-1; -2] := conj(f[1 2; -1]) * SS_arr[1 2; 3 4] * f[3 4; -2] @@ -873,7 +873,7 @@ First, we rewrite the exchange interaction in the following way: \end{equation} ``` Here, ``\vec{S}_i`` and ``\vec{S}_j`` are spin operators on the physical irrep, while the total spin operator ``\vec{S}_i + \vec{S}_j`` can be decomposed onto the different coupled irreps ``k``. -It is a well known fact that the quadratic sum of the generators of ``\mathsf{SU}_2``, often refered to as the [*quadratic Casimir*](https://en.wikipedia.org/wiki/Representation_theory_of_SU(2)#The_Casimir_element), commutes with all generators. +It is a well known fact that the quadratic sum of the generators of ``\mathsf{SU}_2``, often referred to as the [*quadratic Casimir*](https://en.wikipedia.org/wiki/Representation_theory_of_SU(2)#The_Casimir_element), commutes with all generators. By [Schur's lemma](https://en.wikipedia.org/wiki/Schur%27s_lemma), it must then act proportionally to the identity on every irrep, where the corresponding eigenvalue is determined by the spin irrep label. In particular, we have for each irrep ``l`` ```math @@ -953,7 +953,7 @@ This observation then immediately gives the reduced tensor elements of the excha 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). -Each irrep can be labeled as ``l = D(p,q)`` where ``p`` and ``q`` are refered to as the *Dynkin labels*. +Each irrep can be labeled as ``l = D(p,q)`` where ``p`` and ``q`` are referred to as the *Dynkin labels*. The eigenvalue of the quadratic Casimir for a given irrep is given by [Freudenthal's formula](https://en.wikipedia.org/wiki/Weyl_character_formula#Freudenthal's_formula), ```math \Omega(D(p,q)) = \frac{1}{3} (p^2 + q^2 + 3p + 3q + pq). diff --git a/docs/src/man/fusiontrees.md b/docs/src/man/fusiontrees.md index 56b6b2618..7797bc8bd 100644 --- a/docs/src/man/fusiontrees.md +++ b/docs/src/man/fusiontrees.md @@ -248,7 +248,7 @@ The interface provided for this is given by where we now have splitting tree `f1` with `N₁` outgoing sectors, a fusion tree `f2` with `N₂` incoming sectors, `levels1` and `levels2` assign a level or depth to the corresponding uncoupled sectors in `f1` and `f2`, and we represent the new configuration as a pair `p1` and `p2`. Together, `(p1..., p2...)` represents a permutation of length `N₁ + N₂ = N₁′ + N₂′`, where `p1` indicates which of the original sectors should appear as outgoing sectors in the new splitting tree and `p2` indicates which appear as incoming sectors in the new fusion tree. Hereto, we label the uncoupled sectors of `f1` from `1` to `N₁`, followed by the uncoupled sectors of `f2` from `N₁ + 1` to `N₁ + N₂`. -Note that simply repartitioning the splitting and fusion tree such that e.g. all sectors appear in the new splitting tree (i.e. are outgoing), amounts to chosing `p1 = (1,..., N₁, N₁ + N₂, N₁ + N₂ - 1, ... , N₁ + 1)` and `p2 = ()`, because the duality isomorphism reverses the order of the tensor product. +Note that simply repartitioning the splitting and fusion tree such that e.g. all sectors appear in the new splitting tree (i.e. are outgoing), amounts to choosing `p1 = (1,..., N₁, N₁ + N₂, N₁ + N₂ - 1, ... , N₁ + 1)` and `p2 = ()`, because the duality isomorphism reverses the order of the tensor product. This routine is implemented by indeed first making all sectors outgoing using the `repartition` function discussed above, such that only splitting trees remain, then braiding those using the routine from the previous subsection such that the new outgoing sectors appear first, followed by the new incoming sectors (in reverse order), and then again invoking the `repartition` routine to bring everything in final form. The result is again returned as a `Pair`, with the same conventions as for `repartition`. diff --git a/docs/src/man/sectors.md b/docs/src/man/sectors.md index af0621285..156a457cc 100644 --- a/docs/src/man/sectors.md +++ b/docs/src/man/sectors.md @@ -9,7 +9,7 @@ using TensorKit using TensorKit.TensorKitSectors ``` -The first ingredient in order to define and construct symmetric tensors, is a framework to define symmetry sectors and their assocated fusion rules and topological data. +The first ingredient in order to define and construct symmetric tensors, is a framework to define symmetry sectors and their associated fusion rules and topological data. [TensorKitSectors.jl](https://github.com/QuantumKitHub/TensorKitSectors.jl) defines an abstract supertype `Sector` that all sectors will be subtypes of ```@docs; canonical=false diff --git a/docs/src/man/tensors.md b/docs/src/man/tensors.md index 3482ddc00..7aa61f6fe 100644 --- a/docs/src/man/tensors.md +++ b/docs/src/man/tensors.md @@ -432,8 +432,7 @@ t[f1,f2] There are no custom or dedicated methods for reading, writing or storing `TensorMap`s, however, there is the possibility to convert a `t::AbstractTensorMap` into a `Dict`, simply as `convert(Dict, t)`. The backward conversion `convert(TensorMap, dict)` will return a tensor that is equal to `t`, i.e. `t == convert(TensorMap, convert(Dict, t))`. -This conversion relies on that the string represenation of objects such as `VectorSpace`, `FusionTree` or `Sector` should be such that it represents valid code to recreate the object. +This conversion relies on that the string representation of objects such as `VectorSpace`, `FusionTree` or `Sector` should be such that it represents valid code to recreate the object. Hence, we store information about the domain and codomain of the tensor, and the sector associated with each data block, as a `String` obtained with `repr`. This provides the flexibility to still change the internal structure of such objects, without this breaking the ability to load older data files. The resulting dictionary can then be stored using any of the provided Julia packages such as [JLD.jl](https://github.com/JuliaIO/JLD.jl), [JLD2.jl](https://github.com/JuliaIO/JLD2.jl), [BSON.jl](https://github.com/JuliaIO/BSON.jl), [JSON.jl](https://github.com/JuliaIO/JSON.jl), ... - diff --git a/src/planar/analyzers.jl b/src/planar/analyzers.jl index 41585e8c1..f48031b01 100644 --- a/src/planar/analyzers.jl +++ b/src/planar/analyzers.jl @@ -26,7 +26,7 @@ function get_possible_planar_indices(ex) return inds[keep] elseif isexpr(ex, :call) && ex.args[1] == :* length(ex.args) == 3 || - error("unexpected error occured: contraction should have been decomposed into tree by now") + error("unexpected error occurred: contraction should have been decomposed into tree by now") inds1 = get_possible_planar_indices(ex.args[2]) inds2 = get_possible_planar_indices(ex.args[3]) inds = Any[]