-
Notifications
You must be signed in to change notification settings - Fork 10
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
Add one
and copy
for Diagonal
#52
Conversation
src/infarrays.jl
Outdated
@@ -202,6 +202,8 @@ end | |||
# Diagonal | |||
##### | |||
|
|||
one(D::Diagonal{T,<:AbstractFill}) where T = Eye{T}(size(D,1)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This counts as "type piracy": it changes behaviour of FillArrays.jl which is bad.
Instead restrict to the infinite case:
one(D::Diagonal{T,<:AbstractFill{T,Tuple{OneToInf{Int}}}) where T = Eye{T}(size(D,1))
copy(D::Diagonal{T,<:AbstractFill{T,Tuple{OneToInf{Int}}}) where T = D
Though this could be refined to allow for infinite offset indexing.
test/runtests.jl
Outdated
@@ -627,6 +627,7 @@ end | |||
|
|||
@test Eye{Int}(∞) * D ≡ Eye{Int}(∞) * D ≡ D | |||
@test Eye(∞) * D == Eye(∞) * D == D | |||
@test Eye(∞) == Eye(∞)^0 == Eye(∞)^1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add tests for one
and copy
directly as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add tests that Eye(∞) == Eye(∞)^2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add tests for Diagonal(Fill(2,∞))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^2
shouldn't be a problem because LinearAlgebra
deals with matrix powers like this:
# base\intfuncs.jl:243
function power_by_squaring(x_, p::Integer)
x = to_power_type(x_)
if p == 1
return copy(x)
elseif p == 0
return one(x)
elseif p == 2
return x*x
elseif p < 0
isone(x) && return copy(x)
isone(-x) && return iseven(p) ? one(x) : copy(x)
throw_domerr_powbysq(x, p)
end
t = trailing_zeros(p) + 1
p >>= t
while (t -= 1) > 0
x *= x
end
y = x
while p > 0
t = trailing_zeros(p) + 1
p >>= t
while (t -= 1) >= 0
x *= x
end
y *= x
end
return y
end
I added the test anyway.
Actually I encountered this problem when doing
|
The right place to do this is in ArrayLayouts.jl. It's not possible to do this for every array but we can do it for _one(_, _, d::AbstractMatrix{T}) where T = Base.invoke(one, Tuple{AbstractMatrix{T}}, d) # standard def
function _one(::DiagonalLayout, _, d::AbstractMatrix{T}) where T
m,n = size(d)
m==n || throw(DimensionMismatch("multiplicative identity defined only for square matrices"))
Eye{T}(m)
end
# ... Tridiagonal, etc., special cases
one(d::LayoutMatrix) = _one(MemoryLayout(d), axes(d), d)
one(d::SubArray{<:Any,2,<:LayoutMatrix}) = _one(MemoryLayout(d), axes(d), d)
one(d::Diagonal{<:Any,<:LayoutMatrix}) = _one(MemoryLayout(d), axes(d), d)
one(d::Tridiagonal{<:Any,<:LayoutVector}) = _one(MemoryLayout(d), axes(d), d)
one(d::SymTridiagonal{<:Any,<:LayoutVector}) = _one(MemoryLayout(d), axes(d), d) Then in BandedMatrices.jl: function _one(::AbstractBandedLayout, _, d::AbstractMatrix{T}) where T
m,n = size(d)
m==n || throw(DimensionMismatch("multiplicative identity defined only for square matrices"))
convert(BandedMatrix, Eye{T}(m))
end |
Codecov Report
@@ Coverage Diff @@
## master #52 +/- ##
==========================================
+ Coverage 77.44% 77.51% +0.07%
==========================================
Files 4 4
Lines 625 627 +2
==========================================
+ Hits 484 486 +2
Misses 141 141
Continue to review full report at Codecov.
|
#50
JuliaArrays/FillArrays.jl#126