For example, [1 1 ; 2 2 ; 3 3] becomes
[1 1
1 1
1 1
2 2
2 2
2 2
3 3
3 3
3 3]
I am using this:
expander(orig,mult::Int) = orig[ceil(Int,(1:size(orig,1)*mult)/mult),:]; in Julia and the following in Matlab:
function expanded = expander(original,multiplier)
expanded = original(ceil((1:size(original,1)*multiplier)/multiplier),:);
end
Another matlab only way to do it is this:
expanded = kron(original,ones(multiplier,1));
I would prefer a superfast julia option if it exists.
This doesn't prove that kron is fastest, but I compared its time to how long it would just take to populate a similarly sized Array with ones, and kron did quite well:
original = [1 1 ; 2 2 ; 3 3];
multiplier = 3*10^6;
@time begin
for idx = 1:100
expanded = kron(original,ones(multiplier));
end
end
## 9.199143 seconds (600 allocations: 15.646 GB, 9.05% gc time)
@time begin
for idx = 1:100
myones = [ones(multiplier*size(original,1)) ones(multiplier*size(original,1))];
end
end
## 12.746123 seconds (800 allocations: 26.822 GB, 14.86% gc time)
Update In response to comments by David Sanders, here are tests wrapped in a function. The reason I did the tests globally, which I know isn't normal best practice, is because it seemed quite plausible to me that the objects might get created globally.
function kron_test(original, multiplier)
for idx = 1:100
expanded = kron(original,ones(multiplier));
end
end
function ones_test(original, multiplier)
for idx = 1:100
myones = [ones(multiplier*size(original,1)) ones(multiplier*size(original,1))];
end
end
## times given after first function call to compile
@time kron_test(original, multiplier); ## 11.107632 seconds (604 allocations: 15.646 GB, 23.98% gc time)
@time ones_test(original, multiplier); ## 15.849761 seconds (604 allocations: 26.822 GB, 33.50% gc time)
Personally, I'd just use repeat:
repeat(original, inner=(multiplier, 1))
Unlike kron, it's very readable and understandable. Unfortunately it is quite a bit slower. Even so, I'd only use kron if you've identified it as a performance bottleneck. While it's faster for computers to execute, it's much slower for humans to understand what's going on… and the performance of repeat should eventually get better (it's issue #15553).
Edit: As of Julia 1.2, repeat has indeed gotten significantly faster. It now rivals kron:
julia> @btime kron($original,ones($multiplier));
81.039 ms (6 allocations: 160.22 MiB)
julia> @btime repeat($original, inner=($multiplier, 1));
84.087 ms (27 allocations: 137.33 MiB)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With