11using BlockArrays: Block, BlockedMatrix, BlockedVector, blocks, mortar
2- using BlockSparseArrays: BlockSparseArray, BlockDiagonal, eachblockstoredindex
2+ using BlockSparseArrays:
3+ BlockSparseArray, BlockDiagonal, blockstoredlength, eachblockstoredindex
34using MatrixAlgebraKit:
5+ diagview,
6+ eig_full,
7+ eig_trunc,
8+ eig_vals,
9+ eigh_full,
10+ eigh_trunc,
11+ eigh_vals,
412 left_orth,
513 left_polar,
614 lq_compact,
@@ -14,8 +22,9 @@ using MatrixAlgebraKit:
1422 svd_trunc,
1523 truncrank,
1624 trunctol
17- using LinearAlgebra: LinearAlgebra
25+ using LinearAlgebra: LinearAlgebra, Diagonal, hermitianpart
1826using Random: Random
27+ using StableRNGs: StableRNG
1928using Test: @inferred , @testset , @test
2029
2130function test_svd (a, (U, S, Vᴴ); full= false )
@@ -273,3 +282,111 @@ end
273282 @test size (U, 1 ) ≤ 2
274283 @test Matrix (U * U' ) ≈ LinearAlgebra. I
275284end
285+
286+ @testset " eig_full (T=$T )" for T in (Float32, Float64, ComplexF32, ComplexF64)
287+ A = BlockSparseArray {T} (undef, ([2 , 3 ], [2 , 3 ]))
288+ rng = StableRNG (123 )
289+ A[Block (1 , 1 )] = randn (rng, T, 2 , 2 )
290+ A[Block (2 , 2 )] = randn (rng, T, 3 , 3 )
291+
292+ D, V = eig_full (A)
293+ @test size (D) == size (A)
294+ @test size (D) == size (A)
295+ @test blockstoredlength (D) == 2
296+ @test blockstoredlength (V) == 2
297+ @test issetequal (eachblockstoredindex (D), [Block (1 , 1 ), Block (2 , 2 )])
298+ @test issetequal (eachblockstoredindex (V), [Block (1 , 1 ), Block (2 , 2 )])
299+ @test A * V ≈ V * D
300+ end
301+
302+ @testset " eig_vals (T=$T )" for T in (Float32, Float64, ComplexF32, ComplexF64)
303+ A = BlockSparseArray {T} (undef, ([2 , 3 ], [2 , 3 ]))
304+ rng = StableRNG (123 )
305+ A[Block (1 , 1 )] = randn (rng, T, 2 , 2 )
306+ A[Block (2 , 2 )] = randn (rng, T, 3 , 3 )
307+
308+ D = eig_vals (A)
309+ @test size (D) == (size (A, 1 ),)
310+ @test blockstoredlength (D) == 2
311+ D′ = eig_vals (Matrix (A))
312+ @test sort (D; by= abs) ≈ sort (D′; by= abs)
313+ end
314+
315+ @testset " eig_trunc (T=$T )" for T in (Float32, Float64, ComplexF32, ComplexF64)
316+ A = BlockSparseArray {T} (undef, ([2 , 3 ], [2 , 3 ]))
317+ rng = StableRNG (123 )
318+ D1 = [1.0 , 0.1 ]
319+ V1 = randn (rng, T, 2 , 2 )
320+ A1 = V1 * Diagonal (D1) * inv (V1)
321+ D2 = [1.0 , 0.5 , 0.1 ]
322+ V2 = randn (rng, T, 3 , 3 )
323+ A2 = V2 * Diagonal (D2) * inv (V2)
324+ A[Block (1 , 1 )] = A1
325+ A[Block (2 , 2 )] = A2
326+
327+ D, V = eig_trunc (A; trunc= (; maxrank= 3 ))
328+ @test size (D) == (3 , 3 )
329+ @test size (D) == (3 , 3 )
330+ @test blockstoredlength (D) == 2
331+ @test blockstoredlength (V) == 2
332+ @test issetequal (eachblockstoredindex (D), [Block (1 , 1 ), Block (2 , 2 )])
333+ @test issetequal (eachblockstoredindex (V), [Block (1 , 1 ), Block (2 , 2 )])
334+ @test A * V ≈ V * D
335+ @test sort (diagview (D[Block (1 , 1 )]); by= abs, rev= true ) ≈ D1[1 : 1 ]
336+ @test sort (diagview (D[Block (2 , 2 )]); by= abs, rev= true ) ≈ D2[1 : 2 ]
337+ end
338+
339+ herm (x) = parent (hermitianpart (x))
340+
341+ @testset " eigh_full (T=$T )" for T in (Float32, Float64, ComplexF32, ComplexF64)
342+ A = BlockSparseArray {T} (undef, ([2 , 3 ], [2 , 3 ]))
343+ rng = StableRNG (123 )
344+ A[Block (1 , 1 )] = herm (randn (rng, T, 2 , 2 ))
345+ A[Block (2 , 2 )] = herm (randn (rng, T, 3 , 3 ))
346+
347+ D, V = eigh_full (A)
348+ @test size (D) == size (A)
349+ @test size (D) == size (A)
350+ @test blockstoredlength (D) == 2
351+ @test blockstoredlength (V) == 2
352+ @test issetequal (eachblockstoredindex (D), [Block (1 , 1 ), Block (2 , 2 )])
353+ @test issetequal (eachblockstoredindex (V), [Block (1 , 1 ), Block (2 , 2 )])
354+ @test A * V ≈ V * D
355+ end
356+
357+ @testset " eigh_vals (T=$T )" for T in (Float32, Float64, ComplexF32, ComplexF64)
358+ A = BlockSparseArray {T} (undef, ([2 , 3 ], [2 , 3 ]))
359+ rng = StableRNG (123 )
360+ A[Block (1 , 1 )] = herm (randn (rng, T, 2 , 2 ))
361+ A[Block (2 , 2 )] = herm (randn (rng, T, 3 , 3 ))
362+
363+ D = eigh_vals (A)
364+ @test size (D) == (size (A, 1 ),)
365+ @test blockstoredlength (D) == 2
366+ D′ = eigh_vals (Matrix (A))
367+ @test sort (D; by= abs) ≈ sort (D′; by= abs)
368+ end
369+
370+ @testset " eigh_trunc (T=$T )" for T in (Float32, Float64, ComplexF32, ComplexF64)
371+ A = BlockSparseArray {T} (undef, ([2 , 3 ], [2 , 3 ]))
372+ rng = StableRNG (123 )
373+ D1 = [1.0 , 0.1 ]
374+ V1, _ = qr_compact (randn (rng, T, 2 , 2 ))
375+ A1 = V1 * Diagonal (D1) * V1'
376+ D2 = [1.0 , 0.5 , 0.1 ]
377+ V2, _ = qr_compact (randn (rng, T, 3 , 3 ))
378+ A2 = V2 * Diagonal (D2) * V2'
379+ A[Block (1 , 1 )] = herm (A1)
380+ A[Block (2 , 2 )] = herm (A2)
381+
382+ D, V = eigh_trunc (A; trunc= (; maxrank= 3 ))
383+ @test size (D) == (3 , 3 )
384+ @test size (D) == (3 , 3 )
385+ @test blockstoredlength (D) == 2
386+ @test blockstoredlength (V) == 2
387+ @test issetequal (eachblockstoredindex (D), [Block (1 , 1 ), Block (2 , 2 )])
388+ @test issetequal (eachblockstoredindex (V), [Block (1 , 1 ), Block (2 , 2 )])
389+ @test A * V ≈ V * D
390+ @test sort (diagview (D[Block (1 , 1 )]); by= abs, rev= true ) ≈ D1[1 : 1 ]
391+ @test sort (diagview (D[Block (2 , 2 )]); by= abs, rev= true ) ≈ D2[1 : 2 ]
392+ end
0 commit comments