Skip to content

Commit 89f9a32

Browse files
authored
Add ReshapedArray (#19)
* add reshaped * Update InfiniteArrays.jl * MemoryLayout for reshaped * fix indexing bug * v0.4 * axistype * Update runtests.jl * Fix reshapedlayout * BraodcastStyle for Diagonal Fill * reshape for Fill * Update Project.toml * More similar * Change to LazyBanded * searchsorted * Test on 1.3, drop Appveyor
1 parent 8c4c2a7 commit 89f9a32

File tree

8 files changed

+161
-86
lines changed

8 files changed

+161
-86
lines changed

.travis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ language: julia
33
os:
44
- linux
55
- osx
6+
- windows
67
julia:
78
- 1.0
89
- 1.1
9-
- 1.2
10+
- 1.2
11+
- 1.3
1012
- nightly
1113
matrix:
1214
allow_failures:

Project.toml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "InfiniteArrays"
22
uuid = "4858937d-0d70-526a-a4dd-2d5cb5dd786c"
3-
version = "0.3.1"
3+
version = "0.4"
44

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

1313
[compat]
14-
DSP = "0.5.1, 0.6"
15-
FillArrays = "0.7.1"
16-
LazyArrays = "0.12"
14+
DSP = "0.6"
15+
FillArrays = "0.8"
16+
LazyArrays = "0.13,0.14"
1717
julia = "1"
1818

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

2324
[targets]
24-
test = ["Test", "BandedMatrices"]
25+
test = ["Test", "BandedMatrices", "LazyBandedMatrices"]

appveyor.yml

Lines changed: 0 additions & 44 deletions
This file was deleted.

src/InfiniteArrays.jl

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,56 @@
1-
__precompile__()
2-
31
module InfiniteArrays
4-
using Base, Statistics, LinearAlgebra, FillArrays, LazyArrays, DSP
2+
using Base, Statistics, LinearAlgebra, FillArrays, LazyArrays, DSP
53

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

2829
using Base.Broadcast
2930
import Base.Broadcast: BroadcastStyle, AbstractArrayStyle, Broadcasted, broadcasted,
30-
@nexprs, @ncall, combine_eltypes, DefaultArrayStyle, instantiate
31+
@nexprs, @ncall, combine_eltypes, DefaultArrayStyle, instantiate, axistype
3132

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

3637
import Statistics: mean, median
3738

38-
import FillArrays: AbstractFill, getindex_value
39-
import LazyArrays: LazyArrayStyle, AbstractBandedLayout, MemoryLayout, LazyLayout,
40-
ZerosLayout, @lazymul, AbstractArrayApplyStyle, CachedArray, CachedVector
39+
import FillArrays: AbstractFill, getindex_value, fill_reshape
40+
import LazyArrays: LazyArrayStyle, AbstractBandedLayout, MemoryLayout, LazyLayout, UnknownLayout,
41+
ZerosLayout, @lazymul, AbstractArrayApplyStyle, CachedArray, CachedVector,
42+
reshapedlayout
4143

4244
import DSP: conv
4345

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

4648

4749

48-
49-
5050
include("Infinity.jl")
5151
include("infrange.jl")
5252
include("infarrays.jl")
53+
include("reshapedarray.jl")
5354

5455
##
5556
# Fill FillArrays
@@ -119,6 +120,10 @@ end
119120
# Temporary hacks for base support
120121
##
121122
OneTo(::Infinity) = OneToInf()
123+
function OneTo(x::OrientedInfinity)
124+
iszero(x.angle) && return OneTo(∞)
125+
throw(ArgumentError("Cannot create infinite range with negative length"))
126+
end
122127
OneTo{T}(::Infinity) where T<:Integer = OneToInf{T}()
123128
UnitRange(start::Integer, ::Infinity) = InfUnitRange(start)
124129
UnitRange{T}(start::Integer, ::Infinity) where T<:Real = InfUnitRange{T}(start)
@@ -127,7 +132,30 @@ OneTo{T}(::OneToInf) where T<:Integer = OneToInf{T}()
127132

128133
Int(::Infinity) =
129134

130-
135+
axistype(::OneTo{T}, ::OneToInf{V}) where {T,V} = OneToInf{promote_type(T,V)}()
136+
axistype(::OneToInf{V}, ::OneTo{T}) where {T,V} = OneToInf{promote_type(T,V)}()
137+
138+
# sort.jl
139+
# returns the range of indices of v equal to x
140+
# if v does not contain x, returns a 0-length range
141+
# indicating the insertion point of x
142+
function searchsorted(v::AbstractVector, x, ilo::Int, ::Infinity, o::Ordering)
143+
lo = ilo-1
144+
hi =
145+
@inbounds while lo < hi-1
146+
m = isinf(hi) ? lo + 1000 : (lo+hi)>>>1
147+
if lt(o, v[m], x)
148+
lo = m
149+
elseif lt(o, x, v[m])
150+
hi = m
151+
else
152+
a = searchsortedfirst(v, x, max(lo,ilo), m, o)
153+
b = searchsortedlast(v, x, m, hi, o)
154+
return a : b
155+
end
156+
end
157+
return (lo + 1) : (hi - 1)
158+
end
131159

132160

133161
end # module

src/infarrays.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ similar(A::AbstractArray, ::Type{T}, dims::Tuple{Infinity,Infinity}) where T = c
2626

2727
similar(::Type{<:AbstractArray{T}}, axes::Tuple{OneToInf{Int}}) where T = cache(Zeros{T}(axes))
2828
similar(::Type{<:AbstractArray{T}}, axes::Tuple{OneToInf{Int},OneToInf{Int}}) where T = cache(Zeros{T}(axes))
29+
similar(::Type{<:AbstractArray{T}}, axes::Tuple{OneToInf{Int},OneTo{Int}}) where T = cache(Zeros{T}(axes))
30+
similar(::Type{<:AbstractArray{T}}, axes::Tuple{OneTo{Int},OneToInf{Int}}) where T = cache(Zeros{T}(axes))
2931
similar(::Type{<:AbstractArray{T}}, dims::Tuple{Infinity}) where T = cache(Zeros{T}(dims))
3032
similar(::Type{<:AbstractArray{T}}, dims::Tuple{Infinity,Infinity}) where T = cache(Zeros{T}(dims))
3133

@@ -107,7 +109,7 @@ for typ in (:Ones, :Zeros, :Fill)
107109
end
108110
end
109111

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

112114
#####
113115
# Diagonal

src/infrange.jl

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -464,10 +464,3 @@ end
464464

465465
MemoryLayout(::Type{<:AbstractInfUnitRange}) = LazyLayout()
466466
MemoryLayout(::Type{<:InfStepRange}) = LazyLayout()
467-
468-
469-
####
470-
# permutedims
471-
####
472-
permutedims(r::InfRanges) = transpose(r)
473-
permutedims(r::BroadcastVector{<:Number,<:Any,<:Tuple{Int,InfRanges}}) = transpose(r)

src/reshapedarray.jl

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# This file is based on a part of Julia. License is MIT: https://julialang.org/license
2+
3+
using Base.MultiplicativeInverses: SignedMultiplicativeInverse
4+
5+
struct ReshapedArray{T,N,P<:AbstractArray,DIMS<:Tuple,MI<:Tuple{Vararg{SignedMultiplicativeInverse{Int}}}} <: AbstractArray{T,N}
6+
parent::P
7+
dims::DIMS
8+
mi::MI
9+
end
10+
ReshapedArray(parent::AbstractArray{T}, dims::NTuple{N,Integer}, mi) where {T,N} = ReshapedArray{T,N,typeof(parent),typeof(dims),typeof(mi)}(parent, dims, mi)
11+
ReshapedArray(parent::AbstractArray{T}, dims::NTuple{N,Integer}) where {T,N} = ReshapedArray(parent, dims, ())
12+
13+
size(A::ReshapedArray) = A.dims
14+
similar(A::ReshapedArray, eltype::Type, dims::Dims) = similar(parent(A), eltype, dims)
15+
parent(A::ReshapedArray) = A.parent
16+
parentindices(A::ReshapedArray) = map(OneTo, size(parent(A)))
17+
reinterpret(::Type{T}, A::ReshapedArray, dims::Dims) where {T} = reinterpret(T, parent(A), dims)
18+
elsize(::Type{<:ReshapedArray{<:Any,<:Any,P}}) where {P} = elsize(P)
19+
20+
unaliascopy(A::ReshapedArray) = typeof(A)(unaliascopy(A.parent), A.dims, A.mi)
21+
dataids(A::ReshapedArray) = dataids(A.parent)
22+
23+
@inline function getindex(A::ReshapedArray{T,N}, indices::Vararg{Integer,N}) where {T,N}
24+
@boundscheck checkbounds(A, indices...)
25+
_unsafe_getindex(A, indices...)
26+
end
27+
@inline function getindex(A::ReshapedArray, index::ReshapedIndex)
28+
@boundscheck checkbounds(parent(A), index.parentindex)
29+
@inbounds ret = parent(A)[index.parentindex]
30+
ret
31+
end
32+
33+
@inline function _unsafe_getindex(A::ReshapedArray{T,N}, indices::Vararg{Integer,N}) where {T,N}
34+
i = Base._sub2ind(size(A), indices...)
35+
I = ind2sub_rs(axes(A.parent), A.mi, i)
36+
_unsafe_getindex_rs(parent(A), I)
37+
end
38+
39+
@inline function setindex!(A::ReshapedArray{T,N}, val, indices::Vararg{Integer,N}) where {T,N}
40+
@boundscheck checkbounds(A, indices...)
41+
_unsafe_setindex!(A, val, indices...)
42+
end
43+
@inline function setindex!(A::ReshapedArray, val, index::ReshapedIndex)
44+
@boundscheck checkbounds(parent(A), index.parentindex)
45+
@inbounds parent(A)[index.parentindex] = val
46+
val
47+
end
48+
49+
@inline function _unsafe_setindex!(A::ReshapedArray{T,N}, val, indices::Vararg{Integer,N}) where {T,N}
50+
@inbounds parent(A)[ind2sub_rs(axes(A.parent), A.mi, Base._sub2ind(size(A), indices...))...] = val
51+
val
52+
end
53+
54+
unsafe_convert(::Type{Ptr{T}}, a::ReshapedArray{T}) where {T} = unsafe_convert(Ptr{T}, parent(a))
55+
56+
reshape(A::AbstractArray, a::Infinity, b::Integer...) = ReshapedArray(A, tuple(a,b...))
57+
reshape(A::AbstractArray, a::Integer, b::Infinity, c::Integer...) = ReshapedArray(A, tuple(a,b,c...))
58+
reshape(A::AbstractArray, dims::Tuple{Infinity,Vararg{Integer}}) = ReshapedArray(A, dims)
59+
reshape(A::AbstractArray, dims::Tuple{Integer,Infinity,Vararg{Integer}}) = ReshapedArray(A, dims)
60+
reshape(A::AbstractFill, a::Infinity, b::Integer...) = fill_reshape(A, a, b...)
61+
reshape(A::AbstractFill, a::Integer, b::Infinity, c::Integer...) = fill_reshape(A, a, b, c...)
62+
reshape(A::AbstractFill, dims::Tuple{Infinity,Vararg{Integer}}) = fill_reshape(A, dims...)
63+
reshape(A::AbstractFill, dims::Tuple{Integer,Infinity,Vararg{Integer}}) = fill_reshape(A, dims...)
64+
65+
66+
BroadcastStyle(::Type{<:ReshapedArray{T,N,<:Any,NTuple{N,<:Infinity}}}) where {T,N} = LazyArrayStyle{N}()
67+
BroadcastStyle(::Type{<:ReshapedArray{T,2,<:Any,<:Tuple{<:Any,<:Infinity}}}) where {T} = LazyArrayStyle{2}()
68+
BroadcastStyle(::Type{<:ReshapedArray{T,2,<:Any,<:Tuple{<:Infinity,<:Any}}}) where {T} = LazyArrayStyle{2}()
69+
70+
71+
MemoryLayout(::Type{<:ReshapedArray{T,N,A,DIMS}}) where {T,N,A,DIMS} = reshapedlayout(MemoryLayout(A), DIMS)

test/runtests.jl

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using LinearAlgebra, SparseArrays, InfiniteArrays, FillArrays, LazyArrays, Statistics, DSP, BandedMatrices, Test
1+
using LinearAlgebra, SparseArrays, InfiniteArrays, FillArrays, LazyArrays, Statistics, DSP, BandedMatrices, LazyBandedMatrices, Test
22
import InfiniteArrays: OrientedInfinity, OneToInf, InfUnitRange, InfStepRange
33
import LazyArrays: CachedArray, MemoryLayout, LazyLayout, DiagonalLayout, LazyArrayStyle
44
import BandedMatrices: _BandedMatrix, BandedColumns
@@ -508,8 +508,6 @@ end
508508
x = Vcat(1:2, [1,1,1,1,1], 3, Fill(4,∞))
509509
@test maximum(x) == 4
510510
@test minimum(x) == 1
511-
512-
@test_throws ArgumentError maximum(exp.(1:∞))
513511
end
514512

515513
@testset "special vcat" begin
@@ -518,6 +516,13 @@ end
518516
@test [1; zeros(∞)] isa CachedArray
519517
@test [[1,2,3]; zeros(∞)] isa CachedArray
520518
end
519+
520+
@testset "sparse print" begin
521+
A = Vcat(1, Zeros(∞))
522+
@test Base.replace_in_print_matrix(A, 2, 1, "0") == ""
523+
A = Vcat(Ones{Int}(1,∞), Diagonal(1:∞))
524+
@test Base.replace_in_print_matrix(A, 2, 2, "0") == ""
525+
end
521526
end
522527

523528
@testset "broadcasting" begin
@@ -615,9 +620,11 @@ end
615620
C = Vcat([1,2,3], Zeros(∞))
616621
D = Vcat(Fill(1,3,∞), Zeros(∞,∞))
617622

618-
@test A*B isa BroadcastArray
619-
@test size(A*B) == (3,∞)
620-
@test (A*B)[1:3,1:10] == Fill(1,3,10)*Diagonal(1:10)
623+
AB = A*B
624+
@test AB isa BroadcastArray
625+
@test size(AB) == (3,∞)
626+
@test (AB)[1:3,1:10] == Fill(1,3,10)*Diagonal(1:10)
627+
@test MemoryLayout(typeof(AB)) == LazyLayout()
621628

622629
@test A*B*C isa ApplyArray
623630
@test size(A*B*C) == (3,)
@@ -639,11 +646,22 @@ end
639646
@testset "Banded" begin
640647
A = _BandedMatrix((0:∞)', ∞, -1, 1)
641648
@test_broken apply(*, Eye(∞), A) A
649+
@test 2.0A isa BandedMatrix
650+
@test (2.0A)[1:10,1:10] == 2.0A[1:10,1:10]
651+
@test 2.0\A isa BandedMatrix
652+
@test (2.0\A)[1:10,1:10] == 2.0\A[1:10,1:10]
653+
@test A/2 isa BandedMatrix
654+
@test (A/2)[1:10,1:10] == (A/2)[1:10,1:10]
642655
end
643656

644-
@testset "permutedims" begin
645-
@test permutedims(1:∞) isa Transpose
657+
@testset "reshaped" begin
658+
@test InfiniteArrays.ReshapedArray(1:6,(2,3)) == [1 3 5; 2 4 6]
659+
@test InfiniteArrays.ReshapedArray(1:∞,(1,∞))[1,1:10] == 1:10
660+
@test reshape(1:∞,1,∞) === InfiniteArrays.ReshapedArray(1:∞,(1,∞))
661+
@test permutedims(1:∞) isa InfiniteArrays.ReshapedArray
646662
@test permutedims(1:∞)[1,1:10] == (1:10)
663+
a = reshape(Vcat(Fill(1,1,∞),Fill(2,2,∞)),∞)
664+
@test a[1:7] == [1, 2, 2, 1, 2, 2, 1]
647665
end
648666

649667
@testset "norm" begin
@@ -652,4 +670,8 @@ end
652670
@test norm(Fill(5),p) norm(Array(Fill(5)),p) # tests tuple bug
653671
@test norm(Zeros{Float64}(),p) == 0.0 # tests tuple bug
654672
end
673+
end
674+
675+
@testset "sub-Eye" begin
676+
@test bandwidths(view(Eye(∞),:,2:∞)) == (1,-1)
655677
end

0 commit comments

Comments
 (0)