是否有通过复制每一行来快速扩展矩阵n次的方法?

时间:2016-07-14 18:50:03

标签: arrays matlab multidimensional-array julia

例如,[1 1 ; 2 2 ; 3 3]变为

[1 1
 1 1
 1 1
 2 2
 2 2
 2 2
 3 3
 3 3
 3 3]

我正在使用这个: Julia中的expander(orig,mult::Int) = orig[ceil(Int,(1:size(orig,1)*mult)/mult),:];以及Matlab中的以下内容:

function expanded = expander(original,multiplier)
   expanded = original(ceil((1:size(original,1)*multiplier)/multiplier),:);
end

另一个matlab的唯一方法就是:

expanded = kron(original,ones(multiplier,1));

如果它存在,我更喜欢超快的朱莉娅选项。

3 个答案:

答案 0 :(得分:2)

这并不能证明kron是最快的,但是我将它的时间与用一个类似大小的数组填充多长时间进行比较,kron做得很好:

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)

更新在回应David Sanders的评论时,这里是包含在函数中的测试。我在全球范围内进行测试的原因,我知道这不是正常的最佳实践,因为我觉得对象可能是全局创建的,这似乎很合理。

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)

答案 1 :(得分:1)

你可以做到

a = [1 1 ; 2 2 ; 3 3]
a = a' #matrices are in column major order in julia, should  be faster this way
a = repmat(a,1,n) 
a = sortcols(a)

不幸的是,我不知道这种方法是什么"超快"但它相对简单直观

答案 2 :(得分:1)

就个人而言,我只使用repeat

repeat(original, inner=[multiplier, 1])

kron不同,它具有很强的可读性和易懂性。不幸的是它慢了很多。即便如此,如果您已将其识别为性能瓶颈,我也只会使用kron。虽然计算机执行起来要快得多,但人们理解正在发生的事情要慢得多...... repeat的表现最终应该会变得更好(它会变得更好) issue #15553)。