Skip to content

Commit 93966d5

Browse files
committed
Loosen signature for repeat()
Accept any AbstractArray as first argument, and any iterable for inner and outer arguments. Use tuples by default rather than arrays, and allow passing an empty collection to mean no-op.
1 parent 807ec46 commit 93966d5

File tree

4 files changed

+150
-52
lines changed

4 files changed

+150
-52
lines changed

base/abstractarraymath.jl

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -200,31 +200,62 @@ function repmat(a::AbstractVector, m::Int)
200200
return b
201201
end
202202

203-
# Generalized repmat
204-
function repeat{T}(A::AbstractArray{T};
205-
inner::Array{Int} = ones(Int, ndims(A)),
206-
outer::Array{Int} = ones(Int, ndims(A)))
203+
"""
204+
repeat(A::AbstractArray; inner=ntuple(x->1, ndims(A)), outer=ntuple(x->1, ndims(A)))
205+
206+
Construct an array by repeating the entries of `A`. The i-th element of `inner` specifies
207+
the number of times that the individual entries of the i-th dimension of `A` should be
208+
repeated. The i-th element of `outer` specifies the number of times that a slice along the
209+
i-th dimension of `A` should be repeated. If `inner` or `outer` are omitted, no repetition
210+
is performed.
211+
212+
```jldoctest
213+
julia> repeat(1:2, inner=2)
214+
4-element Array{Int64,1}:
215+
1
216+
1
217+
2
218+
2
219+
220+
julia> repeat(1:2, outer=2)
221+
4-element Array{Int64,1}:
222+
1
223+
2
224+
1
225+
2
226+
227+
julia> repeat([1 2; 3 4], inner=(2, 1), outer=(1, 3))
228+
4×6 Array{Int64,2}:
229+
1 2 1 2 1 2
230+
1 2 1 2 1 2
231+
3 4 3 4 3 4
232+
3 4 3 4 3 4
233+
```
234+
"""
235+
function repeat(A::AbstractArray;
236+
inner=ntuple(x->1, ndims(A)),
237+
outer=ntuple(x->1, ndims(A)))
207238
ndims_in = ndims(A)
208239
length_inner = length(inner)
209240
length_outer = length(outer)
210-
ndims_out = max(ndims_in, length_inner, length_outer)
211241

212-
if length_inner < ndims_in || length_outer < ndims_in
213-
throw(ArgumentError("inner/outer repetitions must be set for all input dimensions"))
214-
end
242+
length_inner >= ndims_in || throw(ArgumentError("number of inner repetitions ($(length(inner))) cannot be less than number of dimensions of input ($(ndims(A)))"))
243+
length_outer >= ndims_in || throw(ArgumentError("number of outer repetitions ($(length(outer))) cannot be less than number of dimensions of input ($(ndims(A)))"))
244+
245+
ndims_out = max(ndims_in, length_inner, length_outer)
215246

216-
inner = vcat(inner, ones(Int,ndims_out-length_inner))
217-
outer = vcat(outer, ones(Int,ndims_out-length_outer))
247+
inner = vcat(collect(inner), ones(Int,ndims_out-length_inner))
248+
outer = vcat(collect(outer), ones(Int,ndims_out-length_outer))
218249

219250
size_in = size(A)
220251
size_out = ntuple(i->inner[i]*size(A,i)*outer[i],ndims_out)::Dims
221252
inner_size_out = ntuple(i->inner[i]*size(A,i),ndims_out)::Dims
222253

223-
indices_in = Array(Int, ndims_in)
224-
indices_out = Array(Int, ndims_out)
254+
indices_in = Vector{Int}(ndims_in)
255+
indices_out = Vector{Int}(ndims_out)
225256

226257
length_out = prod(size_out)
227-
R = Array(T, size_out)
258+
R = similar(A, size_out)
228259

229260
for index_out in 1:length_out
230261
ind2sub!(indices_out, size_out, index_out)

base/docs/helpdb/Base.jl

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4300,16 +4300,6 @@ Return an iterator over all keys in a collection. `collect(keys(d))` returns an
43004300
"""
43014301
keys
43024302

4303-
"""
4304-
repeat(A, inner = Int[], outer = Int[])
4305-
4306-
Construct an array by repeating the entries of `A`. The i-th element of `inner` specifies
4307-
the number of times that the individual entries of the i-th dimension of `A` should be
4308-
repeated. The i-th element of `outer` specifies the number of times that a slice along the
4309-
i-th dimension of `A` should be repeated.
4310-
"""
4311-
repeat
4312-
43134303
"""
43144304
ReentrantLock()
43154305

