Skip to content

Commit

Permalink
Doc Strings
Browse files Browse the repository at this point in the history
  • Loading branch information
francescoalemanno committed Mar 6, 2020
1 parent a3dc2b0 commit 6f1e177
Showing 1 changed file with 141 additions and 62 deletions.
203 changes: 141 additions & 62 deletions src/DefaultArrays.jl
Original file line number Diff line number Diff line change
@@ -1,78 +1,157 @@
module DefaultArrays
import Base.size
import Base.getindex
import Base.setindex!
import Base.@propagate_inbounds
import Base.IndexStyle
import Base.BroadcastStyle

export DefaultArray,eachnondefault
struct DefaultArray{T,N} <: AbstractArray{T,N}
default::T
size::NTuple{N,Int}
elements::Dict{Int,T}
end
import Base.similar
import Base.size
import Base.getindex
import Base.setindex!
import Base.@propagate_inbounds
import Base.IndexStyle
import Base.BroadcastStyle

@inline IndexStyle(::DefaultArray) = IndexLinear()
export DefaultArray, eachnondefault
struct DefaultArray{T,N} <: AbstractArray{T,N}
default::T
size::NTuple{N,Int}
elements::Dict{Int,T}
end
import Base.similar

function DefaultArray(default::T, size::NTuple{N,Int}) where {T,N}
DefaultArray(default, size, Dict{Int,T}())
end
function DefaultArray(default,size::Int...)
DefaultArray(default, size)
end
function DefaultArray(default::T, A::AbstractArray{T,N}) where {T,N}
ret=DefaultArray(default,size(A))
ret.=A
ret
end
function DefaultArray(A::AbstractArray)
DefaultArray(zero(eltype(A)),A)
end
function DefaultArray(A::DefaultArray)
A
end
@inline IndexStyle(::DefaultArray) = IndexLinear()

function DefaultArray(default::T, size::NTuple{N,Int}) where {T,N}
DefaultArray(default, size, Dict{Int,T}())
end

@inline size(A::DefaultArray) = A.size
function DefaultArray(default, size::Int...)
DefaultArray(default, size)
end

similar(A::DefaultArray, ::Type{T}, dims::Dims) where {T} = DefaultArray(convert(T,A.default), dims)
function DefaultArray(default::T, A::AbstractArray{T,N}) where {T,N}
ret = DefaultArray(default, size(A))
ret .= A
ret
end
function DefaultArray(A::AbstractArray)
DefaultArray(zero(eltype(A)), A)
end
function DefaultArray(A::DefaultArray)
A
end

@inline function getindex(A::DefaultArray, i::Int)
@boundscheck checkbounds(A,i)
get(A.elements, i, A.default)
end
@inline size(A::DefaultArray) = A.size

@inline function setindex!(A::DefaultArray, v, i::Int)
@boundscheck checkbounds(A,i)
if v == A.default
haskey(A.elements,i) || delete!(A.elements,i)
else
A.elements[i] = v
end
v
end
similar(A::DefaultArray, ::Type{T}, dims::Dims) where {T} =
DefaultArray(convert(T, A.default), dims)

@inline function getindex(A::DefaultArray, i::Int)
@boundscheck checkbounds(A, i)
get(A.elements, i, A.default)
end

@inline function eachnondefault(A::DefaultArray)
@inbounds (i for i in eachindex(A.elements) if A.elements[i]!=A.default)
@inline function setindex!(A::DefaultArray, v, i::Int)
@boundscheck checkbounds(A, i)
if v == A.default
haskey(A.elements, i) || delete!(A.elements, i)
else
A.elements[i] = v
end
v
end

@inline function eachnondefault(A::DefaultArray)
eachnondefault(A,IndexStyle(A))
end

@inline BroadcastStyle(::Type{<:DefaultArray{T}}) where {T} = Broadcast.ArrayStyle{DefaultArray{T}}()
@inline function eachnondefault(A::DefaultArray,Type::IndexLinear)
@inbounds (i for i in eachindex(A.elements) if A.elements[i] != A.default)
end

