Skip to content

Commit 4bc89f2

Browse files
committed
Add Compat.repeat() accepting any AbstractArray
Compatibility for JuliaLang/julia#14082. Since the new version in Julia 0.5 calls similar() internally, it is not enough to wrap it into a compatibility function to backport the fix. This is required to deprecate rep() from DataArrays.jl, which provides similar functionality for two custom array types.
1 parent 8ddd0a8 commit 4bc89f2

File tree

3 files changed

+51
-0
lines changed

3 files changed

+51
-0
lines changed

Diff for: README.md

+2
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ Currently, the `@compat` macro supports the following syntaxes:
217217
Compat provides an unexported `Compat.AsyncCondition` type that is aliased to
218218
`Base.SingleAsyncWork` on Julia 0.3 and 0.4 and `Base.AsyncCondition` on Julia 0.5.
219219

220+
* `repeat` now accepts any `AbstractArray` [#14082](https://github.com/JuliaLang/julia/pull/14082): `Compat.repeat` supports this new API on Julia 0.3 and 0.4, and calls `Base.repeat` on 0.5.
221+
220222
## New types
221223

222224
* [`Nullable` types](http://julia.readthedocs.org/en/latest/manual/types/?highlight=nullable#nullable-types-representing-missing-values) and their associated operations.

Diff for: src/Compat.jl

+45
Original file line numberDiff line numberDiff line change
@@ -1157,4 +1157,49 @@ if !isdefined(Base, @compat Symbol("@static"))
11571157
export @static
11581158
end
11591159

1160+
# JuliaLang/julia#14082
1161+
if VERSION < v"0.5.0-dev+4295"
1162+
function repeat(A::AbstractArray;
1163+
inner=ntuple(x->1, ndims(A)),
1164+
outer=ntuple(x->1, ndims(A)))
1165+
ndims_in = ndims(A)
1166+
length_inner = length(inner)
1167+
length_outer = length(outer)
1168+
1169+
length_inner >= ndims_in || throw(ArgumentError("number of inner repetitions ($(length(inner))) cannot be less than number of dimensions of input ($(ndims(A)))"))
1170+
length_outer >= ndims_in || throw(ArgumentError("number of outer repetitions ($(length(outer))) cannot be less than number of dimensions of input ($(ndims(A)))"))
1171+
1172+
ndims_out = max(ndims_in, length_inner, length_outer)
1173+
1174+
inner = vcat(collect(inner), ones(Int,ndims_out-length_inner))
1175+
outer = vcat(collect(outer), ones(Int,ndims_out-length_outer))
1176+
1177+
size_in = size(A)
1178+
size_out = ntuple(i->inner[i]*size(A,i)*outer[i],ndims_out)::Dims
1179+
inner_size_out = ntuple(i->inner[i]*size(A,i),ndims_out)::Dims
1180+
1181+
indices_in = Array(Int, ndims_in)
1182+
indices_out = Array(Int, ndims_out)
1183+
1184+
length_out = prod(size_out)
1185+
R = similar(A, size_out)
1186+
1187+
for index_out in 1:length_out
1188+
indices_out = ind2sub(size_out, index_out)
1189+
for t in 1:ndims_in
1190+
# "Project" outer repetitions into inner repetitions
1191+
indices_in[t] = mod1(indices_out[t], inner_size_out[t])
1192+
# Find inner repetitions using flooring division
1193+
indices_in[t] = Base.fld1(indices_in[t], inner[t])
1194+
end
1195+
index_in = sub2ind(size_in, indices_in...)
1196+
R[index_out] = A[index_in]
1197+
end
1198+
1199+
return R
1200+
end
1201+
else
1202+
const repeat = Base.repeat
1203+
end
1204+
11601205
end # module

Diff for: test/runtests.jl

+4
Original file line numberDiff line numberDiff line change
@@ -1164,3 +1164,7 @@ let io = IOBuffer(), s = "hello"
11641164
@test string(s, s, s) == "hellohellohello"
11651165
@test String == @compat(Union{Compat.UTF8String,Compat.ASCIIString})
11661166
end
1167+
1168+
@test Compat.repeat(1:2, inner=2) == [1, 1, 2, 2]
1169+
@test Compat.repeat(1:2, outer=[2]) == [1, 2, 1, 2]
1170+
@test Compat.repeat([1,2], inner=(2,)) == [1, 1, 2, 2]

0 commit comments

Comments
 (0)