Skip to content

Implement reverse for more Matrix variants #54231

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 64 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
15ab357
making reverse work for Diagonal, symmetric, Tridiagonal, triangular …
Sahiti004 Apr 24, 2024
f864755
Merge branch 'JuliaLang:master' into changes
Sahiti004 Apr 24, 2024
7a16a73
Update stdlib/LinearAlgebra/src/tridiag.jl
Sahiti004 Apr 24, 2024
634e7af
Update stdlib/LinearAlgebra/src/tridiag.jl
Sahiti004 Apr 24, 2024
4e80715
Update stdlib/LinearAlgebra/src/diagonal.jl
Sahiti004 Apr 24, 2024
ece53d9
Update stdlib/LinearAlgebra/src/hessenberg.jl
Sahiti004 Apr 24, 2024
315526e
Update stdlib/LinearAlgebra/src/symmetric.jl: efficient flipping of data
Sahiti004 Apr 24, 2024
f798a8e
Update stdlib/LinearAlgebra/src/triangular.jl
Sahiti004 Apr 24, 2024
dfb49d1
Update stdlib/LinearAlgebra/src/triangular.jl
Sahiti004 Apr 24, 2024
c1c2e46
Update stdlib/LinearAlgebra/src/triangular.jl
Sahiti004 Apr 24, 2024
3eb00e7
Update stdlib/LinearAlgebra/src/hessenberg.jl
Sahiti004 Apr 24, 2024
4b8c853
Update stdlib/LinearAlgebra/src/symmetric.jl
Sahiti004 Apr 24, 2024
12192d3
Update stdlib/LinearAlgebra/src/symmetric.jl
Sahiti004 Apr 24, 2024
882ea0c
Update stdlib/LinearAlgebra/src/symmetric.jl
Sahiti004 Apr 24, 2024
798614c
Update stdlib/LinearAlgebra/src/hessenberg.jl
Sahiti004 Apr 24, 2024
888b59f
Update stdlib/LinearAlgebra/src/bidiag.jl
Sahiti004 Apr 24, 2024
3b9b323
Update stdlib/LinearAlgebra/src/symmetric.jl
Sahiti004 Apr 24, 2024
4b56e40
Update stdlib/LinearAlgebra/src/triangular.jl
Sahiti004 Apr 24, 2024
a9ad942
Update stdlib/LinearAlgebra/src/bidiag.jl
Sahiti004 Apr 24, 2024
1316977
Update stdlib/LinearAlgebra/src/triangular.jl
Sahiti004 Apr 24, 2024
a009adc
Update stdlib/LinearAlgebra/src/triangular.jl
Sahiti004 Apr 24, 2024
9d543d4
Update stdlib/LinearAlgebra/src/hessenberg.jl
Sahiti004 Apr 24, 2024
4a6009f
Update stdlib/LinearAlgebra/src/symmetric.jl
Sahiti004 Apr 24, 2024
3f1bce8
Update tridiag.jl teset for both even and odd
Sahiti004 Apr 24, 2024
15d747d
Update stdlib/LinearAlgebra/test/diagonal.jl
Sahiti004 Apr 24, 2024
743f3c5
Update stdlib/LinearAlgebra/test/tridiag.jl
Sahiti004 Apr 24, 2024
fe99777
Update tridiag.jl
Sahiti004 Apr 24, 2024
05973cc
Update stdlib/LinearAlgebra/src/symmetric.jl
Sahiti004 Apr 24, 2024
3e40d3c
Update stdlib/LinearAlgebra/test/tridiag.jl
Sahiti004 Apr 25, 2024
dceb4ef
Update tridiag.jl remove test for even n in symtridiagonal
Sahiti004 Apr 25, 2024
8677953
Update tridiag.jl
Sahiti004 Apr 25, 2024
f7424e1
Update stdlib/LinearAlgebra/src/tridiag.jl
Sahiti004 Apr 25, 2024
298a0fc
Update stdlib/LinearAlgebra/src/tridiag.jl
Sahiti004 Apr 25, 2024
543c88a
Update stdlib/LinearAlgebra/src/tridiag.jl
Sahiti004 Apr 26, 2024
3f5f3da
Update stdlib/LinearAlgebra/src/tridiag.jl
Sahiti004 Apr 26, 2024
e368c1f
Update triangular.jl removed whitespace
Sahiti004 Apr 26, 2024
b609e1e
Update diagonal.jl removed whitespace
Sahiti004 Apr 26, 2024
13209b3
Update hessenberg.jl remove whitespace
Sahiti004 Apr 26, 2024
ddcf5eb
Update hessenberg.jl
Sahiti004 Apr 28, 2024
2a1ae8c
Update symmetric.jl
Sahiti004 May 2, 2024
8c0956f
Update abstractarray.jl
Sahiti004 May 2, 2024
d6d70d3
Update test/abstractarray.jl
Sahiti004 May 2, 2024
d779ead
Update diagonal.jl
Sahiti004 May 2, 2024
4f19dee
Update stdlib/LinearAlgebra/test/symmetric.jl
Sahiti004 May 2, 2024
cbcc431
Update stdlib/LinearAlgebra/test/triangular.jl
Sahiti004 May 2, 2024
6e6c321
Update stdlib/LinearAlgebra/test/triangular.jl
Sahiti004 May 2, 2024
a2da2a6
Update stdlib/LinearAlgebra/test/diagonal.jl
Sahiti004 May 2, 2024
fccf3c2
Update stdlib/LinearAlgebra/test/hessenberg.jl
Sahiti004 May 2, 2024
aef6292
Update stdlib/LinearAlgebra/test/symmetric.jl
Sahiti004 May 2, 2024
1948c0b
Update stdlib/LinearAlgebra/test/tridiag.jl
Sahiti004 May 3, 2024
51d73ef
Update stdlib/LinearAlgebra/test/tridiag.jl
Sahiti004 May 3, 2024
775ee20
Update stdlib/LinearAlgebra/test/triangular.jl
Sahiti004 May 3, 2024
f96d9b6
Update stdlib/LinearAlgebra/test/triangular.jl
Sahiti004 May 3, 2024
45d89cd
Update stdlib/LinearAlgebra/test/symmetric.jl
Sahiti004 May 3, 2024
030efd9
Update stdlib/LinearAlgebra/test/symmetric.jl
Sahiti004 May 3, 2024
78f388c
Update stdlib/LinearAlgebra/test/diagonal.jl
Sahiti004 May 3, 2024
82af8e4
Update stdlib/LinearAlgebra/test/diagonal.jl
Sahiti004 May 3, 2024
a1da157
Update stdlib/LinearAlgebra/test/bidiag.jl
Sahiti004 May 3, 2024
9951a48
Update symmetric.jl
Sahiti004 May 3, 2024
3984b74
Merge branch 'master' into changes
dkarrasch May 20, 2024
2e42cc7
clean-up and fixes
dkarrasch May 21, 2024
83eddd9
Update stdlib/LinearAlgebra/test/triangular.jl
dkarrasch May 21, 2024
f32a783
Update abstractarray.jl: specify eltype
dkarrasch May 21, 2024
96f6180
minor fixes
dkarrasch May 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions stdlib/LinearAlgebra/src/bidiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,10 @@ end
return x
end

