Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion REQUIRE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
julia 0.5
julia 0.6
Images
Interpolations
AffineTransforms 0.2.1
Expand Down
24 changes: 12 additions & 12 deletions src/CachedInterpolations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ A single `CachedInterpolation` represents a "movable"
i_2)`. An array of these objects thus implements an array-of-arrays
interface. Create them with `cachedinterpolators`.
"""
type CachedInterpolation{T,N,M,O,K} <: AbstractInterpolation{T,N,BSpline{Quadratic{InPlace}},OnCell}
mutable struct CachedInterpolation{T,N,M,O,K} <: AbstractInterpolation{T,N,BSpline{Quadratic{InPlace}},OnCell}
# Note: M = N+K
coefs::Array{T,M} # tiled array of 3x3x... buffers
parent::Array{T,M} # the overall array (`P` in the documentation above)
Expand All @@ -57,12 +57,12 @@ type CachedInterpolation{T,N,M,O,K} <: AbstractInterpolation{T,N,BSpline{Quadrat
end

const splitN = Base.IteratorsMD.split
Base.size{T,N}(itp::CachedInterpolation{T,N}) = splitN(size(itp.parent), Val{N})[1]
Base.size{T,N}(itp::CachedInterpolation{T,N}, d) = d <= N ? size(itp.parent, d) : 1
Base.size(itp::CachedInterpolation{T,N}) where {T,N} = splitN(size(itp.parent), Val{N})[1]
Base.size(itp::CachedInterpolation{T,N}, d) where {T,N} = d <= N ? size(itp.parent, d) : 1

Base.indices{T,N,M,O}(itp::CachedInterpolation{T,N,M,O}) =
Base.indices(itp::CachedInterpolation{T,N,M,O}) where {T,N,M,O} =
map((x,o)->x-o, splitN(indices(itp.parent), Val{N})[1], O)
Base.indices{T,N,M,O}(itp::CachedInterpolation{T,N,M,O}, d) =
Base.indices(itp::CachedInterpolation{T,N,M,O}, d) where {T,N,M,O} =
d <= N ? indices(itp.parent, d) - O[d] : Base.OneTo(1)

"""
Expand All @@ -87,7 +87,7 @@ coordinates within a tile. For example, one can mimic a
`CenterIndexedArray` when `size(parent, d)` is odd for the first `N`
dimensions and you supply `origin = (div(size(parent,1)+1, 2), ...)`.
"""
function cachedinterpolators{T,M}(parent::Array{T,M}, N, origin=ntuple(d->0,N))
function cachedinterpolators(parent::Array{T,M}, N, origin=ntuple(d->0,N)) where {T,M}
0 <= N <= M || error("N must be between 0 and $M")
length(origin) == N || throw(DimensionMismatch("length(origin) = $(length(origin)) is inconsistent with $N interpolating dimensions"))
sz3 = ntuple(d->d<=N ? 3 : size(parent,d), M)::NTuple{M,Int}
Expand All @@ -100,15 +100,15 @@ function cachedinterpolators{T,M}(parent::Array{T,M}, N, origin=ntuple(d->0,N))
end

# function-barriered to circumvent type-instability in sztiles
@noinline function cachedinterpolators{T,N,M,K}(buffer::Array{T,M}, parent::Array{T,M}, origin::NTuple{N,Int}, center::NTuple{N,Int}, sztiles::NTuple{K,Int})
@noinline function cachedinterpolators(buffer::Array{T,M}, parent::Array{T,M}, origin::NTuple{N,Int}, center::NTuple{N,Int}, sztiles::NTuple{K,Int}) where {T,N,M,K}
itps = Array{CachedInterpolation{T,N,M,origin}}(sztiles)
for tileindex in CartesianRange(sztiles)
itps[tileindex] = CachedInterpolation{T,N,M,origin,K}(buffer, parent, center, tileindex)
end
itps
end

@generated function Base.getindex{T,N,M,O}(itp::CachedInterpolation{T,N,M,O}, xs::Number...)
@generated function Base.getindex(itp::CachedInterpolation{T,N,M,O}, xs::Number...) where {T,N,M,O}
length(xs) == N || error("Must use $N indexes")
ibsyms = [Symbol("ib_", d) for d = 1:N]
ipsyms = [Symbol("ip_", d) for d = 1:N]
Expand Down Expand Up @@ -139,18 +139,18 @@ end
end
end

immutable CoefsWrapper{N,A}
struct CoefsWrapper{N,A}
coefs::A
end

Base.size{N}(itp::CoefsWrapper{N}) = splitN(size(itp.coefs), Val{N})[1]
Base.size{N}(itp::CoefsWrapper{N}, d) = d <= N ? size(itp.coefs, d) : 1
Base.size(itp::CoefsWrapper{N}) where {N} = splitN(size(itp.coefs), Val{N})[1]
Base.size(itp::CoefsWrapper{N}, d) where {N} = d <= N ? size(itp.coefs, d) : 1

# FIXME: this function cheats dangerously, because it does _not_
# update the cache. This is equivalent to the assumption you've called
# getindex for the current `(x_1, x_2, ...)` location before calling
# gradient!. If this is not true, you'll get wrong answers.
@generated function Interpolations.gradient!{T,N,M,O,K}(g::AbstractVector, A::CachedInterpolation{T,N,M,O,K}, ys::Vararg{Number,N})
@generated function Interpolations.gradient!(g::AbstractVector, A::CachedInterpolation{T,N,M,O,K}, ys::Vararg{Number,N}) where {T,N,M,O,K}
IT = Tuple{ntuple(d->BSpline{Quadratic{InPlace}}, N)..., ntuple(d->NoInterp, K)...}
BS = Interpolations.BSplineInterpolation{T,M,Array{T,M},IT,OnCell,0}
ex = Interpolations.gradient_impl(BS)
Expand Down
30 changes: 15 additions & 15 deletions src/CenterIndexedArrays.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export CenterIndexedArray

## SymRange, an AbstractUnitRange that's symmetric around 0
# These are used as indices for CenterIndexedArrays
immutable SymRange <: AbstractUnitRange{Int}
struct SymRange <: AbstractUnitRange{Int}
n::Int # goes from -n:n
end

Expand All @@ -34,9 +34,9 @@ Base.intersect(r::SymRange, s::SymRange) = SymRange(min(last(r), last(s)))
s
end

Base.promote_rule{UR<:AbstractUnitRange}(::Type{SymRange}, ::Type{UR}) =
Base.promote_rule(::Type{SymRange}, ::Type{UR}) where {UR<:AbstractUnitRange} =
UR
Base.promote_rule{T2}(::Type{UnitRange{T2}}, ::Type{SymRange}) =
Base.promote_rule(::Type{UnitRange{T2}}, ::Type{SymRange}) where {T2} =
UnitRange{promote_type(T2, Int)}
function Base.convert(::Type{SymRange}, r::AbstractUnitRange)
first(r) == -last(r) || error("cannot convert $r to a SymRange")
Expand All @@ -53,26 +53,26 @@ A `CenterIndexedArray` is one for which the array center has indexes
CenterIndexedArray(A) "converts" `A` into a CenterIndexedArray. All
the sizes of `A` must be odd.
"""
immutable CenterIndexedArray{T,N,A<:AbstractArray} <: AbstractArray{T,N}
struct CenterIndexedArray{T,N,A<:AbstractArray} <: AbstractArray{T,N}
data::A
halfsize::NTuple{N,Int}

function (::Type{CenterIndexedArray{T,N,A}}){T,N,A<:AbstractArray}(data::A)
function CenterIndexedArray{T,N,A}(data::A) where {T,N,A<:AbstractArray}
new{T,N,A}(data, _halfsize(data))
end
end

CenterIndexedArray{T,N}(A::AbstractArray{T,N}) = CenterIndexedArray{T,N,typeof(A)}(A)
CenterIndexedArray{T}(::Type{T}, dims) = CenterIndexedArray(Array{T}(dims))
CenterIndexedArray{T}(::Type{T}, dims...) = CenterIndexedArray(Array{T}(dims))
CenterIndexedArray(A::AbstractArray{T,N}) where {T,N} = CenterIndexedArray{T,N,typeof(A)}(A)
CenterIndexedArray(::Type{T}, dims) where {T} = CenterIndexedArray(Array{T}(dims))
CenterIndexedArray(::Type{T}, dims...) where {T} = CenterIndexedArray(Array{T}(dims))

# This is the AbstractArray default, but do this just to be sure
@compat Base.IndexStyle{A<:CenterIndexedArray}(::Type{A}) = IndexCartesian()
Base.IndexStyle(::Type{A}) where {A<:CenterIndexedArray} = IndexCartesian()

Base.size(A::CenterIndexedArray) = size(A.data)
Base.indices(A::CenterIndexedArray) = map(SymRange, A.halfsize)

function Base.similar{T}(A::CenterIndexedArray, ::Type{T}, inds::Tuple{SymRange,Vararg{SymRange}})
function Base.similar(A::CenterIndexedArray, ::Type{T}, inds::Tuple{SymRange,Vararg{SymRange}}) where T
data = Array{T}(map(length, inds))
CenterIndexedArray(data)
end
Expand All @@ -86,7 +86,7 @@ function _halfsize(A::AbstractArray)
map(n->n>>UInt(1), size(A))
end

@inline function Base.getindex{T,N}(A::CenterIndexedArray{T,N}, i::Vararg{Number,N})
@inline function Base.getindex(A::CenterIndexedArray{T,N}, i::Vararg{Number,N}) where {T,N}
@boundscheck checkbounds(A, i...)
@inbounds val = A.data[map(offset, A.halfsize, i)...]
val
Expand All @@ -96,16 +96,16 @@ offset(off, i) = off+i+1

const Index = Union{Colon,AbstractVector}

Base.getindex{T}(A::CenterIndexedArray{T,1}, I::Index) = CenterIndexedArray([A[i] for i in _cindex(A, 1, I)])
Base.getindex{T}(A::CenterIndexedArray{T,2}, I::Index, J::Index) = CenterIndexedArray([A[i,j] for i in _cindex(A,1,I), j in _cindex(A,2,J)])
Base.getindex{T}(A::CenterIndexedArray{T,3}, I::Index, J::Index, K::Index) = CenterIndexedArray([A[i,j,k] for i in _cindex(A,1,I), j in _cindex(A,2,J), k in _cindex(A,3,K)])
Base.getindex(A::CenterIndexedArray{T,1}, I::Index) where {T} = CenterIndexedArray([A[i] for i in _cindex(A, 1, I)])
Base.getindex(A::CenterIndexedArray{T,2}, I::Index, J::Index) where {T} = CenterIndexedArray([A[i,j] for i in _cindex(A,1,I), j in _cindex(A,2,J)])
Base.getindex(A::CenterIndexedArray{T,3}, I::Index, J::Index, K::Index) where {T} = CenterIndexedArray([A[i,j,k] for i in _cindex(A,1,I), j in _cindex(A,2,J), k in _cindex(A,3,K)])

_cindex(A::CenterIndexedArray, d, I::Range) = convert(SymRange, I)
_cindex(A::CenterIndexedArray, d, I::AbstractVector) = error("unsupported, use a range")
_cindex(A::CenterIndexedArray, d, ::Colon) = SymRange(A.halfsize[d])


@inline function Base.setindex!{T,N}(A::CenterIndexedArray{T,N}, v, i::Vararg{Number,N})
@inline function Base.setindex!(A::CenterIndexedArray{T,N}, v, i::Vararg{Number,N}) where {T,N}
@boundscheck checkbounds(A, i...)
@inbounds A.data[map(offset, A.halfsize, i)...] = v
v
Expand Down
55 changes: 25 additions & 30 deletions src/RegisterCore.jl
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ This representation is efficient for `Interpolations.jl`, because it
allows interpolation to be performed on "both arrays" at once without
recomputing the interpolation coefficients.
"""
immutable NumDenom{T<:Number}
struct NumDenom{T<:Number}
num::T
denom::T
end
Expand All @@ -206,14 +206,14 @@ NumDenom(n, d) = NumDenom(promote(n, d)...)
(*)(n::Number, p::NumDenom) = NumDenom(n*p.num, n*p.denom)
(*)(p::NumDenom, n::Number) = n*p
(/)(p::NumDenom, n::Number) = NumDenom(p.num/n, p.denom/n)
Base.one{T}(::Type{NumDenom{T}}) = NumDenom(one(T),one(T))
Base.one(::Type{NumDenom{T}}) where {T} = NumDenom(one(T),one(T))
Base.one(p::NumDenom) = one(typeof(p))
Base.zero{T}(::Type{NumDenom{T}}) = NumDenom(zero(T),zero(T))
Base.zero(::Type{NumDenom{T}}) where {T} = NumDenom(zero(T),zero(T))
Base.zero(p::NumDenom) = zero(typeof(p))
Base.promote_rule{T1,T2<:Number}(::Type{NumDenom{T1}}, ::Type{T2}) = NumDenom{promote_type(T1,T2)}
Base.eltype{T}(::Type{NumDenom{T}}) = T
Base.convert{T}(::Type{NumDenom{T}}, p::NumDenom{T}) = p
Base.convert{T}(::Type{NumDenom{T}}, p::NumDenom) = NumDenom{T}(p.num, p.denom)
Base.promote_rule(::Type{NumDenom{T1}}, ::Type{T2}) where {T1,T2<:Number} = NumDenom{promote_type(T1,T2)}
Base.eltype(::Type{NumDenom{T}}) where {T} = T
Base.convert(::Type{NumDenom{T}}, p::NumDenom{T}) where {T} = p
Base.convert(::Type{NumDenom{T}}, p::NumDenom) where {T} = NumDenom{T}(p.num, p.denom)
Base.show(io::IO, p::NumDenom) = print(io, "NumDenom(", p.num, ",", p.denom, ")")
function Base.showcompact(io::IO, p::NumDenom)
print(io, "NumDenom(")
Expand All @@ -223,7 +223,7 @@ function Base.showcompact(io::IO, p::NumDenom)
print(io, ")")
end

@compat const MismatchArray{ND<:NumDenom,N,A} = CenterIndexedArray{ND,N,A}
const MismatchArray{ND<:NumDenom,N,A} = CenterIndexedArray{ND,N,A}

maxshift(A::MismatchArray) = A.halfsize

Expand All @@ -232,7 +232,7 @@ maxshift(A::MismatchArray) = A.halfsize
`(num,denom)` into a single `MismatchArray`. This is useful
preparation for interpolation.
"""
function (::Type{M}){M<:MismatchArray}(num::AbstractArray, denom::AbstractArray)
function (::Type{M})(num::AbstractArray, denom::AbstractArray) where M<:MismatchArray
size(num) == size(denom) || throw(DimensionMismatch("num and denom must have the same size"))
T = promote_type(eltype(num), eltype(denom))
numdenom = CenterIndexedArray(NumDenom{T}, size(num))
Expand Down Expand Up @@ -270,7 +270,7 @@ end

`mms = mismatcharrays(nums, denom)`, for `denom` a single array, uses the same `denom` array for all `nums`.
"""
function mismatcharrays{A<:AbstractArray,T<:Number}(nums::AbstractArray{A}, denom::AbstractArray{T})
function mismatcharrays(nums::AbstractArray{A}, denom::AbstractArray{T}) where {A<:AbstractArray,T<:Number}
first = true
local mms
for i in eachindex(nums)
Expand All @@ -285,7 +285,7 @@ function mismatcharrays{A<:AbstractArray,T<:Number}(nums::AbstractArray{A}, deno
mms
end

function mismatcharrays{A1<:AbstractArray,A2<:AbstractArray}(nums::AbstractArray{A1}, denoms::AbstractArray{A2})
function mismatcharrays(nums::AbstractArray{A1}, denoms::AbstractArray{A2}) where {A1<:AbstractArray,A2<:AbstractArray}
size(nums) == size(denoms) || throw(DimensionMismatch("nums and denoms arrays must have the same number of apertures"))
first = true
local mms
Expand All @@ -304,7 +304,7 @@ end
`num, denom = separate(mm)` splits an `AbstractArray{NumDenom}` into separate
numerator and denominator arrays.
"""
function separate{T}(data::AbstractArray{NumDenom{T}})
function separate(data::AbstractArray{NumDenom{T}}) where T
num = Array{T}(size(data))
denom = similar(num)
for I in eachindex(data)
Expand All @@ -320,7 +320,7 @@ function separate(mm::MismatchArray)
CenterIndexedArray(num), CenterIndexedArray(denom)
end

function separate{M<:MismatchArray}(mma::AbstractArray{M})
function separate(mma::AbstractArray{M}) where M<:MismatchArray
T = eltype(eltype(M))
nums = Array{CenterIndexedArray{T,ndims(M)}}(size(mma))
denoms = similar(nums)
Expand All @@ -336,7 +336,7 @@ end
`denom < thresh`, and `fillval`'s type determines the type of the
output. The default is NaN.
"""
function ratio{T}(mm::MismatchArray, thresh, fillval::T)
function ratio(mm::MismatchArray, thresh, fillval::T) where T
out = CenterIndexedArray(T, size(mm))
for I in eachindex(mm)
nd = mm[I]
Expand All @@ -345,12 +345,12 @@ function ratio{T}(mm::MismatchArray, thresh, fillval::T)
out
end
ratio(mm::MismatchArray, thresh) = ratio(mm, thresh, convert(eltype(eltype(mm)), NaN))
@inline ratio{T}(nd::NumDenom{T}, thresh, fillval=convert(T,NaN)) = nd.denom < thresh ? fillval : nd.num/nd.denom
@inline ratio(nd::NumDenom{T}, thresh, fillval=convert(T,NaN)) where {T} = nd.denom < thresh ? fillval : nd.num/nd.denom

ratio{T<:Real}(r::CenterIndexedArray{T}, thresh, fillval=convert(T,NaN)) = r
ratio(r::CenterIndexedArray{T}, thresh, fillval=convert(T,NaN)) where {T<:Real} = r

(::Type{M}){M<:MismatchArray,T}(::Type{T}, dims) = CenterIndexedArray(NumDenom{T}, dims)
(::Type{M}){M<:MismatchArray,T}(::Type{T}, dims...) = CenterIndexedArray(NumDenom{T}, dims)
(::Type{M})(::Type{T}, dims) where {M<:MismatchArray,T} = CenterIndexedArray(NumDenom{T}, dims)
(::Type{M})(::Type{T}, dims...) where {M<:MismatchArray,T} = CenterIndexedArray(NumDenom{T}, dims)

function Base.copy!(M::MismatchArray, nd::Tuple{AbstractArray, AbstractArray})
num, denom = nd
Expand Down Expand Up @@ -394,7 +394,7 @@ arrays.
end
end

function indmin_mismatch{T<:Number}(r::CenterIndexedArray{T})
function indmin_mismatch(r::CenterIndexedArray{T}) where T<:Number
ind = ind2sub(size(r), indmin(r.data))
indctr = map(d->ind[d]-(size(r,d)+1)>>1, (1:ndims(r)...))
CartesianIndex(indctr)
Expand All @@ -415,7 +415,7 @@ If you do not wish to highpass-filter along a particular axis, put
You may optionally specify the element type of the result, which for
`Integer` or `FixedPoint` inputs defaults to `Float32`.
"""
function highpass{T}(::Type{T}, data::AbstractArray, sigma)
function highpass(::Type{T}, data::AbstractArray, sigma) where T
if any(isinf, sigma)
datahp = convert(Array{T,ndims(data)}, data)
else
Expand All @@ -424,7 +424,7 @@ function highpass{T}(::Type{T}, data::AbstractArray, sigma)
datahp[datahp .< 0] = 0 # truncate anything below 0
datahp
end
highpass{T<:AbstractFloat}(data::AbstractArray{T}, sigma) = highpass(T, data, sigma)
highpass(data::AbstractArray{T}, sigma) where {T<:AbstractFloat} = highpass(T, data, sigma)
highpass(data::AbstractArray, sigma) = highpass(Float32, data, sigma)


Expand All @@ -436,13 +436,8 @@ parent.
See also `trimmedview`.
"""
paddedview(A::SubArray) = _paddedview(A, (), (), A.indexes...)
if VERSION < v"0.6.0-dev"
_paddedview{T,N,P,I}(A::SubArray{T,N,P,I}, newindexes, newsize) =
SubArray(A.parent, newindexes, newsize)
else
_paddedview{T,N,P,I}(A::SubArray{T,N,P,I}, newindexes, newsize) =
SubArray(A.parent, newindexes)
end
_paddedview(A::SubArray{T,N,P,I}, newindexes, newsize) where {T,N,P,I} =
SubArray(A.parent, newindexes)
@inline function _paddedview(A, newindexes, newsize, index, indexes...)
d = length(newindexes)+1
_paddedview(A, (newindexes..., pdindex(A.parent, d, index)), pdsize(A.parent, newsize, d, index), indexes...)
Expand Down Expand Up @@ -480,7 +475,7 @@ end


# For faster and type-stable slicing
immutable ColonFun end
(::Type{ColonFun})(::Int) = Colon()
struct ColonFun end
ColonFun(::Int) = Colon()

end
Loading