Skip to content
New issue

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

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

Already on GitHub? # to your account

Add ReshapedArray #19

Merged
merged 16 commits into from
Nov 13, 2019
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ language: julia
os:
- linux
- osx
- windows
julia:
- 1.0
- 1.1
- 1.2
- 1.2
- 1.3
- nightly
matrix:
allow_failures:
Expand Down
11 changes: 6 additions & 5 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "InfiniteArrays"
uuid = "4858937d-0d70-526a-a4dd-2d5cb5dd786c"
version = "0.3.1"
version = "0.4"

[deps]
DSP = "717857b8-e6f2-59f4-9121-6e50c889abd2"
Expand All @@ -11,14 +11,15 @@ SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"

[compat]
DSP = "0.5.1, 0.6"
FillArrays = "0.7.1"
LazyArrays = "0.12"
DSP = "0.6"
FillArrays = "0.8"
LazyArrays = "0.13,0.14"
julia = "1"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
BandedMatrices = "aae01518-5342-5314-be14-df237901396f"
LazyBandedMatrices = "d7e5e226-e90b-4449-9968-0f923699bf6f"

[targets]
test = ["Test", "BandedMatrices"]
test = ["Test", "BandedMatrices", "LazyBandedMatrices"]
44 changes: 0 additions & 44 deletions appveyor.yml

This file was deleted.

68 changes: 48 additions & 20 deletions src/InfiniteArrays.jl
Original file line number Diff line number Diff line change
@@ -1,55 +1,56 @@
__precompile__()

module InfiniteArrays
using Base, Statistics, LinearAlgebra, FillArrays, LazyArrays, DSP
using Base, Statistics, LinearAlgebra, FillArrays, LazyArrays, DSP

import Base: *, +, -, /, \, ==, isinf, isfinite, sign, angle, show, isless,
fld, cld, div, min, max, minimum, maximum, mod,
<, ≤, >, ≥, promote_rule, convert, copy,
<, ≤, >, ≥, promote_rule, convert, unsafe_convert, copy,
size, step, isempty, length, first, last,
getindex, setindex!, intersect, @_inline_meta,
sort, sort!, issorted, sortperm, sum, in, broadcast,
eltype, parent, real, imag,
conj, transpose,
eltype, elsize, parent, parentindices, reinterpret,
unaliascopy, dataids,
real, imag, conj, transpose,
exp, log, sqrt, cos, sin, tan, csc, sec, cot,
cosh, sinh, tanh, csch, sech, coth, acos, asin, atan, acsc, asec, acot,
acosh, asinh, atanh, acsch, asech, acoth, (:),
AbstractMatrix, AbstractArray, checkindex, unsafe_length, OneTo,
to_shape, _sub2ind, print_matrix, print_matrix_row, print_matrix_vdots,
checkindex, Slice, @propagate_inbounds, @_propagate_inbounds_meta,
_in_range, _range, _rangestyle, Ordered,
ArithmeticWraps, floatrange, reverse, unitrange_last,
AbstractArray, AbstractVector, Array, Vector, Matrix,
axes, (:), _sub2ind_recurse, broadcast, promote_eltypeof,
diff, cumsum, show_delim_array, show_circular, Int,
similar, _unsafe_getindex, string, zeros, fill, permutedims,
cat_similar, vcat
_in_range, _range, _rangestyle, Ordered,
ArithmeticWraps, floatrange, reverse, unitrange_last,
AbstractArray, AbstractVector, Array, Vector, Matrix,
axes, (:), _sub2ind_recurse, broadcast, promote_eltypeof,
diff, cumsum, show_delim_array, show_circular, Int,
similar, _unsafe_getindex, string, zeros, fill, permutedims,
cat_similar, vcat,
reshape, ReshapedIndex, ind2sub_rs, _unsafe_getindex_rs,
searchsorted, Ordering, lt

using Base.Broadcast
import Base.Broadcast: BroadcastStyle, AbstractArrayStyle, Broadcasted, broadcasted,
@nexprs, @ncall, combine_eltypes, DefaultArrayStyle, instantiate
@nexprs, @ncall, combine_eltypes, DefaultArrayStyle, instantiate, axistype

import LinearAlgebra: BlasInt, BlasFloat, norm, diag, diagm, ishermitian, issymmetric,
det, logdet, istriu, istril, adjoint, tr, AbstractTriangular,
norm2, norm1, normp

import Statistics: mean, median