function similar(bc::Broadcast.Broadcasted{Broadcast.ArrayStyle{DefaultArray{T}}}, ::Type{ElType}) where {ElType,T}
da = find_defaultarray(bc)
va,_ =promote(da.default,zero(ElType))
gooddefault=ifelse(typeof(va)==ElType, va, zero(ElType))
return DefaultArray(gooddefault::ElType,size(bc))
end
@inline function eachnondefault(A::DefaultArray,Type::IndexCartesian)
B=CartesianIndices(A)
@inbounds (B[i] for i in eachindex(A.elements) if A.elements[i] != A.default)
end

@inline BroadcastStyle(::Type{<:DefaultArray{T}}) where {T} =
Broadcast.ArrayStyle{DefaultArray{T}}()

function similar(bc::Broadcast.Broadcasted{Broadcast.ArrayStyle{DefaultArray{T}}}, ::Type{ElType}) where {ElType,T}
da = find_defaultarray(bc)
va, _ = promote(da.default, zero(ElType))
gooddefault = ifelse(typeof(va) == ElType, va, zero(ElType))
return DefaultArray(gooddefault::ElType, size(bc))
end


@inline find_defaultarray(bc::Base.Broadcast.Broadcasted) = find_defaultarray(bc.args)
@inline find_defaultarray(bc::Base.Broadcast.Extruded) = find_defaultarray(bc.x)
@inline find_defaultarray(args::Tuple) = find_defaultarray(find_defaultarray(args[1]), Base.tail(args))
@inline find_defaultarray(x) = x
@inline find_defaultarray(a::DefaultArray, rest) = a
@inline find_defaultarray(a::Any, rest) = find_defaultarray(rest)

"""
eachnondefault(A::DefaultArray, indexstyle = IndexLinear())
Create an generator object for visiting each index of a `DefaultArray A` containing a non-default value, in an efficient manner.
Example:
```julia
julia> A = DefaultArray(1,[1 2; 3 4]);
julia> for i in eachnondefault(A) # linear indexing
println(i, " ", A[i])
end
4 4
2 3
3 2
```
notice how the value "1" has been skipped, since we set 1 as the default value.
```julia
julia> A = DefaultArray(1,[1 2; 3 4]);
julia> for i in eachnondefault(A,IndexCartesian()) # cartesian indexing
println(i, " ", A[i])
end
CartesianIndex(2, 2) 4
CartesianIndex(2, 1) 3
CartesianIndex(1, 2) 2
```
"""
eachnondefault

"""
DefaultArray(default, size...)
Create a DefaultArray
Example 1:
```julia
julia> DefaultArray("X",3,3)
3×3 DefaultArray{String,2}:
"X" "X" "X"
"X" "X" "X"
"X" "X" "X"
```
Example 2:
```julia
julia> DefaultArray(false,3,4)
3×4 DefaultArray{Bool,2}:
0 0 0 0
0 0 0 0
0 0 0 0
```
DefaultArray(default, A::AbstractArray)
@inline find_defaultarray(bc::Base.Broadcast.Broadcasted) = find_defaultarray(bc.args)
@inline find_defaultarray(bc::Base.Broadcast.Extruded) = find_defaultarray(bc.x)
@inline find_defaultarray(args::Tuple) = find_defaultarray(find_defaultarray(args[1]), Base.tail(args))
@inline find_defaultarray(x) = x
@inline find_defaultarray(a::DefaultArray, rest) = a
@inline find_defaultarray(a::Any, rest) = find_defaultarray(rest)
Example 3:
```julia
DefaultArray(false,rand(Bool,5,5))
5×5 DefaultArray{Bool,2}:
1 0 0 1 0
1 1 1 1 1
1 1 1 0 0
0 1 0 0 1
0 0 1 1 0
```
"""
DefaultArray
end # module

2 comments on commit 6f1e177

@francescoalemanno
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request updated: JuliaRegistries/General/10476

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if Julia TagBot is installed, or can be done manually through the github interface, or via:

git tag -a v1.0.0 -m "<description of version>" 6f1e1770fcffb8a7e290b4b7f5538d30da91c5c4
git push origin v1.0.0

Please sign in to comment.