Skip to content

Commit d418899

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 b7eed50 commit d418899

File tree

4 files changed

+148
-51
lines changed

4 files changed

+148
-51
lines changed

Diff for: base/abstractarraymath.jl

+43-13
Original file line numberDiff line numberDiff line change
@@ -200,31 +200,61 @@ 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=(), outer=())
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.
210+
211+
```jldoctest
212+
julia> repeat(1:2, inner=2)
213+
4-element Array{Int64,1}:
214+
1
215+
1
216+
2
217+
2
218+
219+
julia> repeat(1:2, outer=2)
220+
4-element Array{Int64,1}:
221+
1
222+
2
223+
1
224+
2
225+
226+
julia> repeat([1 2; 3 4], inner=(2, 1), outer=(1, 3))
227+
4×6 Array{Int64,2}:
228+
1 2 1 2 1 2
229+
1 2 1 2 1 2
230+
3 4 3 4 3 4
231+
3 4 3 4 3 4
232+
```
233+
"""
234+
function repeat(A::AbstractArray;
235+
inner=ntuple(_->1, ndims(A)),
236+
outer=ntuple(_->1, ndims(A)))
207237
ndims_in = ndims(A)
208238
length_inner = length(inner)
209239
length_outer = length(outer)
210-
ndims_out = max(ndims_in, length_inner, length_outer)
211240

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
241+
length_inner >= ndims_in || throw(ArgumentError("number of inner repetitions ($(length(inner))) cannot be less than number of dimensions of input ($(ndims(A)))"))
242+
length_outer >= ndims_in || throw(ArgumentError("number of outer repetitions ($(length(outer))) cannot be less than number of dimensions of input ($(ndims(A)))"))
243+
244+
ndims_out = max(ndims_in, length_inner, length_outer)
215245

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

219249
size_in = size(A)
220250
size_out = ntuple(i->inner[i]*size(A,i)*outer[i],ndims_out)::Dims
221251
inner_size_out = ntuple(i->inner[i]*size(A,i),ndims_out)::Dims
222252

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

226256
length_out = prod(size_out)
227-
R = Array(T, size_out)
257+
R = similar(A, size_out)
228258

229259
for index_out in 1:length_out
230260
ind2sub!(indices_out, size_out, index_out)

Diff for: base/docs/helpdb/Base.jl

-10
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

Diff for: doc/stdlib/linalg.rst

+24-1
Original file line numberDiff line numberDiff line change
@@ -979,12 +979,35 @@ 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=(), outer=())
983983

984984
.. Docstring generated from Julia source
985985
986986
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.
987987

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
1010+
9881011
.. function:: kron(A, B)
9891012

9901013
.. Docstring generated from Julia source

Diff for: test/arrayops.jl

+81-27
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)