Base._reverse(A::Bidiagonal, dims) = reverse!(Matrix(A); dims)
Base._reverse(A::Bidiagonal, dims::Colon) = Bidiagonal(reverse(A.dv), reverse(A.ev), A.uplo)
Base._reverse!(A::Bidiagonal, dims::Colon) = (reverse!(A.dv); reverse!(A.ev); A)

## structured matrix methods ##
function Base.replace_in_print_matrix(A::Bidiagonal,i::Integer,j::Integer,s::AbstractString)
if A.uplo == 'U'
Expand Down
6 changes: 5 additions & 1 deletion stdlib/LinearAlgebra/src/diagonal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,10 @@ end
diagzero(::Diagonal{T}, i, j) where {T} = zero(T)
diagzero(D::Diagonal{<:AbstractMatrix{T}}, i, j) where {T} = zeros(T, size(D.diag[i], 1), size(D.diag[j], 2))

Base._reverse(A::Diagonal, dims) = reverse!(Matrix(A); dims)
Base._reverse(A::Diagonal, dims::Colon) = Diagonal(reverse(A.diag))
Base._reverse!(A::Diagonal, dims::Colon) = (reverse!(A.diag); A)

function setindex!(D::Diagonal, v, i::Int, j::Int)
@boundscheck checkbounds(D, i, j)
if i == j
Expand Down Expand Up @@ -946,4 +950,4 @@ end

