1
1
using BlockArrays: Block, BlockedMatrix, BlockedVector, blocks, mortar
2
2
using 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
4
10
using MatrixAlgebraKit:
5
11
diagview,
6
12
eig_full,
@@ -22,10 +28,76 @@ using MatrixAlgebraKit:
22
28
svd_trunc,
23
29
truncrank,
24
30
trunctol
25
- using LinearAlgebra: LinearAlgebra, Diagonal, hermitianpart
26
31
using Random: Random
27
32
using 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
29
101
30
102
function test_svd (a, (U, S, Vᴴ); full= false )
31
103
# Check that the SVD is correct
0 commit comments