diff --git a/NDTensors/src/blocksparse/fermions.jl b/NDTensors/src/blocksparse/fermions.jl index 4acc85fe8e..3fdb96fd9c 100644 --- a/NDTensors/src/blocksparse/fermions.jl +++ b/NDTensors/src/blocksparse/fermions.jl @@ -1,4 +1,5 @@ block_parity(i, block) = 0 +block_sign(i, block) = 1 right_arrow_sign(i, block) = 1 left_arrow_sign(i, block) = 1 diff --git a/NDTensors/src/blocksparse/linearalgebra.jl b/NDTensors/src/blocksparse/linearalgebra.jl index 1c8732e05c..2835d262c7 100644 --- a/NDTensors/src/blocksparse/linearalgebra.jl +++ b/NDTensors/src/blocksparse/linearalgebra.jl @@ -184,9 +184,12 @@ function LinearAlgebra.svd(T::BlockSparseMatrix{ElT}; kwargs...) where {ElT} # This sign (sVP) accounts for the fact that # V is transposed, i.e. the index connecting to S # is the second index: - sVP = using_auto_fermion() ? -block_parity(vind, blockV[2]) : 1 + sVP = 1 + if using_auto_fermion() + sVP = -block_sign(vind, blockV[2]) + end - if (sV * sV) == -1 + if (sV * sVP) == -1 blockview(V, blockV) .= -Vb else blockview(V, blockV) .= Vb diff --git a/src/physics/fermions.jl b/src/physics/fermions.jl index 17270dfb6c..262721746e 100644 --- a/src/physics/fermions.jl +++ b/src/physics/fermions.jl @@ -107,6 +107,8 @@ end NDTensors.block_parity(i::QNIndex, block::Integer) = fparity(qn(i, block)) +NDTensors.block_sign(i::QNIndex, block::Integer) = 2 * NDTensors.block_parity(i, block) - 1 + function NDTensors.right_arrow_sign(i::QNIndex, block::Integer) !using_auto_fermion() && return 1 if dir(i) == Out && NDTensors.block_parity(i, block) == 1 diff --git a/test/base/test_fermions.jl b/test/base/test_fermions.jl index 2a6ecefb2f..fe03c06713 100644 --- a/test/base/test_fermions.jl +++ b/test/base/test_fermions.jl @@ -699,7 +699,7 @@ import ITensors: Out, In T = ITensor(s[1], dag(s[2])) T[2, 2] = 1.0 U, S, V, spec, u, v = svd(T, s[1]) - @test_broken norm(T - U * S * V) ≈ 0 + @test norm(T - U * S * V) ≈ 0 UU = dag(U) * prime(U, u) @test norm(UU - id(u)) ≈ 0 VV = dag(V) * prime(V, v) @@ -711,7 +711,7 @@ import ITensors: Out, In T = ITensor(dag(s[1]), dag(s[2])) T[1, 2] = 1.0 U, S, V, spec, u, v = svd(T, s[1]) - @test_broken norm(T - U * S * V) ≈ 0 + @test norm(T - U * S * V) ≈ 0 UU = dag(U) * prime(U, u) @test norm(UU - id(u)) ≈ 0 VV = dag(V) * prime(V, v)