• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JuliaLang / julia / #37459

pending completion
#37459

push

local

web-flow
Calculate a checksum for the system image (#48869)

68962 of 81872 relevant lines covered (84.23%)

32262914.75 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.78
/stdlib/LinearAlgebra/src/factorization.jl
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2

3
## Matrix factorizations and decompositions
4
"""
5
    LinearAlgebra.Factorization
6

7
Abstract type for [matrix factorizations](https://en.wikipedia.org/wiki/Matrix_decomposition)
8
a.k.a. matrix decompositions.
9
See [online documentation](@ref man-linalg-factorizations) for a list of available
10
matrix factorizations.
11
"""
12
abstract type Factorization{T} end
13

14
"""
15
    AdjointFactorization
16

17
Lazy wrapper type for the adjoint of the underlying `Factorization` object. Usually, the
18
`AdjointFactorization` constructor should not be called directly, use
19
[`adjoint(:: Factorization)`](@ref) instead.
20
"""
21
struct AdjointFactorization{T,S<:Factorization} <: Factorization{T}
22
    parent::S
415✔
23
end
24
AdjointFactorization(F::Factorization) =
415✔
25
    AdjointFactorization{Base.promote_op(adjoint,eltype(F)),typeof(F)}(F)
26

27
"""
28
    TransposeFactorization
29

30
Lazy wrapper type for the transpose of the underlying `Factorization` object. Usually, the
31
`TransposeFactorization` constructor should not be called directly, use
32
[`transpose(:: Factorization)`](@ref) instead.
33
"""
34
struct TransposeFactorization{T,S<:Factorization} <: Factorization{T}
35
    parent::S
1,169✔
36
end
37
TransposeFactorization(F::Factorization) =
1,169✔
38
    TransposeFactorization{Base.promote_op(adjoint,eltype(F)),typeof(F)}(F)
39

40
eltype(::Type{<:Factorization{T}}) where {T} = T
10,389✔
41
size(F::AdjointFactorization) = reverse(size(parent(F)))
141✔
42
size(F::TransposeFactorization) = reverse(size(parent(F)))
550✔
43
size(F::Union{AdjointFactorization,TransposeFactorization}, d::Integer) = d in (1, 2) ? size(F)[d] : 1
×
44
parent(F::Union{AdjointFactorization,TransposeFactorization}) = F.parent
1,198✔
45

46
"""
47
    adjoint(F::Factorization)
48

49
Lazy adjoint of the factorization `F`. By default, returns an
50
[`AdjointFactorization`](@ref) wrapper.
51
"""
52
adjoint(F::Factorization) = AdjointFactorization(F)
410✔
53
"""
54
    transpose(F::Factorization)
55

56
Lazy transpose of the factorization `F`. By default, returns a [`TransposeFactorization`](@ref),
57
except for `Factorization`s with real `eltype`, in which case returns an [`AdjointFactorization`](@ref).
58
"""
59
transpose(F::Factorization) = TransposeFactorization(F)
329✔
60
transpose(F::Factorization{<:Real}) = AdjointFactorization(F)
5✔
61
adjoint(F::AdjointFactorization) = F.parent
26✔
62
transpose(F::TransposeFactorization) = F.parent
12✔
63
transpose(F::AdjointFactorization{<:Real}) = F.parent
×
64
conj(A::TransposeFactorization) = adjoint(A.parent)
×
65
conj(A::AdjointFactorization) = transpose(A.parent)
×
66

67
checkpositivedefinite(info) = info == 0 || throw(PosDefException(info))
933✔
68
checknonsingular(info, ::RowMaximum) = info == 0 || throw(SingularException(info))
3,073✔
69
checknonsingular(info, ::RowNonZero) = info == 0 || throw(SingularException(info))
5✔
70
checknonsingular(info, ::NoPivot) = info == 0 || throw(ZeroPivotException(info))
38✔
71
checknonsingular(info) = checknonsingular(info, RowMaximum())
2,752✔
72

73
"""
74
    issuccess(F::Factorization)
75

76
Test that a factorization of a matrix succeeded.
77

78
!!! compat "Julia 1.6"
79
    `issuccess(::CholeskyPivoted)` requires Julia 1.6 or later.
80

81
```jldoctest
82
julia> F = cholesky([1 0; 0 1]);
83

84
julia> issuccess(F)
85
true
86

87
julia> F = lu([1 0; 0 0]; check = false);
88

89
julia> issuccess(F)
90
false
91
```
92
"""
93
issuccess(F::Factorization)
94

95
function logdet(F::Factorization)
429✔
96
    d, s = logabsdet(F)
589✔
97
    return d + log(s)
429✔
98
end
99

100
function det(F::Factorization)
1,323✔
101
    d, s = logabsdet(F)
1,850✔
102
    return exp(d)*s
1,323✔
103
end
104

105
convert(::Type{T}, f::T) where {T<:Factorization} = f
2,192✔
106
convert(::Type{T}, f::Factorization) where {T<:Factorization} = T(f)::T
68✔
107

108
convert(::Type{T}, f::Factorization) where {T<:AbstractArray} = T(f)::T
163✔
109

110
### General promotion rules
111
Factorization{T}(F::Factorization{T}) where {T} = F
×
112
# This no longer looks odd since the return _is_ a Factorization!
113
Factorization{T}(A::AdjointFactorization) where {T} =
89✔
114
    adjoint(Factorization{T}(parent(A)))
115
Factorization{T}(A::TransposeFactorization) where {T} =
396✔
116
    transpose(Factorization{T}(parent(A)))
117
inv(F::Factorization{T}) where {T} = (n = size(F, 1); ldiv!(F, Matrix{T}(I, n, n)))
28✔
118

119
Base.hash(F::Factorization, h::UInt) = mapreduce(f -> hash(getfield(F, f)), hash, 1:nfields(F); init=h)
348✔
120
Base.:(==)(  F::T, G::T) where {T<:Factorization} = all(f -> getfield(F, f) == getfield(G, f), 1:nfields(F))
306✔
121
Base.isequal(F::T, G::T) where {T<:Factorization} = all(f -> isequal(getfield(F, f), getfield(G, f)), 1:nfields(F))::Bool
66✔
122

123
function Base.show(io::IO, x::AdjointFactorization)
1✔
124
    print(io, "adjoint of ")
1✔
125
    show(io, parent(x))
1✔
126
end
127
function Base.show(io::IO, x::TransposeFactorization)
1✔
128
    print(io, "transpose of ")
1✔
129
    show(io, parent(x))
1✔
130
end
131
function Base.show(io::IO, ::MIME"text/plain", x::AdjointFactorization)
1✔
132
    print(io, "adjoint of ")
1✔
133
    show(io, MIME"text/plain"(), parent(x))
1✔
134
end
135
function Base.show(io::IO, ::MIME"text/plain", x::TransposeFactorization)
1✔
136
    print(io, "transpose of ")
1✔
137
    show(io, MIME"text/plain"(), parent(x))
1✔
138
end
139

140
# With a real lhs and complex rhs with the same precision, we can reinterpret
141
# the complex rhs as a real rhs with twice the number of columns or rows
142
function (\)(F::Factorization{T}, B::VecOrMat{Complex{T}}) where {T<:BlasReal}
131✔
143
    require_one_based_indexing(B)
131✔
144
    c2r = reshape(copy(transpose(reinterpret(T, reshape(B, (1, length(B)))))), size(B, 1), 2*size(B, 2))
224✔
145
    x = ldiv!(F, c2r)
155✔
146
    return reshape(copy(reinterpret(Complex{T}, copy(transpose(reshape(x, div(length(x), 2), 2))))), _ret_size(F, B))
128✔
147
end
148
# don't do the reinterpretation for [Adjoint/Transpose]Factorization
149
(\)(F::TransposeFactorization{T}, B::VecOrMat{Complex{T}}) where {T<:BlasReal} =
3✔
150
    conj!(adjoint(parent(F)) \ conj.(B))
151
(\)(F::AdjointFactorization{T}, B::VecOrMat{Complex{T}}) where {T<:BlasReal} =
6✔
152
    @invoke \(F::typeof(F), B::VecOrMat)
153

154
function (/)(B::VecOrMat{Complex{T}}, F::Factorization{T}) where {T<:BlasReal}
22✔
155
    require_one_based_indexing(B)
22✔
156
    x = rdiv!(copy(reinterpret(T, B)), F)
44✔
157
    return copy(reinterpret(Complex{T}, x))
22✔
158
end
159
# don't do the reinterpretation for [Adjoint/Transpose]Factorization
160
(/)(B::VecOrMat{Complex{T}}, F::TransposeFactorization{T}) where {T<:BlasReal} =
×
161
    conj!(adjoint(parent(F)) \ conj.(B))
162
(/)(B::VecOrMat{Complex{T}}, F::AdjointFactorization{T}) where {T<:BlasReal} =
×
163
    @invoke /(B::VecOrMat{Complex{T}}, F::Factorization{T})
×
164

165
function (\)(F::Factorization, B::AbstractVecOrMat)
440✔
166
    require_one_based_indexing(B)
440✔
167
    TFB = typeof(oneunit(eltype(F)) \ oneunit(eltype(B)))
440✔
168
    ldiv!(F, copy_similar(B, TFB))
442✔
169
end
170
(\)(F::TransposeFactorization, B::AbstractVecOrMat) = conj!(adjoint(F.parent) \ conj.(B))
12✔
171

172
function (/)(B::AbstractMatrix, F::Factorization)
121✔
173
    require_one_based_indexing(B)
121✔
174
    TFB = typeof(oneunit(eltype(B)) / oneunit(eltype(F)))
121✔
175
    rdiv!(copy_similar(B, TFB), F)
121✔
176
end
177
(/)(A::AbstractMatrix, F::AdjointFactorization) = adjoint(adjoint(F) \ adjoint(A))
12✔
178
(/)(A::AbstractMatrix, F::TransposeFactorization) = transpose(transpose(F) \ transpose(A))
10✔
179

180
function ldiv!(Y::AbstractVector, A::Factorization, B::AbstractVector)
92✔
181
    require_one_based_indexing(Y, B)
92✔
182
    m, n = size(A)
92✔
183
    if m > n
92✔
184
        Bc = copy(B)
×
185
        ldiv!(A, Bc)
×
186
        return copyto!(Y, 1, Bc, 1, n)
×
187
    else
188
        return ldiv!(A, copyto!(Y, B))
92✔
189
    end
190
end
191
function ldiv!(Y::AbstractMatrix, A::Factorization, B::AbstractMatrix)
116✔
192
    require_one_based_indexing(Y, B)
116✔
193
    m, n = size(A)
116✔
194
    if m > n
116✔
195
        Bc = copy(B)
×
196
        ldiv!(A, Bc)
×
197
        return copyto!(Y, view(Bc, 1:n, :))
×
198
    else
199
        copyto!(view(Y, 1:m, :), view(B, 1:m, :))
181✔
200
        return ldiv!(A, Y)
116✔
201
    end
202
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc