Skip to content

Commit cbd854b

Browse files
dalumEvey Dee
andauthored
Add range indexing to UniformScaling (#24359)
* Add range indexing to UniformScaling * Add tests * Return sparse matrix when indexing UniformScaling * start -> first * Correctly handle non-integer steps * Make getindex(::UniformScaling, ranges...) return a dense array * Remove unneccessary (and slower) branch * Add (range, integer) indexing to UniformScaling * Update tests * Fix unbound param * Add NEWS item * Update docstring and add compat annotation Co-authored-by: Evey Dee <eveydee@users.noreply.github.com>
1 parent e74c957 commit cbd854b

File tree

3 files changed

+59
-4
lines changed

3 files changed

+59
-4
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ Standard library changes
5050

5151
#### LinearAlgebra
5252
* New method `LinearAlgebra.issuccess(::CholeskyPivoted)` for checking whether pivoted Cholesky factorization was successful ([#36002]).
53+
* `UniformScaling` can now be indexed into using ranges to return dense matrices and vectors ([#24359]).
5354

5455
#### Markdown
5556

stdlib/LinearAlgebra/src/uniformscaling.jl

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,13 @@ import Base: copy, adjoint, getindex, show, transpose, one, zero, inv,
66
"""
77
UniformScaling{T<:Number}
88
9-
Generically sized uniform scaling operator defined as a scalar times the
10-
identity operator, `λ*I`. See also [`I`](@ref).
9+
Generically sized uniform scaling operator defined as a scalar times
10+
the identity operator, `λ*I`. Although without an explicit `size`, it
11+
acts similarly to a matrix in many cases and includes support for some
12+
indexing. See also [`I`](@ref).
13+
14+
!!! compat "Julia 1.6"
15+
Indexing using ranges is available as of Julia 1.6.
1116
1217
# Examples
1318
```jldoctest
@@ -24,6 +29,11 @@ julia> J*A
2429
2×2 Array{Float64,2}:
2530
2.0 4.0
2631
6.0 8.0
32+
33+
julia> J[1:2, 1:2]
34+
2×2 Array{Float64,2}:
35+
2.0 0.0
36+
0.0 2.0
2737
```
2838
"""
2939
struct UniformScaling{T<:Number}
@@ -78,6 +88,28 @@ ndims(J::UniformScaling) = 2
7888
Base.has_offset_axes(::UniformScaling) = false
7989
getindex(J::UniformScaling, i::Integer,j::Integer) = ifelse(i==j,J.λ,zero(J.λ))
8090

91+
getindex(x::UniformScaling, n::Integer, m::AbstractRange{<:Integer}) = getindex(x, m, n)
92+
function getindex(x::UniformScaling{T}, n::AbstractRange{<:Integer}, m::Integer) where T
93+
v = zeros(T, length(n))
94+
@inbounds for (i,ii) in enumerate(n)
95+
if ii == m
96+
v[i] = x.λ
97+
end
98+
end
99+
return v
100+
end
101+
102+
103+
function getindex(x::UniformScaling{T}, n::AbstractRange{<:Integer}, m::AbstractRange{<:Integer}) where T
104+
A = zeros(T, length(n), length(m))
105+
@inbounds for (j,jj) in enumerate(m), (i,ii) in enumerate(n)
106+
if ii == jj
107+
A[i,j] = x.λ
108+
end
109+
end
110+
return A
111+
end
112+
81113
function show(io::IO, ::MIME"text/plain", J::UniformScaling)
82114
s = "$(J.λ)"
83115
if occursin(r"\w+\s*[\+\-]\s*\w+", s)

stdlib/LinearAlgebra/test/uniformscaling.jl

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ using .Main.Quaternions
1111
Random.seed!(123)
1212

1313
@testset "basic functions" begin
14-
@test I[1,1] == 1 # getindex
15-
@test I[1,2] == 0 # getindex
1614
@test I === I' # transpose
1715
@test ndims(I) == 2
1816
@test one(UniformScaling{Float32}) == UniformScaling(one(Float32))
@@ -27,6 +25,30 @@ Random.seed!(123)
2725
@test opnorm(UniformScaling(1+im)) sqrt(2)
2826
end
2927

28+
@testset "getindex" begin
29+
@test I[1,1] == 1
30+
@test I[1,2] == 0
31+
32+
J = I(15)
33+
for (a, b) in [
34+
# indexing that returns a Vector
35+
(1:10, 1),
36+
(4, 1:10),
37+
(11, 1:10),
38+
# indexing that returns a Matrix
39+
(1:2, 1:2),
40+
(1:2:3, 1:2:3),
41+
(1:2:8, 2:2:9),
42+
(1:2:8, 9:-4:1),
43+
(9:-4:1, 1:2:8),
44+
(2:3, 1:2),
45+
(2:-1:1, 1:2),
46+
(1:2:9, 5:2:13),
47+
]
48+
@test I[a,b] == J[a,b]
49+
end
50+
end
51+
3052
@testset "sqrt, exp, log, and trigonometric functions" begin
3153
# convert to a dense matrix with random size
3254
M(J) = (N = rand(1:10); Matrix(J, N, N))

0 commit comments

Comments
 (0)