doc/stdlib/linalg.rst

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -979,11 +979,34 @@ Linear algebra functions in Julia are largely implemented by calling functions f
979979
980980
Construct a matrix by repeating the given matrix ``n`` times in dimension 1 and ``m`` times in dimension 2.
981981

982-
.. function:: repeat(A, inner = Int[], outer = Int[])
982+
.. function:: repeat(A::AbstractArray; inner=ntuple(x->1, ndims(A)), outer=ntuple(x->1, ndims(A)))
983983

984984
.. Docstring generated from Julia source
985985
986-
Construct an array by repeating the entries of ``A``\ . The i-th element of ``inner`` specifies the number of times that the individual entries of the i-th dimension of ``A`` should be repeated. The i-th element of ``outer`` specifies the number of times that a slice along the i-th dimension of ``A`` should be repeated.
986+
Construct an array by repeating the entries of ``A``\ . The i-th element of ``inner`` specifies the number of times that the individual entries of the i-th dimension of ``A`` should be repeated. The i-th element of ``outer`` specifies the number of times that a slice along the i-th dimension of ``A`` should be repeated. If ``inner`` or ``outer`` are omitted, no repetition is performed.
987+
988+
.. doctest::
989+
990+
julia> repeat(1:2, inner=2)
991+
4-element Array{Int64,1}:
992+
1
993+
1
994+
2
995+
2
996+
997+
julia> repeat(1:2, outer=2)
998+
4-element Array{Int64,1}:
999+
1
1000+
2
1001+
1
1002+
2
1003+
1004+
julia> repeat([1 2; 3 4], inner=(2, 1), outer=(1, 3))
1005+
4×6 Array{Int64,2}:
1006+
1 2 1 2 1 2
1007+
1 2 1 2 1 2
1008+
3 4 3 4 3 4
1009+
3 4 3 4 3 4
9871010

9881011
.. function:: kron(A, B)
9891012

test/arrayops.jl

Lines changed: 81 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -502,53 +502,86 @@ let
502502
@test isequal(cumsum(A,2),A2)
503503
@test isequal(cumsum(A,3),A3)
504504

505-
R = repeat([1, 2], inner = [1], outer = [1])
505+
R = repeat([1, 2])
506506
@test R == [1, 2]
507-
R = repeat([1, 2], inner = [2], outer = [1])
507+
R = repeat([1, 2], inner=1)
508+
@test R == [1, 2]
509+
R = repeat([1, 2], outer=1)
510+
@test R == [1, 2]
511+
R = repeat([1, 2], inner=(1,))
512+
@test R == [1, 2]
513+
R = repeat([1, 2], outer=(1,))
514+
@test R == [1, 2]
515+
R = repeat([1, 2], inner=[1])
516+
@test R == [1, 2]
517+
R = repeat([1, 2], outer=[1])
518+
@test R == [1, 2]
519+
R = repeat([1, 2], inner=1, outer=1)
520+
@test R == [1, 2]
521+
R = repeat([1, 2], inner=(1,), outer=(1,))
522+
@test R == [1, 2]
523+
R = repeat([1, 2], inner=[1], outer=[1])
524+
@test R == [1, 2]
525+
526+
R = repeat([1, 2], inner=2)
527+
@test R == [1, 1, 2, 2]
528+
R = repeat([1, 2], outer=2)
529+
@test R == [1, 2, 1, 2]
530+
R = repeat([1, 2], inner=(2,))
508531
@test R == [1, 1, 2, 2]
509-
R = repeat([1, 2], inner = [1], outer = [2])
532+
R = repeat([1, 2], outer=(2,))
510533
@test R == [1, 2, 1, 2]
511-
R = repeat([1, 2], inner = [2], outer = [2])
534+
R = repeat([1, 2], inner=[2])
535+
@test R == [1, 1, 2, 2]
536+
R = repeat([1, 2], outer=[2])
537+
@test R == [1, 2, 1, 2]
538+
539+
R = repeat([1, 2], inner=2, outer=2)
512540
@test R == [1, 1, 2, 2, 1, 1, 2, 2]
513-
R = repeat([1, 2], inner = [1, 1], outer = [1, 1])
541+
R = repeat([1, 2], inner=(2,), outer=(2,))
542+
@test R == [1, 1, 2, 2, 1, 1, 2, 2]
543+
R = repeat([1, 2], inner=[2], outer=[2])
544+
@test R == [1, 1, 2, 2, 1, 1, 2, 2]
545+
546+
R = repeat([1, 2], inner = (1, 1), outer = (1, 1))
514547
@test R == [1, 2]''
515-
R = repeat([1, 2], inner = [2, 1], outer = [1, 1])
548+
R = repeat([1, 2], inner = (2, 1), outer = (1, 1))
516549
@test R == [1, 1, 2, 2]''
517-
R = repeat([1, 2], inner = [1, 2], outer = [1, 1])
550+
R = repeat([1, 2], inner = (1, 2), outer = (1, 1))
518551
@test R == [1 1; 2 2]
519-
R = repeat([1, 2], inner = [1, 1], outer = [2, 1])
552+
R = repeat([1, 2], inner = (1, 1), outer = (2, 1))
520553
@test R == [1, 2, 1, 2]''
521-
R = repeat([1, 2], inner = [1, 1], outer = [1, 2])
554+
R = repeat([1, 2], inner = (1, 1), outer = (1, 2))
522555
@test R == [1 1; 2 2]
523556

