1
1
using BlockArrays: Block, BlockedMatrix, BlockedVector, blocks, mortar
2
2
using BlockSparseArrays: BlockSparseArray, BlockDiagonal, eachblockstoredindex
3
- using MatrixAlgebraKit: svd_compact, svd_full, svd_trunc, truncrank
3
+ using MatrixAlgebraKit: svd_compact, svd_full, svd_trunc, truncrank, trunctol
4
4
using LinearAlgebra: LinearAlgebra
5
5
using Random: Random
6
6
using Test: @inferred , @testset , @test
88
88
# ----------
89
89
90
90
@testset " svd_trunc ($m , $n ) BlockSparseMatri{$T }" for ((m, n), T) in test_params
91
- (m, n), T = first (test_params)
92
91
a = BlockSparseArray {T} (undef, m, n)
93
92
94
93
# test blockdiagonal
99
98
100
99
minmn = min (size (a)... )
101
100
r = max (1 , minmn - 2 )
101
+ trunc = truncrank (r)
102
102
103
- U1, S1, V1ᴴ = svd_trunc (a; trunc= truncrank (r) )
104
- U2, S2, V2ᴴ = svd_trunc (Matrix (a); trunc= truncrank (r) )
103
+ U1, S1, V1ᴴ = svd_trunc (a; trunc)
104
+ U2, S2, V2ᴴ = svd_trunc (Matrix (a); trunc)
105
105
@test size (U1) == size (U2)
106
106
@test size (S1) == size (S2)
107
107
@test size (V1ᴴ) == size (V2ᴴ)
@@ -110,11 +110,11 @@ end
110
110
@test (U1' * U1 ≈ LinearAlgebra. I)
111
111
@test (V1ᴴ * V1ᴴ' ≈ LinearAlgebra. I)
112
112
113
- # test permuted blockdiagonal
114
- perm = Random . randperm ( length (m) )
115
- b = a[ Block .(perm), Block .( 1 : length (n))]
116
- U1, S1, V1ᴴ = svd_trunc (b ; trunc= truncrank (r) )
117
- U2, S2, V2ᴴ = svd_trunc (Matrix (b ); trunc= truncrank (r) )
113
+ atol = minimum (LinearAlgebra . diag (S1)) + 10 * eps ( real (T))
114
+ trunc = trunctol (atol )
115
+
116
+ U1, S1, V1ᴴ = svd_trunc (a ; trunc)
117
+ U2, S2, V2ᴴ = svd_trunc (Matrix (a ); trunc)
118
118
@test size (U1) == size (U2)
119
119
@test size (S1) == size (S2)
120
120
@test size (V1ᴴ) == size (V2ᴴ)
@@ -123,17 +123,34 @@ end
123
123
@test (U1' * U1 ≈ LinearAlgebra. I)
124
124
@test (V1ᴴ * V1ᴴ' ≈ LinearAlgebra. I)
125
125
126
+ # test permuted blockdiagonal
127
+ perm = Random. randperm (length (m))
128
+ b = a[Block .(perm), Block .(1 : length (n))]
129
+ for trunc in (truncrank (r), trunctol (atol))
130
+ U1, S1, V1ᴴ = svd_trunc (b; trunc)
131
+ U2, S2, V2ᴴ = svd_trunc (Matrix (b); trunc)
132
+ @test size (U1) == size (U2)
133
+ @test size (S1) == size (S2)
134
+ @test size (V1ᴴ) == size (V2ᴴ)
135
+ @test Matrix (U1 * S1 * V1ᴴ) ≈ U2 * S2 * V2ᴴ
136
+
137
+ @test (U1' * U1 ≈ LinearAlgebra. I)
138
+ @test (V1ᴴ * V1ᴴ' ≈ LinearAlgebra. I)
139
+ end
140
+
126
141
# test permuted blockdiagonal with missing row/col
127
142
I_removed = rand (eachblockstoredindex (b))
128
143
c = copy (b)
129
144
delete! (blocks (c). storage, CartesianIndex (Int .(Tuple (I_removed))))
130
- U1, S1, V1ᴴ = svd_trunc (c; trunc= truncrank (r))
131
- U2, S2, V2ᴴ = svd_trunc (Matrix (c); trunc= truncrank (r))
132
- @test size (U1) == size (U2)
133
- @test size (S1) == size (S2)
134
- @test size (V1ᴴ) == size (V2ᴴ)
135
- @test Matrix (U1 * S1 * V1ᴴ) ≈ U2 * S2 * V2ᴴ
136
-
137
- @test (U1' * U1 ≈ LinearAlgebra. I)
138
- @test (V1ᴴ * V1ᴴ' ≈ LinearAlgebra. I)
145
+ for trunc in (truncrank (r), trunctol (atol))
146
+ U1, S1, V1ᴴ = svd_trunc (c; trunc)
147
+ U2, S2, V2ᴴ = svd_trunc (Matrix (c); trunc)
148
+ @test size (U1) == size (U2)
149
+ @test size (S1) == size (S2)
150
+ @test size (V1ᴴ) == size (V2ᴴ)
151
+ @test Matrix (U1 * S1 * V1ᴴ) ≈ U2 * S2 * V2ᴴ
152
+
153
+ @test (U1' * U1 ≈ LinearAlgebra. I)
154
+ @test (V1ᴴ * V1ᴴ' ≈ LinearAlgebra. I)
155
+ end
139
156
end
0 commit comments