Skip to content

Commit 1903b01

Browse files
committed
Update and use MatrixAlgebraKit.isisometry
Correctly implement `isisometry`
1 parent d79bd90 commit 1903b01

File tree

4 files changed

+20
-39
lines changed

4 files changed

+20
-39
lines changed

src/TensorKit.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export mul!, lmul!, rmul!, adjoint!, pinv, axpy!, axpby!
7373
export leftorth, rightorth, leftnull, rightnull, leftpolar, rightpolar,
7474
leftorth!, rightorth!, leftnull!, rightnull!, leftpolar!, rightpolar!,
7575
tsvd!, tsvd, eigen, eigen!, eig, eig!, eigh, eigh!, exp, exp!,
76-
isposdef, isposdef!, ishermitian, isisometry, sylvester, rank, cond
76+
isposdef, isposdef!, ishermitian, isisometry, isunitary, sylvester, rank, cond
7777
export braid, braid!, permute, permute!, transpose, transpose!, twist, twist!, repartition,
7878
repartition!
7979
export catdomain, catcodomain

src/auxiliary/linalg.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,6 @@ end
8484
safesign(s::Real) = ifelse(s < zero(s), -one(s), +one(s))
8585
safesign(s::Complex) = ifelse(iszero(s), one(s), s / abs(s))
8686