524557
R = repeat([1 2;
525-
3 4], inner = [1, 1], outer = [1, 1])
558+
3 4], inner = (1, 1), outer = (1, 1))
526559
@test R == [1 2;
527560
3 4]
528561
R = repeat([1 2;
529-
3 4], inner = [1, 1], outer = [2, 1])
562+
3 4], inner = (1, 1), outer = (2, 1))
530563
@test R == [1 2;
531564
3 4;
532565
1 2;
533566
3 4]
534567
R = repeat([1 2;
535-
3 4], inner = [1, 1], outer = [1, 2])
568+
3 4], inner = (1, 1), outer = (1, 2))
536569
@test R == [1 2 1 2;
537570
3 4 3 4]
538571
R = repeat([1 2;
539-
3 4], inner = [1, 1], outer = [2, 2])
572+
3 4], inner = (1, 1), outer = (2, 2))
540573
@test R == [1 2 1 2;
541574
3 4 3 4;
542575
1 2 1 2;
543576
3 4 3 4]
544577
R = repeat([1 2;
545-
3 4], inner = [2, 1], outer = [1, 1])
578+
3 4], inner = (2, 1), outer = (1, 1))
546579
@test R == [1 2;
547580
1 2;
548581
3 4;
549582
3 4]
550583
R = repeat([1 2;
551-
3 4], inner = [2, 1], outer = [2, 1])
584+
3 4], inner = (2, 1), outer = (2, 1))
552585
@test R == [1 2;
553586
1 2;
554587
3 4;
@@ -558,13 +591,13 @@ let
558591
3 4;
559592
3 4]
560593
R = repeat([1 2;
561-
3 4], inner = [2, 1], outer = [1, 2])
594+
3 4], inner = (2, 1), outer = (1, 2))
562595
@test R == [1 2 1 2;
563596
1 2 1 2;
564597
3 4 3 4;
565598
3 4 3 4;]
566599
R = repeat([1 2;
567-
3 4], inner = [2, 1], outer = [2, 2])
600+
3 4], inner = (2, 1), outer = (2, 2))
568601
@test R == [1 2 1 2;
569602
1 2 1 2;
570603
3 4 3 4;
@@ -574,33 +607,33 @@ let
574607
3 4 3 4;
575608
3 4 3 4]
576609
R = repeat([1 2;
577-
3 4], inner = [1, 2], outer = [1, 1])
610+
3 4], inner = (1, 2), outer = (1, 1))
578611
@test R == [1 1 2 2;
579612
3 3 4 4]
580613
R = repeat([1 2;
581-
3 4], inner = [1, 2], outer = [2, 1])
614+
3 4], inner = (1, 2), outer = (2, 1))
582615
@test R == [1 1 2 2;
583616
3 3 4 4;
584617
1 1 2 2;
585618
3 3 4 4]
586619
R = repeat([1 2;
587-
3 4], inner = [1, 2], outer = [1, 2])
620+
3 4], inner = (1, 2), outer = (1, 2))
588621
@test R == [1 1 2 2 1 1 2 2;
589622
3 3 4 4 3 3 4 4]
590623
R = repeat([1 2;
591-
3 4], inner = [1, 2], outer = [2, 2])
624+
3 4], inner = (1, 2), outer = (2, 2))
592625
@test R == [1 1 2 2 1 1 2 2;
593626
3 3 4 4 3 3 4 4;
594627
1 1 2 2 1 1 2 2;
595628
3 3 4 4 3 3 4 4]
596629
R = repeat([1 2;
597-
3 4], inner = [2, 2], outer = [1, 1])
630+
3 4], inner = (2, 2), outer = [1, 1])
598631
@test R == [1 1 2 2;
599632
1 1 2 2;
600633
3 3 4 4;
601634
3 3 4 4]
602635
R = repeat([1 2;
603-
3 4], inner = [2, 2], outer = [2, 1])
636+
3 4], inner = (2, 2), outer = (2, 1))
604637
@test R == [1 1 2 2;
605638
1 1 2 2;
606639
3 3 4 4;
@@ -610,13 +643,13 @@ let
610643
3 3 4 4;
611644
3 3 4 4]
612645
R = repeat([1 2;
613-
3 4], inner = [2, 2], outer = [1, 2])
646+
3 4], inner = (2, 2), outer = (1, 2))
614647
@test R == [1 1 2 2 1 1 2 2;
615648
1 1 2 2 1 1 2 2;
616649
3 3 4 4 3 3 4 4;
617650
3 3 4 4 3 3 4 4]
618651
R = repeat([1 2;
619-
3 4], inner = [2, 2], outer = [2, 2])
652+
3 4], inner = (2, 2), outer = (2, 2))
620653
@test R == [1 1 2 2 1 1 2 2;
621654
1 1 2 2 1 1 2 2;
622655
3 3 4 4 3 3 4 4;
@@ -625,17 +658,25 @@ let
625658
1 1 2 2 1 1 2 2;
626659
3 3 4 4 3 3 4 4;
627660
3 3 4 4 3 3 4 4]
661+
@test_throws ArgumentError repeat([1 2;
662+
3 4], inner=2, outer=(2, 2))
663+
@test_throws ArgumentError repeat([1 2;
664+
3 4], inner=(2, 2), outer=2)
665+
@test_throws ArgumentError repeat([1 2;
666+
3 4], inner=(2,), outer=(2, 2))
667+
@test_throws ArgumentError repeat([1 2;
668+
3 4], inner=(2, 2), outer=(2,))
628669

