Skip to content

Commit c030ce5

Browse files
committed
orth for non-AbstractMatrix
1 parent 7cc51bf commit c030ce5

3 files changed

Lines changed: 77 additions & 8 deletions

File tree

src/implementations/orthnull.jl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,26 @@ function left_orth_polar!(A, VC, alg)
107107
return left_polar!(A, VC, alg′)
108108
end
109109
function left_orth_svd!(A, VC, alg, trunc::Nothing=nothing)
110+
alg′ = select_algorithm(svd_compact!, A, alg)
111+
U, S, Vᴴ = svd_compact!(A, alg′)
112+
V, C = VC
113+
return copy!(V, U), mul!(C, S, Vᴴ)
114+
end
115+
function left_orth_svd!(A::AbstractMatrix, VC, alg, trunc::Nothing=nothing)
110116
alg′ = select_algorithm(svd_compact!, A, alg)
111117
V, C = VC
112118
S = Diagonal(initialize_output(svd_vals!, A, alg′))
113119
U, S, Vᴴ = svd_compact!(A, (V, S, C), alg′)
114120
return U, lmul!(S, Vᴴ)
115121
end
116122
function left_orth_svd!(A, VC, alg, trunc)
123+
alg′ = select_algorithm(svd_compact!, A, alg)
124+
alg_trunc = select_algorithm(svd_trunc!, A, alg′; trunc)
125+
U, S, Vᴴ = svd_trunc!(A, alg_trunc)
126+
V, C = VC
127+
return copy!(V, U), mul!(C, S, Vᴴ)
128+
end
129+
function left_orth_svd!(A::AbstractMatrix, VC, alg, trunc)
117130
alg′ = select_algorithm(svd_compact!, A, alg)
118131
alg_trunc = select_algorithm(svd_trunc!, A, alg′; trunc)
119132
V, C = VC
@@ -148,13 +161,26 @@ function right_orth_polar!(A, CVᴴ, alg)
148161
return right_polar!(A, CVᴴ, alg′)
149162
end
150163
function right_orth_svd!(A, CVᴴ, alg, trunc::Nothing=nothing)
164+
alg′ = select_algorithm(svd_compact!, A, alg)
165+
U, S, Vᴴ′ = svd_compact!(A, alg′)
166+
C, Vᴴ = CVᴴ
167+
return mul!(C, U, S), copy!(Vᴴ, Vᴴ′)
168+
end
169+
function right_orth_svd!(A::AbstractMatrix, CVᴴ, alg, trunc::Nothing=nothing)
151170
alg′ = select_algorithm(svd_compact!, A, alg)
152171
C, Vᴴ = CVᴴ
153172
S = Diagonal(initialize_output(svd_vals!, A, alg′))
154173
U, S, Vᴴ = svd_compact!(A, (C, S, Vᴴ), alg′)
155174
return rmul!(U, S), Vᴴ
156175
end
157176
function right_orth_svd!(A, CVᴴ, alg, trunc)
177+
alg′ = select_algorithm(svd_compact!, A, alg)
178+
alg_trunc = select_algorithm(svd_trunc!, A, alg′; trunc)
179+
U, S, Vᴴ′ = svd_trunc!(A, alg_trunc)
180+
C, Vᴴ = CVᴴ
181+
return mul!(C, U, S), copy!(Vᴴ, Vᴴ′)
182+
end
183+
function right_orth_svd!(A::AbstractMatrix, CVᴴ, alg, trunc)
158184
alg′ = select_algorithm(svd_compact!, A, alg)
159185
alg_trunc = select_algorithm(svd_trunc!, A, alg′; trunc)
160186
C, Vᴴ = CVᴴ