function Base.muladd(A::Diagonal, B::Diagonal, z::Diagonal)
Diagonal(A.diag .* B.diag .+ z.diag)
end
end
4 changes: 4 additions & 0 deletions stdlib/LinearAlgebra/src/hessenberg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ Base.isassigned(H::UpperHessenberg, i::Int, j::Int) =
Base.@propagate_inbounds getindex(H::UpperHessenberg{T}, i::Integer, j::Integer) where {T} =
i <= j+1 ? convert(T, H.data[i,j]) : zero(T)

Base._reverse(A::UpperHessenberg, dims) = reverse(Matrix(A); dims)
Base._reverse(A::UpperHessenberg, dims::Colon) = (reverse(Matrix(A)), A.data)
Base._reverse!(A::UpperHessenberg, dims::Colon) = (reverse!(A.data); A)

Base.@propagate_inbounds function setindex!(A::UpperHessenberg, x, i::Integer, j::Integer)
if i > j+1
x == 0 || throw(ArgumentError("cannot set index in the lower triangular part " *
Expand Down
8 changes: 8 additions & 0 deletions stdlib/LinearAlgebra/src/symmetric.jl
Original file line number Diff line number Diff line change
Expand Up @@ -254,11 +254,19 @@ end
end
end

Base._reverse(A::Symmetric, dims::Integer) = (reverse((Matrix(A)); dims))
Base._reverse(A::Symmetric, dims::Colon) = Symmetric(reverse(Matrix(A)))
Base._reverse!(A::Symmetric, dims::Colon) = (reverse!(A.data); A)

@propagate_inbounds function setindex!(A::Symmetric, v, i::Integer, j::Integer)
i == j || throw(ArgumentError("Cannot set a non-diagonal index in a symmetric matrix"))
setindex!(A.data, v, i, j)
end

Base._reverse(A::Hermitian, dims) = Hermitian(reverse(Matrix(A)); dims)
Base._reverse(A::Hermitian, dims::Colon) = Hermitian(reverse(Matrix(A)))
Base._reverse!(A::Hermitian, dims::Colon) = (reverse!(A.data); A)

@propagate_inbounds function setindex!(A::Hermitian, v, i::Integer, j::Integer)
if i != j
throw(ArgumentError("Cannot set a non-diagonal index in a Hermitian matrix"))
Expand Down
9 changes: 9 additions & 0 deletions stdlib/LinearAlgebra/src/triangular.jl
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,11 @@ Base.isstored(A::UpperTriangular, i::Int, j::Int) =
@propagate_inbounds getindex(A::UpperTriangular, i::Integer, j::Integer) =
i <= j ? A.data[i,j] : _zero(A.data,j,i)

Base._reverse(A::UpperTriangular, dims::Integer) = (reverse((Matrix(A)); dims))
Base._reverse(A::UpperTriangular, dims::Colon) = (reverse(Matrix(A)))
Base._reverse!(A::UpperTriangular, dims::Colon) = UpperTriangular(reverse!(A.data); A)


@propagate_inbounds function setindex!(A::UpperTriangular, x, i::Integer, j::Integer)
if i > j
iszero(x) || throw(ArgumentError("cannot set index in the lower triangular part " *
Expand All @@ -295,6 +300,10 @@ end
return A
end

Base._reverse(A::LowerTriangular, dims) = LowerTriangular(reverse((Matrix(A)); dims))
Base._reverse(A::LowerTriangular, dims::Colon) = LowerTriangular(reverse(Matrix(A)))
Base._reverse!(A::LowerTriangular, dims::Colon) = (reverse!(A.data); A)

@propagate_inbounds function setindex!(A::LowerTriangular, x, i::Integer, j::Integer)
if i < j
iszero(x) || throw(ArgumentError("cannot set index in the upper triangular part " *
Expand Down
8 changes: 8 additions & 0 deletions stdlib/LinearAlgebra/src/tridiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,10 @@ end
end
end

Base._reverse(A::SymTridiagonal, dims) = reverse!(Matrix(A); dims)
Base._reverse(A::SymTridiagonal, dims::Colon) = SymTridiagonal(reverse(A.dv), reverse(A.ev))
Base._reverse!(A::SymTridiagonal, dims::Colon) = (reverse!(A.dv); reverse!(A.ev); A)

@inline function setindex!(A::SymTridiagonal, x, i::Integer, j::Integer)
@boundscheck checkbounds(A, i, j)
if i == j
Expand Down Expand Up @@ -693,6 +697,10 @@ end
end
end

Base._reverse(A::Tridiagonal, dims) = reverse!(Matrix(A); dims)
Base._reverse(A::Tridiagonal, dims::Colon) = Tridiagonal(reverse(A.dl), reverse(A.d), reverse(A.du))
Base._reverse!(A::Tridiagonal, dims::Colon) = (reverse!(A.dl); reverse!(A.d); reverse!(A.du); A)

@inline function setindex!(A::Tridiagonal, x, i::Integer, j::Integer)
@boundscheck checkbounds(A, i, j)
if i == j
Expand Down
11 changes: 11 additions & 0 deletions stdlib/LinearAlgebra/test/bidiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -904,6 +904,17 @@ end
@test mul!(C1, B, sv, 1, 2) == mul!(C2, B, v, 1 ,2)
end

@testset "Reverse operation on Bidiagonal" begin
n = 5
d = randn(n)
e = randn(n - 1)
B = Bidiagonal(d, e)
@test reverse(B, dims=1) == reverse(Matrix(B), dims=1)
@test reverse(B, dims=2) == reverse(Matrix(B), dims=2)
@test reverse(B) == reverse(Matrix(B))
end


@testset "Matrix conversion for non-numeric and undef" begin
B = Bidiagonal(Vector{BigInt}(undef, 4), fill(big(3), 3), :U)
M = Matrix(B)
Expand Down
19 changes: 19 additions & 0 deletions stdlib/LinearAlgebra/test/diagonal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ Random.seed!(1)
@test_throws MethodError convert(Diagonal, [1,2,3,4])
@test_throws DimensionMismatch convert(Diagonal, [1 2 3 4])
@test_throws InexactError convert(Diagonal, ones(2,2))

# Test reversing
# Test reversing along rows
@test reverse(D, dims=1) == reverse(Matrix(D), dims=1)

# Test reversing along columns
@test reverse(D, dims=2) == reverse(Matrix(D), dims=2)

# Test reversing the entire matrix
@test reverse(D) == reverse(Matrix(D))
end

@testset "Basic properties" begin
Expand Down Expand Up @@ -609,6 +619,15 @@ end
end
end

@testset "Test reverse" begin
d = randn(n)
D = Diagonal(d)
@test reverse(D, dims=1) == reverse(Matrix(D), dims=1)
@test reverse(D, dims=2) == reverse(Matrix(D), dims=2)
@test reverse(D) == reverse(Matrix(D))
end


@testset "inverse" begin
for d in Any[randn(n), Int[], [1, 2, 3], [1im, 2im, 3im], [1//1, 2//1, 3//1], [1+1im//1, 2//1, 3im//1]]
D = Diagonal(d)
Expand Down
7 changes: 7 additions & 0 deletions stdlib/LinearAlgebra/test/hessenberg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,13 @@ let n = 10
end
end

@testset "Reverse operation on UpperHessenberg" begin
A = UpperHessenberg(randn(n, n))
@test reverse(A, dims=1) == reverse(Matrix(A), dims=1)
@test reverse(A, dims=2) == reverse(Matrix(A), dims=2)
@test reverse(A) == reverse(Matrix(A))
end

@testset "hessenberg(::AbstractMatrix)" begin
n = 10
A = Tridiagonal(rand(n-1), rand(n), rand(n-1))
Expand Down
15 changes: 15 additions & 0 deletions stdlib/LinearAlgebra/test/symmetric.jl
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,21 @@ end
end
end

@testset "Reverse operation on Symmetric" begin
A = Symmetric(randn(n, n))
@test reverse(A, dims=1) == reverse(Matrix(A), dims=1)
@test reverse(A, dims=2) == reverse(Matrix(A), dims=2)
@test reverse(A) == reverse(Matrix(A))
end

@testset "Reverse operation on Hermitian" begin
A = Hermitian(randn(ComplexF64, n, n))
@test reverse(A, dims=1) == reverse(Matrix(A), dims=1)
@test reverse(A, dims=2) == reverse(Matrix(A), dims=2)
@test reverse(A) == reverse(Matrix(A))
end


# bug identified in PR #52318: dot products of quaternionic Hermitian matrices,
# or any number type where conj(a)*conj(b) ≠ conj(a*b):
@testset "dot Hermitian quaternion #52318" begin
Expand Down
16 changes: 16 additions & 0 deletions stdlib/LinearAlgebra/test/triangular.jl
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,22 @@ end
# Issue 16196
@test UpperTriangular(Matrix(1.0I, 3, 3)) \ view(fill(1., 3), [1,2,3]) == fill(1., 3)


@testset "Reverse operation on UpperTriangular" begin
A = UpperTriangular(randn(n, n))
@test reverse(A, dims=1) == reverse(Matrix(A), dims=1)
@test reverse(A, dims=2) == reverse(Matrix(A), dims=2)
@test reverse(A) == reverse(Matrix(A))
end

@testset "Reverse operation on LowerTriangular" begin
A = LowerTriangular(randn(n, n))
@test reverse(A, dims=1) == reverse(Matrix(A), dims=1)
@test reverse(A, dims=2) == reverse(Matrix(A), dims=2)
@test reverse(A) == reverse(Matrix(A))
end


# dimensional correctness:
const BASE_TEST_PATH = joinpath(Sys.BINDIR, "..", "share", "julia", "test")
isdefined(Main, :Furlongs) || @eval Main include(joinpath($(BASE_TEST_PATH), "testhelpers", "Furlongs.jl"))
Expand Down
22 changes: 22 additions & 0 deletions stdlib/LinearAlgebra/test/tridiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,28 @@ end
@test axes(B) === (ax, ax)
end

@testset "Reverse operation on Tridiagonal" begin
n = 5
d = randn(n)
dl = randn(n - 1)
du = randn(n - 1)
T = Tridiagonal(dl, d, du)
@test reverse(T, dims=1) == reverse(Matrix(T), dims=1)
@test reverse(T, dims=2) == reverse(Matrix(T), dims=2)
@test reverse(T) == reverse(Matrix(T))
end

@testset "Reverse operation on SymTridiagonal" begin
n = 5
d = randn(n)
dl = randn(n - 1)
ST = SymTridiagonal(d, dl)
@test reverse(ST, dims=1) == reverse(Matrix(ST), dims=1)
@test reverse(ST, dims=2) == reverse(Matrix(ST), dims=2)
@test reverse(ST) == reverse(Matrix(ST))
end


@testset "Matrix conversion for non-numeric and undef" begin
T = Tridiagonal(fill(big(3), 3), Vector{BigInt}(undef, 4), fill(big(3), 3))
M = Matrix(T)
Expand Down