11using BlockArrays: Block, BlockedMatrix, BlockedVector, blocks, mortar
22using BlockSparseArrays:
3- BlockSparseArray, BlockDiagonal, blockstoredlength, eachblockstoredindex
3+ BlockSparseArrays,
4+ BlockDiagonal,
5+ BlockSparseArray,
6+ BlockSparseMatrix,
7+ blockstoredlength,
8+ eachblockstoredindex
9+ using LinearAlgebra: LinearAlgebra, Diagonal, hermitianpart, pinv
410using MatrixAlgebraKit:
511 diagview,
612 eig_full,
@@ -22,10 +28,76 @@ using MatrixAlgebraKit:
2228 svd_trunc,
2329 truncrank,
2430 trunctol
25- using LinearAlgebra: LinearAlgebra, Diagonal, hermitianpart
2631using Random: Random
2732using StableRNGs: StableRNG
28- using Test: @inferred , @testset , @test
33+ using Test: @inferred , @test , @test_throws , @testset
34+
35+ # These functions involve inverses so break when there are zeros on the diagonal.
36+ MATRIX_FUNCTIONS_SINGULAR = [:csc , :cot , :csch , :coth ]
37+
38+ # Broken because of type stability issues. Fix manually by forcing to be complex.
39+ MATRIX_FUNCTIONS_UNSTABLE = [
40+ :log ,
41+ :sqrt ,
42+ :acos ,
43+ :asin ,
44+ :atan ,
45+ :acsc ,
46+ :asec ,
47+ :acot ,
48+ :acosh ,
49+ :asinh ,
50+ :atanh ,
51+ :acsch ,
52+ :asech ,
53+ :acoth ,
54+ ]
55+
56+ @testset " Matrix functions (eltype=$elt )" for elt in (Float32, Float64, ComplexF64)
57+ rng = StableRNG (123 )
58+ a = BlockSparseMatrix {elt} (undef, [2 , 3 ], [2 , 3 ])
59+ a[Block (1 , 1 )] = randn (rng, elt, 2 , 2 )
60+ a[Block (2 , 2 )] = randn (rng, elt, 3 , 3 )
61+ MATRIX_FUNCTIONS = BlockSparseArrays. MATRIX_FUNCTIONS
62+ MATRIX_FUNCTIONS = [MATRIX_FUNCTIONS; [:inv , :pinv ]]
63+ # Only works when real, also isn't defined in Julia 1.10.
64+ MATRIX_FUNCTIONS = setdiff (MATRIX_FUNCTIONS, [:cbrt ])
65+ # Broken because of type stability issues. Fix manually by forcing to be complex.
66+ MATRIX_FUNCTIONS = setdiff (MATRIX_FUNCTIONS, MATRIX_FUNCTIONS_UNSTABLE)
67+ for f in MATRIX_FUNCTIONS
68+ @eval begin
69+ fa = $ f ($ a)
70+ @test Matrix (fa) ≈ $ f (Matrix ($ a))
71+ @test fa isa BlockSparseMatrix
72+ @test issetequal (eachblockstoredindex (fa), [Block (1 , 1 ), Block (2 , 2 )])
73+ end
74+ end
75+
76+ # Skip inverse functions when there are missing/zero diagonal blocks.
77+ rng = StableRNG (123 )
78+ a = BlockSparseMatrix {elt} (undef, [2 , 3 ], [2 , 3 ])
79+ a[Block (2 , 2 )] = randn (rng, elt, 3 , 3 )
80+ MATRIX_FUNCTIONS = BlockSparseArrays. MATRIX_FUNCTIONS
81+ # These functions involve inverses so break when there are zeros on the diagonal.
82+ MATRIX_FUNCTIONS = setdiff (MATRIX_FUNCTIONS, MATRIX_FUNCTIONS_SINGULAR)
83+ # Broken because of type stability issues. Fix manually by forcing to be complex.
84+ MATRIX_FUNCTIONS = setdiff (MATRIX_FUNCTIONS, MATRIX_FUNCTIONS_UNSTABLE)
85+ # Dense version is broken for some reason, investigate.
86+ MATRIX_FUNCTIONS = setdiff (MATRIX_FUNCTIONS, [:cbrt ])
87+ for f in MATRIX_FUNCTIONS
88+ @eval begin
89+ fa = $ f ($ a)
90+ @test Matrix (fa) ≈ $ f (Matrix ($ a))
91+ @test fa isa BlockSparseMatrix
92+ @test issetequal (eachblockstoredindex (fa), [Block (1 , 1 ), Block (2 , 2 )])
93+ end
94+ end
95+ for f in MATRIX_FUNCTIONS_SINGULAR
96+ @eval begin
97+ @test_throws LinearAlgebra. SingularException $ f ($ a)
98+ end
99+ end
100+ end
29101
30102function test_svd (a, (U, S, Vᴴ); full= false )
31103 # Check that the SVD is correct
0 commit comments