src/interface/orthnull.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,10 @@ See also [`right_orth(!)`](@ref right_orth), [`left_null(!)`](@ref left_null), [
6969
"""
7070
function left_orth end
7171
function left_orth! end
72-
function left_orth!(A::AbstractMatrix; kwargs...)
72+
function left_orth!(A; kwargs...)
7373
return left_orth!(A, initialize_output(left_orth!, A); kwargs...)
7474
end
75-
function left_orth(A::AbstractMatrix; kwargs...)
75+
function left_orth(A; kwargs...)
7676
return left_orth!(copy_input(left_orth, A); kwargs...)
7777
end
7878

@@ -128,10 +128,10 @@ See also [`left_orth(!)`](@ref left_orth), [`left_null(!)`](@ref left_null), [`r
128128
"""
129129
function right_orth end
130130
function right_orth! end
131-
function right_orth!(A::AbstractMatrix; kwargs...)
131+
function right_orth!(A; kwargs...)
132132
return right_orth!(A, initialize_output(right_orth!, A); kwargs...)
133133
end
134-
function right_orth(A::AbstractMatrix; kwargs...)
134+
function right_orth(A; kwargs...)
135135
return right_orth!(copy_input(right_orth, A); kwargs...)
136136
end
137137

@@ -180,10 +180,10 @@ See also [`right_null(!)`](@ref right_null), [`left_orth(!)`](@ref left_orth), [
180180
"""
181181
function left_null end
182182
function left_null! end
183-
function left_null!(A::AbstractMatrix; kwargs...)
183+
function left_null!(A; kwargs...)
184184
return left_null!(A, initialize_output(left_null!, A); kwargs...)
185185
end
186-
function left_null(A::AbstractMatrix; kwargs...)
186+
function left_null(A; kwargs...)
187187
return left_null!(copy_input(left_null, A); kwargs...)
188188
end
189189

@@ -230,9 +230,9 @@ See also [`left_null(!)`](@ref left_null), [`left_orth(!)`](@ref left_orth), [`r
230230
"""
231231
function right_null end
232232
function right_null! end
233-
function right_null!(A::AbstractMatrix; kwargs...)
233+
function right_null!(A; kwargs...)
234234
return right_null!(A, initialize_output(right_null!, A); kwargs...)
235235
end
236-
function right_null(A::AbstractMatrix; kwargs...)
236+
function right_null(A; kwargs...)
237237
return right_null!(copy_input(right_null, A); kwargs...)
238238
end

test/orthnull.jl

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,41 @@ using StableRNGs
55
using LinearAlgebra: LinearAlgebra, I
66
using MatrixAlgebraKit: TruncationKeepAbove, TruncationKeepBelow
77

8+
# Used to test non-AbstractMatrix codepaths.
9+
struct LinearMap{P<:AbstractMatrix}
10+
parent::P
11+
end
12+
using MatrixAlgebraKit: LAPACK_SVDAlgorithm, check_input, copy_input, default_svd_algorithm,
13+
initialize_output
14+
function MatrixAlgebraKit.copy_input(::typeof(qr_compact), A::LinearMap)
15+
return LinearMap(copy_input(qr_compact, A.parent))
16+
end
17+
function MatrixAlgebraKit.copy_input(::typeof(lq_compact), A::LinearMap)
18+
return LinearMap(copy_input(lq_compact, A.parent))
19+
end
20+
function MatrixAlgebraKit.initialize_output(::typeof(left_orth!), A::LinearMap)
21+
return initialize_output(left_orth!, A.parent)
22+
end
23+
function MatrixAlgebraKit.initialize_output(::typeof(right_orth!), A::LinearMap)
24+
return initialize_output(right_orth!, A.parent)
25+
end
26+
function MatrixAlgebraKit.check_input(::typeof(left_orth!), A::LinearMap, VC)
27+
return check_input(left_orth!, A.parent, VC)
28+
end
29+
function MatrixAlgebraKit.check_input(::typeof(right_orth!), A::LinearMap, VC)
30+
return check_input(right_orth!, A.parent, VC)
31+
end
32+
function MatrixAlgebraKit.default_svd_algorithm(A::LinearMap)
33+
return default_svd_algorithm(A.parent)
34+
end
35+
function MatrixAlgebraKit.initialize_output(::typeof(svd_compact!), A::LinearMap,
36+
alg::LAPACK_SVDAlgorithm)
37+
return initialize_output(svd_compact!, A.parent, alg)
38+
end
39+
function MatrixAlgebraKit.svd_compact!(A::LinearMap, USVᴴ, alg::LAPACK_SVDAlgorithm)
40+
return svd_compact!(A.parent, USVᴴ, alg)
41+
end
42+
843
@testset "left_orth and left_null for T = $T" for T in (Float32, Float64, ComplexF32,
944
ComplexF64)
1045
rng = StableRNG(123)
@@ -23,6 +58,10 @@ using MatrixAlgebraKit: TruncationKeepAbove, TruncationKeepBelow
2358
@test N' * N I
2459
@test V * V' + N * N' I
2560

61+
M = LinearMap(A)
62+
V, C = @constinferred left_orth(M; kind=:svd)
63+
@test V * C A
64+
2665
if m > n
2766
nullity = 5
2867
V, C = @constinferred left_orth(A)
@@ -162,6 +201,10 @@ end
162201
@test Nᴴ * Nᴴ' I
163202
@test Vᴴ' * Vᴴ + Nᴴ' * Nᴴ I
164203

204+
M = LinearMap(A)
205+
C, Vᴴ = @constinferred right_orth(M; kind=:svd)
206+
@test C * Vᴴ A
207+
165208
Ac = similar(A)
166209
C2, Vᴴ2 = @constinferred right_orth!(copy!(Ac, A), (C, Vᴴ))
167210
Nᴴ2 = @constinferred right_null!(copy!(Ac, A), Nᴴ)

0 commit comments

Comments
 (0)