11using TestExtras
2+ using LinearAlgebra: Diagonal, normalize!
23
34function test_projections(T:: Type , sz; kwargs... )
45 summary_str = testargs_summary(T, sz)
@@ -16,7 +17,7 @@ function test_project_antihermitian(
1617 )
1718 summary_str = testargs_summary(T, sz)
1819 return @testset " project_antihermitian! $summary_str " begin
19- noisefactor = eps(real(T ))^ (3 / 4 )
20+ noisefactor = eps(real(eltype(T) ))^ (3 / 4 )
2021 algs = (NativeBlocked(blocksize = 16 ), NativeBlocked(blocksize = 32 ), NativeBlocked(blocksize = 64 ))
2122 @testset " algorithm $alg " for alg in algs
2223 A = instantiate_matrix(T, sz)
@@ -30,7 +31,8 @@ function test_project_antihermitian(
3031 @test A == Ac
3132 Ba_approx = Ba + noisefactor * Ah
3233 @test ! isantihermitian(Ba_approx)
33- @test isantihermitian(Ba_approx; rtol = 10 * noisefactor)
34+ # this is never anti-hermitian for real Diagonal: |A - A'| == 0
35+ @test isantihermitian(Ba_approx; rtol = 10 * noisefactor) || norm(Aa) == 0
3436
3537 copy!(Ac, A)
3638 Ba = project_antihermitian!(Ac, alg)
@@ -40,7 +42,7 @@ function test_project_antihermitian(
4042 end
4143
4244 # test approximate error calculation
43- A = normalize!(randn(rng, T, m, m ))
45+ A = normalize!(randn(rng, eltype(T), size(A) . .. ))
4446 Ah = project_hermitian(A)
4547 Aa = project_antihermitian(A)
4648
@@ -63,7 +65,7 @@ function test_project_hermitian(
6365 )
6466 summary_str = testargs_summary(T, sz)
6567 return @testset " project_hermitian! $summary_str " begin
66- noisefactor = eps(real(T ))^ (3 / 4 )
68+ noisefactor = eps(real(eltype(T) ))^ (3 / 4 )
6769 algs = (NativeBlocked(blocksize = 16 ), NativeBlocked(blocksize = 32 ), NativeBlocked(blocksize = 64 ))
6870 @testset " algorithm $alg " for alg in algs
6971 A = instantiate_matrix(T, sz)
@@ -76,7 +78,8 @@ function test_project_hermitian(
7678 @test Bh ≈ Ah
7779 @test A == Ac
7880 Bh_approx = Bh + noisefactor * Aa
79- @test ! ishermitian(Bh_approx)
81+ # this is still hermitian for real Diagonal: |A - A'| == 0
82+ @test ! ishermitian(Bh_approx) || norm(Aa) == 0
8083 @test ishermitian(Bh_approx; rtol = 10 * noisefactor)
8184
8285 Bh = project_hermitian!(Ac, alg)
@@ -86,7 +89,7 @@ function test_project_hermitian(
8689 end
8790
8891 # test approximate error calculation
89- A = normalize!(randn(rng, T, m, m ))
92+ A = normalize!(randn(rng, eltype(T), size(A) . .. ))
9093 Ah = project_hermitian(A)
9194 Aa = project_antihermitian(A)
9295
@@ -109,24 +112,29 @@ function test_project_isometric(
109112 )
110113 summary_str = testargs_summary(T, sz)
111114 return @testset " project_isometric! $summary_str " begin
112- algs = (PolarViaSVD(), PolarNewton())
115+ A = instantiate_matrix(T, sz)
116+ algs = if T <: Diagonal
117+ (PolarNewton(),)
118+ else
119+ (PolarViaSVD(MatrixAlgebraKit. default_svd_algorithm(A)), PolarNewton())
120+ end
113121 @testset " algorithm $alg " for alg in algs
114- A = instantiate_matrix(T, sz)
115- Ac = deepcopy(A)
116- k = min(size(A). .. )
117- W = project_isometric(A, alg)
122+ A = instantiate_matrix(T, sz)
123+ Ac = deepcopy(A)
124+ k = min(size(A). .. )
125+ W = project_isometric(A, alg)
118126 @test isisometric(W)
119- W2 = project_isometric(W, alg)
127+ W2 = project_isometric(W, alg)
120128 @test W2 ≈ W # stability of the projection
121129 @test W * (W' * A) ≈ A
122130
123- W2 = @constinferred project_isometric!(Ac, W, alg)
131+ W2 = @testinferred project_isometric!(Ac, W, alg)
124132 @test W2 === W
125133 @test isisometric(W)
126134
127135 # test that W is closer to A then any other isometry
128136 for k in 1:10
129- δA = randn(rng, T, m, n )
137+ δA = randn(rng, eltype(T), size(A)... )
130138 W = project_isometric(A, alg)
131139 W2 = project_isometric(A + δA / 100, alg)
132140 @test norm(A - W2) > norm(A - W)
0 commit comments