Skip to content

Commit e9c976e

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 090b82d commit e9c976e

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ Currently, the `@compat` macro supports the following syntaxes:
213213
Compat provides an unexported `Compat.AsyncCondition` type that is aliased to
214214
`Base.SingleAsyncWork` on Julia 0.3 and 0.4 and `Base.AsyncCondition` on Julia 0.5.
215215

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

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

src/Compat.jl

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,4 +1138,49 @@ if !isdefined(Base, @compat Symbol("@static"))
11381138
export @static
11391139
end
11401140

1141+
# JuliaLang/julia#14082
1142+
if VERSION < v"0.5.0-dev+4295" && VERSION >= v"0.4"
1143+
function repeat(A::AbstractArray;
1144+
inner=ntuple(x->1, ndims(A)),
1145+
outer=ntuple(x->1, ndims(A)))
1146+
ndims_in = ndims(A)
1147+
length_inner = length(inner)
1148+
length_outer = length(outer)
1149+
1150+
length_inner >= ndims_in || throw(ArgumentError("number of inner repetitions ($(length(inner))) cannot be less than number of dimensions of input ($(ndims(A)))"))
1151+
length_outer >= ndims_in || throw(ArgumentError("number of outer repetitions ($(length(outer))) cannot be less than number of dimensions of input ($(ndims(A)))"))
1152+
1153+
ndims_out = max(ndims_in, length_inner, length_outer)
1154+
1155+
inner = vcat(collect(inner), ones(Int,ndims_out-length_inner))
1156+
outer = vcat(collect(outer), ones(Int,ndims_out-length_outer))
1157+
1158+
size_in = size(A)
1159+
size_out = ntuple(i->inner[i]*size(A,i)*outer[i],ndims_out)::Dims
1160+
inner_size_out = ntuple(i->inner[i]*size(A,i),ndims_out)::Dims
1161+
1162+
indices_in = Vector{Int}(ndims_in)
1163+
indices_out = Vector{Int}(ndims_out)
1164+
1165+
length_out = prod(size_out)
1166+
R = similar(A, size_out)
1167+
1168+
for index_out in 1:length_out
1169+
ind2sub!(indices_out, size_out, index_out)
1170+
for t in 1:ndims_in
1171+
# "Project" outer repetitions into inner repetitions
1172+
indices_in[t] = mod1(indices_out[t], inner_size_out[t])
1173+
# Find inner repetitions using flooring division
1174+
indices_in[t] = Base.fld1(indices_in[t], inner[t])
1175+
end
1176+
index_in = sub2ind(size_in, indices_in...)
1177+
R[index_out] = A[index_in]
1178+
end
1179+
1180+
return R
1181+
end
1182+
else
1183+
const repeat = Base.repeat
1184+
end
1185+
11411186
end # module

test/runtests.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,3 +1147,9 @@ end
11471147
else
11481148
@test VERSION < v"0.4"
11491149
end
1150+
1151+
if VERSION >= v"0.4"
1152+
@test Compat.repeat(1:2, inner=2) == [1, 1, 2, 2]
1153+
@test Compat.repeat(1:2, outer=[2]) == [1, 2, 1, 2]
1154+
@test Compat.repeat([1,2], inner=(2,)) == [1, 1, 2, 2]
1155+
end

0 commit comments

Comments
 (0)