diff --git a/Project.toml b/Project.toml index 224b4b5..25f1f8c 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "FusionTensors" uuid = "e16ca583-1f51-4df0-8e12-57d32947d33e" authors = ["ITensor developers and contributors"] -version = "0.5.9" +version = "0.5.10" [deps] Accessors = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" diff --git a/src/fusiontensor/linear_algebra_interface.jl b/src/fusiontensor/linear_algebra_interface.jl index b63bc03..2d2a7ca 100644 --- a/src/fusiontensor/linear_algebra_interface.jl +++ b/src/fusiontensor/linear_algebra_interface.jl @@ -33,13 +33,20 @@ function LinearAlgebra.mul!( return C end -function LinearAlgebra.norm(ft::FusionTensor) +function LinearAlgebra.norm(ft::FusionTensor, p::Real=2) m = data_matrix(ft) row_sectors = sectors(codomain_axis(ft)) - n2 = sum(eachblockstoredindex(m); init=zero(real(eltype(ft)))) do b - return quantum_dimension(row_sectors[Int(first(Tuple(b)))]) * norm(m[b])^2 + np = sum(eachblockstoredindex(m); init=zero(real(eltype(ft)))) do b + return quantum_dimension(row_sectors[Int(first(Tuple(b)))]) * norm(m[b], p)^p end - return sqrt(n2) + return np^(1 / p) +end + +LinearAlgebra.normalize(ft::FusionTensor, p::Real=2) = ft / norm(ft, p) + +function LinearAlgebra.normalize!(ft::FusionTensor, p::Real=2) + data_matrix(ft) ./= norm(ft, p) + return ft end function LinearAlgebra.tr(ft::FusionTensor) @@ -49,18 +56,3 @@ function LinearAlgebra.tr(ft::FusionTensor) return quantum_dimension(row_sectors[Int(first(Tuple(b)))]) * tr(m[b]) end end - -function LinearAlgebra.qr(ft::FusionTensor) - qmat, rmat = block_qr(data_matrix(ft)) - qtens = FusionTensor(qmat, codomain_axes(ft), (axes(qmat, 2),)) - rtens = FusionTensor(rmat, (axes(rmat, 1),), domain_axes(ft)) - return qtens, rtens -end - -function LinearAlgebra.svd(ft::FusionTensor) - umat, s, vmat = block_svd(data_matrix(ft)) - utens = FusionTensor(umat, codomain_axes(ft), (axes(umat, 2),)) - stens = FusionTensor(s, (axes(umat, 1),), (axes(vmat, 2),)) - vtens = FusionTensor(vmat, (axes(vmat, 1),), domain_axes(ft)) - return utens, stens, vtens -end diff --git a/test/test_linear_algebra.jl b/test/test_linear_algebra.jl index 669457f..9b9f66c 100644 --- a/test/test_linear_algebra.jl +++ b/test/test_linear_algebra.jl @@ -1,11 +1,11 @@ -using LinearAlgebra: norm, tr +using LinearAlgebra: norm, normalize, normalize!, tr using Test: @test, @testset using BlockArrays: BlockArrays using BlockSparseArrays: BlockSparseArrays using FusionTensors: FusionTensor, to_fusiontensor -using GradedArrays: SU2, TrivialSector, U1, dual, gradedrange +using GradedArrays: O2, SU2, TrivialSector, U1, dual, gradedrange include("setup.jl") @@ -20,12 +20,31 @@ include("setup.jl") g0 = gradedrange([TrivialSector() => 2]) gu1 = gradedrange([U1(1) => 1, U1(-1) => 1]) + go2 = gradedrange([O2(1 / 2) => 1]) gsu2 = gradedrange([SU2(1 / 2) => 1]) - for g in [g0, gu1, gsu2] + for g in [g0, gu1, go2, gsu2] ft = to_fusiontensor(sdst, (g, g), (dual(g), dual(g))) @test isnothing(check_sanity(ft)) @test norm(ft) ≈ √3 / 2 + @test norm(ft, 2) ≈ √3 / 2 + @test norm(ft, 2.0) ≈ √3 / 2 @test isapprox(tr(ft), 0; atol=eps(Float64)) + + ft2 = normalize(ft) + @test norm(ft2) ≈ 1.0 + @test norm(ft) ≈ √3 / 2 # unaffected by normalize + @test ft ≈ √3 / 2 * ft2 + normalize!(ft) + @test norm(ft) ≈ 1.0 + end + + for g in [g0, gu1] + ft = to_fusiontensor(sdst, (g, g), (dual(g), dual(g))) + @test norm(ft, 1) ≈ 2.0 + end + for g in [go2, gsu2] + ft = to_fusiontensor(sdst, (g, g), (dual(g), dual(g))) + @test norm(ft, 1) ≈ 1.5 end end