import FillArrays: AbstractFill, getindex_value
import LazyArrays: LazyArrayStyle, AbstractBandedLayout, MemoryLayout, LazyLayout,
ZerosLayout, @lazymul, AbstractArrayApplyStyle, CachedArray, CachedVector
import FillArrays: AbstractFill, getindex_value, fill_reshape
import LazyArrays: LazyArrayStyle, AbstractBandedLayout, MemoryLayout, LazyLayout, UnknownLayout,
ZerosLayout, @lazymul, AbstractArrayApplyStyle, CachedArray, CachedVector,
reshapedlayout

import DSP: conv

export ∞, Hcat, Vcat, Zeros, Ones, Fill, Eye, BroadcastArray, cache





include("Infinity.jl")
include("infrange.jl")
include("infarrays.jl")
include("reshapedarray.jl")

##
# Fill FillArrays
Expand Down Expand Up @@ -119,6 +120,10 @@ end
# Temporary hacks for base support
##
OneTo(::Infinity) = OneToInf()
function OneTo(x::OrientedInfinity)
iszero(x.angle) && return OneTo(∞)
throw(ArgumentError("Cannot create infinite range with negative length"))
end
OneTo{T}(::Infinity) where T<:Integer = OneToInf{T}()
UnitRange(start::Integer, ::Infinity) = InfUnitRange(start)
UnitRange{T}(start::Integer, ::Infinity) where T<:Real = InfUnitRange{T}(start)
Expand All @@ -127,7 +132,30 @@ OneTo{T}(::OneToInf) where T<:Integer = OneToInf{T}()

Int(::Infinity) = ∞


axistype(::OneTo{T}, ::OneToInf{V}) where {T,V} = OneToInf{promote_type(T,V)}()
axistype(::OneToInf{V}, ::OneTo{T}) where {T,V} = OneToInf{promote_type(T,V)}()

# sort.jl
# returns the range of indices of v equal to x
# if v does not contain x, returns a 0-length range
# indicating the insertion point of x
function searchsorted(v::AbstractVector, x, ilo::Int, ::Infinity, o::Ordering)
lo = ilo-1
hi = ∞
@inbounds while lo < hi-1
m = isinf(hi) ? lo + 1000 : (lo+hi)>>>1
if lt(o, v[m], x)
lo = m
elseif lt(o, x, v[m])
hi = m
else
a = searchsortedfirst(v, x, max(lo,ilo), m, o)
b = searchsortedlast(v, x, m, hi, o)
return a : b
end
end
return (lo + 1) : (hi - 1)
end


end # module
4 changes: 3 additions & 1 deletion src/infarrays.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ similar(A::AbstractArray, ::Type{T}, dims::Tuple{Infinity,Infinity}) where T = c

similar(::Type{<:AbstractArray{T}}, axes::Tuple{OneToInf{Int}}) where T = cache(Zeros{T}(axes))
similar(::Type{<:AbstractArray{T}}, axes::Tuple{OneToInf{Int},OneToInf{Int}}) where T = cache(Zeros{T}(axes))
similar(::Type{<:AbstractArray{T}}, axes::Tuple{OneToInf{Int},OneTo{Int}}) where T = cache(Zeros{T}(axes))
similar(::Type{<:AbstractArray{T}}, axes::Tuple{OneTo{Int},OneToInf{Int}}) where T = cache(Zeros{T}(axes))
similar(::Type{<:AbstractArray{T}}, dims::Tuple{Infinity}) where T = cache(Zeros{T}(dims))
similar(::Type{<:AbstractArray{T}}, dims::Tuple{Infinity,Infinity}) where T = cache(Zeros{T}(dims))

Expand Down Expand Up @@ -107,7 +109,7 @@ for typ in (:Ones, :Zeros, :Fill)
end
end

BroadcastStyle(::Type{<:Eye{T,OneToInf{I}}}) where {T,I} = LazyArrayStyle{2}()
BroadcastStyle(::Type{<:Diagonal{T,<:AbstractFill{T,1,Tuple{OneToInf{I}}}}}) where {T,I} = LazyArrayStyle{2}()

#####
# Diagonal
Expand Down
7 changes: 0 additions & 7 deletions src/infrange.jl
Original file line number Diff line number Diff line change
Expand Up @@ -464,10 +464,3 @@ end

MemoryLayout(::Type{<:AbstractInfUnitRange}) = LazyLayout()
MemoryLayout(::Type{<:InfStepRange}) = LazyLayout()


