Skip to content

Commit ad868c7

Browse files
authored
Backports release 1.12 (#1411)
[x] #1365 [x] #1373 [x] #1385 [x] #1397 [x] #1402 [x] #1413 [x] #1417 [x] #1418
2 parents 8f753a7 + e4eeff1 commit ad868c7

File tree

13 files changed

+119
-22
lines changed

13 files changed

+119
-22
lines changed

.buildkite/runtests.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ steps:
1313
gid: 1000
1414
# Julia installation inside the sandbox
1515
- JuliaCI/julia#v1:
16-
version: "nightly"
16+
version: "1.12"
1717
arch: "i686"
1818
command: |
1919
julia --color=yes --code-coverage=@ .ci/run_tests.jl
@@ -37,7 +37,7 @@ steps:
3737
gid: 1000
3838
# Julia installation inside the sandbox
3939
- JuliaCI/julia#v1:
40-
version: "nightly"
40+
version: "1.12"
4141
command: |
4242
julia --color=yes --code-coverage=@ .ci/run_tests.jl
4343
agents:
@@ -49,7 +49,7 @@ steps:
4949
- label: ":macos: macos-aarch64"
5050
plugins:
5151
- JuliaCI/julia#v1:
52-
version: "nightly"
52+
version: "1.12"
5353
- JuliaCI/julia-coverage#v1:
5454
codecov: true
5555
command: |
@@ -62,7 +62,7 @@ steps:
6262
- label: ":windows: windows-x86_64"
6363
plugins:
6464
- JuliaCI/julia#v1:
65-
version: "nightly"
65+
version: "1.12"
6666
- JuliaCI/julia-coverage#v1:
6767
codecov: true
6868
command: |

docs/src/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,7 @@ LinearAlgebra.BLAS.trsv
745745

746746
```@docs
747747
LinearAlgebra.BLAS.ger!
748-
# xGERU
748+
LinearAlgebra.BLAS.geru!
749749
# xGERC
750750
LinearAlgebra.BLAS.her!
751751
# xHPR

src/adjtrans.jl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,3 +536,27 @@ conj(A::Adjoint) = transpose(A.parent)
536536
function Base.replace_in_print_matrix(A::AdjOrTrans,i::Integer,j::Integer,s::AbstractString)
537537
Base.replace_in_print_matrix(parent(A), j, i, s)
538538
end
539+
540+
# Special adjoint/transpose methods for Adjoint/Transpose that have been reshaped as a vector
541+
# these are used in transposing banded matrices by forwarding the operation to the bands
542+
"""
543+
_vectranspose(A::AbstractVector)::AbstractVector
544+
545+
Compute `vec(transpose(A))`, but avoid an allocating reshape if possible
546+
"""
547+
_vectranspose(A::AbstractVector) = vec(transpose(A))
548+
_vectranspose(A::Base.ReshapedArray{<:Any,1,<:TransposeAbsVec}) = transpose(parent(A))
549+
"""
550+
_vecadjoint(A::AbstractVector)::AbstractVector
551+
552+
Compute `vec(adjoint(A))`, but avoid an allocating reshape if possible
553+
"""
554+
_vecadjoint(A::AbstractVector) = vec(adjoint(A))
555+
_vecadjoint(A::Base.ReshapedArray{<:Any,1,<:AdjointAbsVec}) = adjoint(parent(A))
556+
557+
diagview(A::Transpose, k::Integer = 0) = _vectranspose(diagview(parent(A), -k))
558+
diagview(A::Adjoint, k::Integer = 0) = _vecadjoint(diagview(parent(A), -k))
559+
560+
# triu and tril
561+
triu!(A::AdjOrTransAbsMat, k::Integer = 0) = wrapperop(A)(tril!(parent(A), -k))
562+
tril!(A::AdjOrTransAbsMat, k::Integer = 0) = wrapperop(A)(triu!(parent(A), -k))

src/factorization.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ Factorization{T}(A::AdjointFactorization) where {T} =
110110
adjoint(Factorization{T}(parent(A)))
111111
Factorization{T}(A::TransposeFactorization) where {T} =
112112
transpose(Factorization{T}(parent(A)))
113-
inv(F::Factorization{T}) where {T} = (n = size(F, 1); ldiv!(F, Matrix{T}(I, n, n)))
113+
inv(F::Factorization{T}) where {T} = (n = checksquare(F); ldiv!(F, Matrix{T}(I, n, n)))
114114

115115
Base.hash(F::Factorization, h::UInt) = mapreduce(f -> hash(getfield(F, f)), hash, 1:nfields(F); init=h)
116116
Base.:(==)( F::T, G::T) where {T<:Factorization} = all(f -> getfield(F, f) == getfield(G, f), 1:nfields(F))

src/generic.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1821,7 +1821,7 @@ julia> det(BigInt[1 0; 2 2]) # exact integer determinant
18211821
function det(A::AbstractMatrix{T}) where {T}
18221822
if istriu(A) || istril(A)
18231823
S = promote_type(T, typeof((one(T)*zero(T) + zero(T))/one(T)))
1824-
return convert(S, det(UpperTriangular(A)))
1824+
return prod(Base.Fix1(convert, S), @view A[diagind(A)]; init=one(S))
18251825
end
18261826
return det(lu(A; check = false))
18271827
end

src/matmul.jl

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -968,11 +968,13 @@ function __generic_matvecmul!(::typeof(identity), C::AbstractVector, A::Abstract
968968
C[i] = zero(A[i]*B[1] + A[i]*B[1])
969969
end
970970
end
971-
for k = eachindex(B)
972-
aoffs = (k-1)*Astride
973-
b = @stable_muladdmul MulAddMul(alpha,false)(B[k])
974-
for i = eachindex(C)
975-
C[i] += A[aoffs + i] * b
971+
if !iszero(alpha)
972+
for k = eachindex(B)
973+
aoffs = (k-1)*Astride
974+
b = @stable_muladdmul MulAddMul(alpha,false)(B[k])
975+
for i = eachindex(C)
976+
C[i] += A[aoffs + i] * b
977+
end
976978
end
977979
end
978980
end

src/qr.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,28 @@ function ldiv!(A::QRCompactWY{T}, B::AbstractMatrix{T}) where {T}
535535
return B
536536
end
537537

538+
"""
539+
rank(A::QRPivoted{<:Any, T}; atol::Real=0, rtol::Real=min(n,m)*ϵ) where {T}
540+
541+
Compute the numerical rank of the QR factorization `A` by counting how many diagonal entries of
542+
`A.factors` are greater than `max(atol, rtol*Δ₁)` where `Δ₁` is the largest calculated such entry.
543+
This is similar to the [`rank(::AbstractMatrix)`](@ref) method insofar as it counts the number of
544+
(numerically) nonzero coefficients from a matrix factorization, although the default method uses an
545+
SVD instead of a QR factorization. Like [`rank(::SVD)`](@ref), this method also re-uses an existing
546+
matrix factorization.
547+
548+
Using a QR factorization to compute rank should typically produce the same result as using SVD,
549+
although it may be more prone to overestimating the rank in pathological cases where the matrix is
550+
ill-conditioned. It is also worth noting that it is generally faster to compute a QR factorization
551+
than it is to compute an SVD, so this method may be preferred when performance is a concern.
552+
553+
`atol` and `rtol` are the absolute and relative tolerances, respectively.
554+
The default relative tolerance is `n*ϵ`, where `n` is the size of the smallest dimension of `A`
555+
and `ϵ` is the [`eps`](@ref) of the element type of `A`.
556+
557+
!!! compat "Julia 1.12"
558+
The `rank(::QRPivoted)` method requires at least Julia 1.12.
559+
"""
538560
function rank(A::QRPivoted; atol::Real=0, rtol::Real=min(size(A)...) * eps(real(float(eltype(A)))) * iszero(atol))
539561
m = min(size(A)...)
540562
m == 0 && return 0

src/svd.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ function ldiv!(A::SVD{T}, B::AbstractVecOrMat) where T
272272
end
273273

274274
function inv(F::SVD{T}) where T
275+
checksquare(F)
275276
@inbounds for i in eachindex(F.S)
276277
iszero(F.S[i]) && throw(SingularException(i))
277278
end

src/triangular.jl

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -248,16 +248,15 @@ Base.@constprop :aggressive @propagate_inbounds function getindex(A::Union{Lower
248248
_shouldforwardindex(A, b) ? A.data[b] : diagzero(A.data, b)
249249
end
250250

251-
_zero_triangular_half_str(::Type{<:UpperOrUnitUpperTriangular}) = "lower"
252-
_zero_triangular_half_str(::Type{<:LowerOrUnitLowerTriangular}) = "upper"
251+
_zero_triangular_half_str(T::Type) = T <: UpperOrUnitUpperTriangular ? "lower" : "upper"
253252

254-
@noinline function throw_nonzeroerror(T, @nospecialize(x), i, j)
253+
@noinline function throw_nonzeroerror(T::DataType, @nospecialize(x), i, j)
255254
Ts = _zero_triangular_half_str(T)
256255
Tn = nameof(T)
257256
throw(ArgumentError(
258257
lazy"cannot set index in the $Ts triangular part ($i, $j) of an $Tn matrix to a nonzero value ($x)"))
259258
end
260-
@noinline function throw_nononeerror(T, @nospecialize(x), i, j)
259+
@noinline function throw_nononeerror(T::DataType, @nospecialize(x), i, j)
261260
Tn = nameof(T)
262261
throw(ArgumentError(
263262
lazy"cannot set index on the diagonal ($i, $j) of an $Tn matrix to a non-unit value ($x)"))
@@ -303,7 +302,7 @@ end
303302
return A
304303
end
305304

306-
@noinline function throw_setindex_structuralzero_error(T, @nospecialize(x))
305+
@noinline function throw_setindex_structuralzero_error(T::DataType, @nospecialize(x))
307306
Ts = _zero_triangular_half_str(T)
308307
Tn = nameof(T)
309308
throw(ArgumentError(

test/adjtrans.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,4 +749,26 @@ end
749749
end
750750
end
751751

752+
@testset "diagview" begin
753+
for A in (rand(4, 4), rand(ComplexF64,4,4),
754+
fill([1 2; 3 4], 4, 4))
755+
for k in -3:3
756+
@test diagview(A', k) == diag(A', k)
757+
@test diagview(transpose(A), k) == diag(transpose(A), k)
758+
end
759+
@test IndexStyle(diagview(A')) == IndexLinear()
760+
end
761+
end
762+
763+
@testset "triu!/tril!" begin
764+
@testset for sz in ((4,4), (3,4), (4,3))
765+
A = rand(sz...)
766+
B = similar(A)
767+
@testset for f in (adjoint, transpose), k in -3:3
768+
@test triu!(f(copy!(B, A)), k) == triu(f(A), k)
769+
@test tril!(f(copy!(B, A)), k) == tril!(f(A), k)
770+
end
771+
end
772+
end
773+
752774
end # module TestAdjointTranspose

0 commit comments

Comments
 (0)