Skip to content

Commit 0fd7a90

Browse files
lkdvosclaude
andcommitted
Add tests for TruncationUnion and minrank
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 4320dcd commit 0fd7a90

2 files changed

Lines changed: 76 additions & 2 deletions

File tree

test/testsuite/decompositions/svd.jl

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,29 @@ function test_svd_trunc(
212212
@test diagview(S2) diagview(S)[1:2]
213213
end
214214
end
215+
@testset "mix minrank and tol" begin
216+
m4 = 4
217+
U = instantiate_unitary(T, A, m4)
218+
Sdiag = similar(A, real(eltype(T)), m4)
219+
copyto!(Sdiag, [0.9, 0.3, 0.1, 0.01])
220+
S = Diagonal(Sdiag)
221+
Vᴴ = instantiate_unitary(T, A, m4)
222+
A = U * S * Vᴴ
223+
for trunc_fun in (
224+
(rtol, minrank) -> (; rtol, minrank),
225+
(rtol, minrank) -> trunctol(; rtol) | truncrank(minrank),
226+
)
227+
# trunctol(rtol=0.5) keeps 1 value, truncrank(3) keeps 3, union keeps 3
228+
U1, S1, V1ᴴ, ϵ1 = svd_trunc(A; trunc = trunc_fun(0.5, 3))
229+
@test length(diagview(S1)) == 3
230+
@test diagview(S1) diagview(S)[1:3]
231+
232+
# trunctol(rtol=0.2) keeps 2 values, truncrank(1) keeps 1, union keeps 2
233+
U2, S2, V2ᴴ = svd_trunc_no_error(A; trunc = trunc_fun(0.2, 1))
234+
@test length(diagview(S2)) == 2
235+
@test diagview(S2) diagview(S)[1:2]
236+
end
237+
end
215238
@testset "specify truncation algorithm" begin
216239
atol = sqrt(eps(real(eltype(T))))
217240
m4 = 4
@@ -294,6 +317,29 @@ function test_svd_trunc_algs(
294317
@test collect(diagview(S2)) collect(diagview(S)[1:2])
295318
end
296319
end
320+
@testset "mix minrank and tol" begin
321+
m4 = 4
322+
U = instantiate_unitary(T, A, m4)
323+
Sdiag = similar(A, real(eltype(T)), m4)
324+
copyto!(Sdiag, real(eltype(T))[0.9, 0.3, 0.1, 0.01])
325+
S = Diagonal(Sdiag)
326+
Vᴴ = instantiate_unitary(T, A, m4)
327+
A = U * S * Vᴴ
328+
for trunc_fun in (
329+
(rtol, minrank) -> (; rtol, minrank),
330+
(rtol, minrank) -> trunctol(; rtol) | truncrank(minrank),
331+
)
332+
# trunctol(rtol=0.5) keeps 1 value, truncrank(3) keeps 3, union keeps 3
333+
U1, S1, V1ᴴ, ϵ1 = svd_trunc(A; trunc = trunc_fun(0.5, 3), alg)
334+
@test length(diagview(S1)) == 3
335+
@test collect(diagview(S1)) collect(diagview(S)[1:3])
336+
337+
# trunctol(rtol=0.2) keeps 2 values, truncrank(1) keeps 1, union keeps 2
338+
U2, S2, V2ᴴ, ϵ2 = svd_trunc(A; trunc = trunc_fun(0.2, 1), alg)
339+
@test length(diagview(S2)) == 2
340+
@test collect(diagview(S2)) collect(diagview(S)[1:2])
341+
end
342+
end
297343
@testset "specify truncation algorithm" begin
298344
atol = sqrt(eps(real(eltype(T))))
299345
m4 = 4

test/truncate.jl

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
using MatrixAlgebraKit
22
using Test
33
using TestExtras
4-
using MatrixAlgebraKit: NoTruncation, TruncationIntersection, TruncationByOrder,
5-
TruncationByValue, TruncationStrategy, findtruncated, findtruncated_svd
4+
using MatrixAlgebraKit: NoTruncation, TruncationIntersection, TruncationUnion,
5+
TruncationByOrder, TruncationByValue, TruncationStrategy, findtruncated, findtruncated_svd
66

77
@testset "truncate" begin
88
trunc = @constinferred TruncationStrategy()
@@ -65,4 +65,32 @@ using MatrixAlgebraKit: NoTruncation, TruncationIntersection, TruncationByOrder,
6565
@test issetequal(values[@constinferred(findtruncated(values, strategy))], values[2:5])
6666
vals_sorted = sort(values; by = abs, rev = true)
6767
@test vals_sorted[@constinferred(findtruncated_svd(vals_sorted, strategy))] == vals_sorted[1:4]
68+
69+
# TruncationUnion / minrank
70+
trunc = @constinferred TruncationStrategy(; minrank = 3)
71+
@test trunc isa TruncationByOrder
72+
@test trunc == truncrank(3)
73+
74+
trunc = @constinferred TruncationStrategy(; atol, minrank = 3)
75+
@test trunc isa TruncationUnion
76+
@test trunc == trunctol(; atol) | truncrank(3)
77+
78+
# | operator
79+
values2 = [1.0, 0.9, 0.5, 0.3, 0.01]
80+
# trunctol keeps 1:3 (above 0.4), truncrank(4) keeps 1:4, union keeps 1:4
81+
strategy = trunctol(; atol = 0.4) | truncrank(4)
82+
@test @constinferred(findtruncated_svd(values2, strategy)) == 1:4
83+
# trunctol keeps 1:3, truncrank(2) keeps 1:2, union keeps 1:3
84+
strategy = trunctol(; atol = 0.4) | truncrank(2)
85+
@test @constinferred(findtruncated_svd(values2, strategy)) == 1:3
86+
87+
# notrunc is absorbing for |
88+
@test (notrunc() | truncrank(3)) isa NoTruncation
89+
@test (truncrank(3) | notrunc()) isa NoTruncation
90+
91+
# TruncationUnion flattening
92+
union1 = truncrank(2) | trunctol(; atol = 0.4)
93+
union2 = union1 | truncrank(4)
94+
@test union2 isa TruncationUnion
95+
@test length(union2.components) == 3
6896
end

0 commit comments

Comments
 (0)