1
1
using BlockArrays: Block, BlockedMatrix, BlockedVector, blocks, mortar
2
- using BlockSparseArrays: BlockSparseArray, BlockDiagonal, eachblockstoredindex
2
+ using BlockSparseArrays:
3
+ BlockSparseArray, BlockDiagonal, blockstoredlength, eachblockstoredindex
3
4
using MatrixAlgebraKit:
5
+ diagview,
6
+ eig_full,
7
+ eig_trunc,
8
+ eig_vals,
9
+ eigh_full,
10
+ eigh_trunc,
11
+ eigh_vals,
4
12
left_orth,
5
13
left_polar,
6
14
lq_compact,
@@ -14,8 +22,9 @@ using MatrixAlgebraKit:
14
22
svd_trunc,
15
23
truncrank,
16
24
trunctol
17
- using LinearAlgebra: LinearAlgebra
25
+ using LinearAlgebra: LinearAlgebra, Diagonal, hermitianpart
18
26
using Random: Random
27
+ using StableRNGs: StableRNG
19
28
using Test: @inferred , @testset , @test
20
29
21
30
function test_svd (a, (U, S, Vᴴ); full= false )
@@ -273,3 +282,111 @@ end
273
282
@test size (U, 1 ) ≤ 2
274
283
@test Matrix (U * U' ) ≈ LinearAlgebra. I
275
284
end
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