629670
A = reshape(1:8, 2, 2, 2)
630-
R = repeat(A, inner = [1, 1, 2], outer = [1, 1, 1])
671+
R = repeat(A, inner = (1, 1, 2), outer = (1, 1, 1))
631672
T = reshape([1:4; 1:4; 5:8; 5:8], 2, 2, 4)
632673
@test R == T
633674
A = Array(Int, 2, 2, 2)
634675
A[:, :, 1] = [1 2;
635676
3 4]
636677
A[:, :, 2] = [5 6;
637678
7 8]
638-
R = repeat(A, inner = [2, 2, 2], outer = [2, 2, 2])
679+
R = repeat(A, inner = (2, 2, 2), outer = (2, 2, 2))
639680
@test R[1, 1, 1] == 1
640681
@test R[2, 2, 2] == 1
641682
@test R[3, 3, 3] == 8
@@ -645,6 +686,19 @@ let
645686
@test R[7, 7, 7] == 8
646687
@test R[8, 8, 8] == 8
647688

689+
R = repeat(1:2)
690+
@test R == [1, 2]
691+
R = repeat(1:2, inner=1)
692+
@test R == [1, 2]
693+
R = repeat(1:2, inner=2)
694+
@test R == [1, 1, 2, 2]
695+
R = repeat(1:2, outer=1)
696+
@test R == [1, 2]
697+
R = repeat(1:2, outer=2)
698+
@test R == [1, 2, 1, 2]
699+
R = repeat(1:2, inner=(3,), outer=(2,))
700+
@test R == [1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2]
701+
648702
A = rand(4,4)
649703
for s in Any[A[1:2:4, 1:2:4], sub(A, 1:2:4, 1:2:4)]
650704
c = cumsum(s, 1)

0 commit comments

Comments
 (0)