####
# permutedims
####
permutedims(r::InfRanges) = transpose(r)
permutedims(r::BroadcastVector{<:Number,<:Any,<:Tuple{Int,InfRanges}}) = transpose(r)
71 changes: 71 additions & 0 deletions src/reshapedarray.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# This file is based on a part of Julia. License is MIT: https://julialang.org/license

using Base.MultiplicativeInverses: SignedMultiplicativeInverse

struct ReshapedArray{T,N,P<:AbstractArray,DIMS<:Tuple,MI<:Tuple{Vararg{SignedMultiplicativeInverse{Int}}}} <: AbstractArray{T,N}
parent::P
dims::DIMS
mi::MI
end
ReshapedArray(parent::AbstractArray{T}, dims::NTuple{N,Integer}, mi) where {T,N} = ReshapedArray{T,N,typeof(parent),typeof(dims),typeof(mi)}(parent, dims, mi)
ReshapedArray(parent::AbstractArray{T}, dims::NTuple{N,Integer}) where {T,N} = ReshapedArray(parent, dims, ())

size(A::ReshapedArray) = A.dims
similar(A::ReshapedArray, eltype::Type, dims::Dims) = similar(parent(A), eltype, dims)
parent(A::ReshapedArray) = A.parent
parentindices(A::ReshapedArray) = map(OneTo, size(parent(A)))
reinterpret(::Type{T}, A::ReshapedArray, dims::Dims) where {T} = reinterpret(T, parent(A), dims)
elsize(::Type{<:ReshapedArray{<:Any,<:Any,P}}) where {P} = elsize(P)

unaliascopy(A::ReshapedArray) = typeof(A)(unaliascopy(A.parent), A.dims, A.mi)
dataids(A::ReshapedArray) = dataids(A.parent)

@inline function getindex(A::ReshapedArray{T,N}, indices::Vararg{Integer,N}) where {T,N}
@boundscheck checkbounds(A, indices...)
_unsafe_getindex(A, indices...)
end
@inline function getindex(A::ReshapedArray, index::ReshapedIndex)
@boundscheck checkbounds(parent(A), index.parentindex)
@inbounds ret = parent(A)[index.parentindex]
ret
end

@inline function _unsafe_getindex(A::ReshapedArray{T,N}, indices::Vararg{Integer,N}) where {T,N}
i = Base._sub2ind(size(A), indices...)
I = ind2sub_rs(axes(A.parent), A.mi, i)
_unsafe_getindex_rs(parent(A), I)
end

@inline function setindex!(A::ReshapedArray{T,N}, val, indices::Vararg{Integer,N}) where {T,N}
@boundscheck checkbounds(A, indices...)
_unsafe_setindex!(A, val, indices...)
end
@inline function setindex!(A::ReshapedArray, val, index::ReshapedIndex)
@boundscheck checkbounds(parent(A), index.parentindex)
@inbounds parent(A)[index.parentindex] = val
val
end

@inline function _unsafe_setindex!(A::ReshapedArray{T,N}, val, indices::Vararg{Integer,N}) where {T,N}
@inbounds parent(A)[ind2sub_rs(axes(A.parent), A.mi, Base._sub2ind(size(A), indices...))...] = val
val
end

unsafe_convert(::Type{Ptr{T}}, a::ReshapedArray{T}) where {T} = unsafe_convert(Ptr{T}, parent(a))

reshape(A::AbstractArray, a::Infinity, b::Integer...) = ReshapedArray(A, tuple(a,b...))
reshape(A::AbstractArray, a::Integer, b::Infinity, c::Integer...) = ReshapedArray(A, tuple(a,b,c...))
reshape(A::AbstractArray, dims::Tuple{Infinity,Vararg{Integer}}) = ReshapedArray(A, dims)
reshape(A::AbstractArray, dims::Tuple{Integer,Infinity,Vararg{Integer}}) = ReshapedArray(A, dims)
reshape(A::AbstractFill, a::Infinity, b::Integer...) = fill_reshape(A, a, b...)
reshape(A::AbstractFill, a::Integer, b::Infinity, c::Integer...) = fill_reshape(A, a, b, c...)
reshape(A::AbstractFill, dims::Tuple{Infinity,Vararg{Integer}}) = fill_reshape(A, dims...)
reshape(A::AbstractFill, dims::Tuple{Integer,Infinity,Vararg{Integer}}) = fill_reshape(A, dims...)