87-
isisometry(A::StridedMatrix; kwargs...) = isapprox(A' * A, LinearAlgebra.I, kwargs...)
88-
8987
function leftorth!(A::StridedMatrix{<:BlasFloat}, alg::Union{QR,QRpos}, atol::Real)
9088
iszero(atol) || throw(ArgumentError("nonzero atol not supported by $alg"))
9189
m, n = size(A)

src/tensors/factorizations/factorizations.jl

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,12 +174,15 @@ function LinearAlgebra.isposdef!(t::TensorMap)
174174
end
175175

176176
# TODO: tolerances are per-block, not global or weighted - does that matter?
177-
function isisometry(t::AbstractTensorMap; kwargs...)
177+
function MatrixAlgebraKit.is_left_isometry(t::AbstractTensorMap; kwargs...)
178178
domain(t) codomain(t) || return false
179-
for (_, b) in blocks(t)
180-
MatrixAlgebra.isisometry(b; kwargs...) || return false
181-
end
182-
return true
179+
f((c, b)) = MatrixAlgebraKit.is_left_isometry(b; kwargs...)
180+
return all(f, blocks(t))
181+
end
182+
function MatrixAlgebraKit.is_right_isometry(t::AbstractTensorMap; kwargs...)
183+
domain(t) codomain(t) || return false
184+
f((c, b)) = MatrixAlgebraKit.is_right_isometry(b; kwargs...)
185+
return all(f, blocks(t))
183186
end
184187

185188
end

test/tensors.jl

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -365,9 +365,8 @@ for V in spacelist
365365
for T in (Float64, ComplexF64)
366366
t1 = randisometry(T, W1, W2)
367367
t2 = randisometry(T, W2 W2)
368-
@test t1' * t1 one(t2)
369-
@test t2' * t2 one(t2)
370-
@test t2 * t2' one(t2)
368+
@test isisometry(t1)
369+
@test isunitary(t2)
371370
P = t1 * t1'
372371
@test P * P P
373372
end
@@ -447,21 +446,14 @@ for V in spacelist
447446
TensorKit.Polar(), TensorKit.SVD(),
448447
TensorKit.SDD())
449448
Q, R = @constinferred leftorth(t, ((3, 4, 2), (1, 5)); alg=alg)
450-
QdQ = Q' * Q
451-
@test QdQ one(QdQ)
449+
@test isisometry(Q)
452450
@test Q * R permute(t, ((3, 4, 2), (1, 5)))
453-
# removed since leftorth now merges legs!
454-
# if alg isa Polar
455-
# @test isposdef(R)
456-
# @test domain(R) == codomain(R) == space(t, 1)' ⊗ space(t, 5)'
457-
# end
458451
end
459452
@testset "leftnull with $alg" for alg in
460453
(TensorKit.QR(), TensorKit.SVD(),
461454
TensorKit.SDD())
462455
N = @constinferred leftnull(t, ((3, 4, 2), (1, 5)); alg=alg)
463-
NdN = N' * N
464-
@test NdN one(NdN)
456+
@test isisometry(N)
465457
@test norm(N' * permute(t, ((3, 4, 2), (1, 5)))) <
466458
100 * eps(norm(t))
467459
end
@@ -471,30 +463,21 @@ for V in spacelist
471463
TensorKit.Polar(), TensorKit.SVD(),
472464
TensorKit.SDD())
473465
L, Q = @constinferred rightorth(t, ((3, 4), (2, 1, 5)); alg=alg)
474-
QQd = Q * Q'
475-
@test QQd one(QQd)
466+
@test isisometry(Q; side=:right)
476467
@test L * Q permute(t, ((3, 4), (2, 1, 5)))
477-
# removed since rightorth now merges legs!
478-
# if alg isa Polar
479-
# @test isposdef(L)
480-
# @test domain(L) == codomain(L) == space(t, 3) ⊗ space(t, 4)
481-
# end
482468
end
483469
@testset "rightnull with $alg" for alg in
484470
(TensorKit.LQ(), TensorKit.SVD(),
485471
TensorKit.SDD())
486472
M = @constinferred rightnull(t, ((3, 4), (2, 1, 5)); alg=alg)
487-
MMd = M * M'
488-
@test MMd one(MMd)
473+
@test isisometry(M; side=:right)
489474
@test norm(permute(t, ((3, 4), (2, 1, 5))) * M') <
490475
100 * eps(norm(t))
491476
end
492477
@testset "tsvd with $alg" for alg in (TensorKit.SVD(), TensorKit.SDD())
493478
U, S, V = @constinferred tsvd(t, ((3, 4, 2), (1, 5)); alg=alg)
494-
UdU = U' * U
495-
@test UdU one(UdU)
496-
VVd = V * V'
497-
@test VVd one(VVd)
479+
@test isisometry(U)
480+
@test isisometry(V; side=:right)
498481
t2 = permute(t, ((3, 4, 2), (1, 5)))
499482
@test U * S * V t2
500483

@@ -537,8 +520,7 @@ for V in spacelist
537520
(TensorKit.QR(), TensorKit.SVD(),
538521
TensorKit.SDD())
539522
N = @constinferred leftnull(t; alg=alg)
540-
@test N' * N id(domain(N))
541-
@test N * N' id(codomain(N))
523+
@test isunitary(N)
542524
end
543525
@testset "rightorth with $alg" for alg in
544526
(TensorKit.RQ(), TensorKit.RQpos(),
@@ -553,8 +535,7 @@ for V in spacelist
553535
(TensorKit.LQ(), TensorKit.SVD(),
554536
TensorKit.SDD())
555537
M = @constinferred rightnull(copy(t'); alg=alg)
556-
@test M * M' id(codomain(M))
557-
@test M' * M id(domain(M))
538+
@test isunitary(M)
558539
end
559540
@testset "tsvd with $alg" for alg in (TensorKit.SVD(), TensorKit.SDD())
560541
U, S, V = @constinferred tsvd(t; alg=alg)
@@ -590,8 +571,7 @@ for V in spacelist
590571
@test !isposdef(t2) # unlikely for non-hermitian map
591572
t2 = (t2 + t2')
592573
D, V = eigen(t2)
593-
VdV = V' * V
594-
@test VdV one(VdV)
574+
@test isisometry(V)
595575
D̃, Ṽ = @constinferred eigh(t2)
596576
@test D
597577
@test V

0 commit comments

Comments
 (0)