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