BroadcastStyle(::Type{<:ReshapedArray{T,N,<:Any,NTuple{N,<:Infinity}}}) where {T,N} = LazyArrayStyle{N}()
BroadcastStyle(::Type{<:ReshapedArray{T,2,<:Any,<:Tuple{<:Any,<:Infinity}}}) where {T} = LazyArrayStyle{2}()
BroadcastStyle(::Type{<:ReshapedArray{T,2,<:Any,<:Tuple{<:Infinity,<:Any}}}) where {T} = LazyArrayStyle{2}()


MemoryLayout(::Type{<:ReshapedArray{T,N,A,DIMS}}) where {T,N,A,DIMS} = reshapedlayout(MemoryLayout(A), DIMS)
38 changes: 30 additions & 8 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using LinearAlgebra, SparseArrays, InfiniteArrays, FillArrays, LazyArrays, Statistics, DSP, BandedMatrices, Test
using LinearAlgebra, SparseArrays, InfiniteArrays, FillArrays, LazyArrays, Statistics, DSP, BandedMatrices, LazyBandedMatrices, Test
import InfiniteArrays: OrientedInfinity, OneToInf, InfUnitRange, InfStepRange
import LazyArrays: CachedArray, MemoryLayout, LazyLayout, DiagonalLayout, LazyArrayStyle
import BandedMatrices: _BandedMatrix, BandedColumns
Expand Down Expand Up @@ -508,8 +508,6 @@ end
x = Vcat(1:2, [1,1,1,1,1], 3, Fill(4,∞))
@test maximum(x) == 4
@test minimum(x) == 1

@test_throws ArgumentError maximum(exp.(1:∞))
end

@testset "special vcat" begin
Expand All @@ -518,6 +516,13 @@ end
@test [1; zeros(∞)] isa CachedArray
@test [[1,2,3]; zeros(∞)] isa CachedArray
end

@testset "sparse print" begin
A = Vcat(1, Zeros(∞))
@test Base.replace_in_print_matrix(A, 2, 1, "0") == "⋅"
A = Vcat(Ones{Int}(1,∞), Diagonal(1:∞))
@test Base.replace_in_print_matrix(A, 2, 2, "0") == "⋅"
end
end

@testset "broadcasting" begin
Expand Down Expand Up @@ -615,9 +620,11 @@ end
C = Vcat([1,2,3], Zeros(∞))
D = Vcat(Fill(1,3,∞), Zeros(∞,∞))

@test A*B isa BroadcastArray
@test size(A*B) == (3,∞)
@test (A*B)[1:3,1:10] == Fill(1,3,10)*Diagonal(1:10)
AB = A*B
@test AB isa BroadcastArray
@test size(AB) == (3,∞)
@test (AB)[1:3,1:10] == Fill(1,3,10)*Diagonal(1:10)
@test MemoryLayout(typeof(AB)) == LazyLayout()

@test A*B*C isa ApplyArray
@test size(A*B*C) == (3,)
Expand All @@ -639,11 +646,22 @@ end
@testset "Banded" begin
A = _BandedMatrix((0:∞)', ∞, -1, 1)
@test_broken apply(*, Eye(∞), A) ≡ A
@test 2.0A isa BandedMatrix
@test (2.0A)[1:10,1:10] == 2.0A[1:10,1:10]
@test 2.0\A isa BandedMatrix
@test (2.0\A)[1:10,1:10] == 2.0\A[1:10,1:10]
@test A/2 isa BandedMatrix
@test (A/2)[1:10,1:10] == (A/2)[1:10,1:10]
end

@testset "permutedims" begin
@test permutedims(1:∞) isa Transpose
@testset "reshaped" begin
@test InfiniteArrays.ReshapedArray(1:6,(2,3)) == [1 3 5; 2 4 6]
@test InfiniteArrays.ReshapedArray(1:∞,(1,∞))[1,1:10] == 1:10
@test reshape(1:∞,1,∞) === InfiniteArrays.ReshapedArray(1:∞,(1,∞))
@test permutedims(1:∞) isa InfiniteArrays.ReshapedArray
@test permutedims(1:∞)[1,1:10] == (1:10)
a = reshape(Vcat(Fill(1,1,∞),Fill(2,2,∞)),∞)
@test a[1:7] == [1, 2, 2, 1, 2, 2, 1]
end

@testset "norm" begin
Expand All @@ -652,4 +670,8 @@ end
@test norm(Fill(5),p) ≈ norm(Array(Fill(5)),p) # tests tuple bug
@test norm(Zeros{Float64}(),p) == 0.0 # tests tuple bug
end
end

@testset "sub-Eye" begin
@test bandwidths(view(Eye(∞),:,2:∞)) == (1,-1)
end