diff --git a/README.md b/README.md index 3b215cd..96d36cd 100644 --- a/README.md +++ b/README.md @@ -23,28 +23,28 @@ julia> basis = symmetrized_basis(zbasis(9, 4), Flip(9), 0, Shift(9), 0); julia> state = normalize!(ones(2^9)); # initial state - all up in x direction julia> @btime symm_state = symmetrize_state(state, basis) - 765.253 Ξs (7781 allocations: 727.29 KiB) -14-element Vector{ComplexF64}: - 0.18750000000000006 + 0.0im - 0.18750000000000006 + 0.0im - 0.18750000000000006 + 0.0im - 0.18750000000000006 + 0.0im - 0.18750000000000006 + 0.0im - 0.18750000000000006 + 0.0im - 0.18750000000000006 + 0.0im - 0.18750000000000006 + 0.0im - 0.18750000000000006 + 0.0im - 0.18750000000000006 + 0.0im - 0.18750000000000006 + 0.0im - 0.18750000000000006 + 0.0im - 0.18750000000000006 + 0.0im - 0.18750000000000006 + 0.0im +637.317 Ξs (4245 allocations: 646.05 KiB) +14-element Vector{Float64}: + 0.18749999999999994 + 0.18749999999999994 + 0.18749999999999994 + 0.18749999999999994 + 0.18749999999999994 + 0.18749999999999994 + 0.18749999999999994 + 0.18749999999999994 + 0.18749999999999994 + 0.18749999999999994 + 0.18749999999999994 + 0.18749999999999994 + 0.18749999999999994 + 0.18749999999999994 julia> operator = kron([1 0; 0 -1], kron([1 0; 0 -1], I(2^7))); # operator Z ⊗ Z ⊗ 𝟙 ⊗ .. ⊗ 𝟙 julia> @btime symm_op = symmetrize_operator(operator, basis) - 41.828 ms (922891 allocations: 29.66 MiB) -14×14 Matrix{ComplexF64}: + 1.096 ms (4248 allocations: 703.76 KiB) +14×14 Matrix{Float64}: [...] ``` @@ -62,6 +62,8 @@ The symmetry operations supported are: where `N` denotes the number of spins in the system and their positions should be given as a Julian index, i.e. in the range `1:N`. +To get the tranformation matrix to the symmetrized subspace just use `transformationmatrix(symmetrized_basis)`. + **Note:** The projection on a specific magnetization block is applied first. Thus if you have spin flip symmetry and restrict to a magnetization block, your symmetrized basis states look like "|↑..↑âŸĐ Âą |↓..↑âŸĐ". So in this case you effectively specified S_z^2 and parity. ## User-defined symmetries diff --git a/src/SpinSymmetry.jl b/src/SpinSymmetry.jl index 69c4741..abbb1ab 100644 --- a/src/SpinSymmetry.jl +++ b/src/SpinSymmetry.jl @@ -1,10 +1,10 @@ module SpinSymmetry -import SparseArrays +using SparseArrays: sparse export Flip, Shift, Swap, SpatialReflection, GenericSymmetry export zbasis, FullZBasis, ZBlockBasis, basissize -export SymmetrizedBasis, symmetrized_basis, symmetrize_state, symmetrize_operator +export SymmetrizedBasis, symmetrized_basis, symmetrize_state, symmetrize_operator, transformationmatrix include("abstract.jl") include("basis.jl") diff --git a/src/basis.jl b/src/basis.jl index e4c6e72..708aac1 100644 --- a/src/basis.jl +++ b/src/basis.jl @@ -162,7 +162,7 @@ function symmetrize_state(state, basis::SymmetrizedBasis) throw(ArgumentError("""State has wrong size. Expected $(2^basis.basis.N), got: $(length(state))""")) end - return _transformationmatrix(basis) * state + return transformationmatrix(basis) * state # inds = _indices(basis.basis) # factors = _phase_factors(inds, basis.symmetries, basis.sectors) # use_real = all(d -> all(denominator.(values(d)) .<= 2), factors) @@ -200,7 +200,7 @@ function symmetrize_operator(operator, basis::SymmetrizedBasis) Expected $(2^basis.basis.N)x$(2^basis.basis.N), got: $(size(operator))""")) end - trafo = _transformationmatrix(basis) + trafo = transformationmatrix(basis) return trafo * operator * trafo' @@ -303,8 +303,7 @@ function _phase_factors(inds, symms, sectors) output end -SparseArrays.sparse(symmbasis::SymmetrizedBasis) = _transformationmatrix(symmbasis) -function _transformationmatrix(symmbasis) +function transformationmatrix(symmbasis) inds = SpinSymmetry._indices(symmbasis.basis) phases = SpinSymmetry._phase_factors(inds, symmbasis.symmetries, symmbasis.sectors) @@ -326,5 +325,5 @@ function _transformationmatrix(symmbasis) index += 1 end end - SparseArrays.sparse(I,J,V,length(phases), 2^(symmbasis.basis.N)) + sparse(I,J,V,length(phases), 2^(symmbasis.basis.N)) end