【问题标题】:Taking alternatively elements of two vectors and compose them in Matlab [duplicate]交替取两个向量的元素并在Matlab中组合它们[重复]
【发布时间】:2016-06-01 16:43:16
【问题描述】:

你能帮我在 Matlab 中写下一个非常快速的算法,它执行以下操作:我有 2 向量、A 维度 nx1B 维度 nx1。我想构造维度为2nx1C 这样

C(1)=A(1), C(2)=B(1), C(3)=A(2), C(4)=B(2), C(5)=A(3), C(6)=B(3), ... 

我想

C=[];
for j=1:n
    C=[C; [A(j) B(j)]'];
end

你知道更快更高效的事情吗?

例子:

n=9
A=[1 3 5 7 9 11 13 15 17]';
B=[2 4 6 8 10 12 14 16 18]';
C=[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18]';

【问题讨论】:

  • 您不想要一个快速的答案吗?我添加了一个显示相对性能的基准。

标签: arrays matlab


【解决方案1】:

通常,您会希望避免在循环中将数据附加到数组中,就像您编写的那样,因为当您展开变量时,每次都必须通过循环重新分配内存。 p>

最简单的做法是使用(:).' 将它们都转换为行向量,沿第一个维度连接它们,然后使用reshape 展平为列向量。由于 MATLAB 的列优先顺序,这将自动交错 AB 的值以创建 C

C = reshape(cat(1, A(:).', B(:).'), [], 1)

基准测试

至于这是否比索引更快(@ThP 的回答),这里是对两者进行基准测试的简短测试。

sizes = round(linspace(100, 10000, 100));

times1 = zeros(size(sizes));
times2 = zeros(size(sizes));

for k = 1:numel(sizes)
    A = rand(sizes(k), 1);
    B = rand(sizes(k), 1);

    times1(k) = timeit(@()combine1(A,B));
    times2(k) = timeit(@()combine2(A,B));
end

figure
plot(sizes, times1)
hold on
plot(sizes, times2)
legend('cat + reshape', 'Indexing')

function C = combine1(A, B)
    C = reshape(cat(1, A(:).', B(:).'), [], 1);
end

function C = combine2(A,B)
    C = zeros(2*numel(A),1);
    C(1:2:end) = A;
    C(2:2:end) = B;
end

【讨论】:

  • 不错。按照 Luis Mendo 的建议,使用 C(2*n,1)=0 进行比较会很有趣
  • @ThP 我比较了它。几乎没有任何区别。i.imgur.com/1DqE2gc.png
  • 只是微优化,但是下面稍微快一点 `C = [A(:).'; B(:).']; C = C(:);` 猜测是它只是一个函数调用(因为差异是关于“cat + reshape”的常数),但如果问题由许多函数调用组成,它可能很重要。跨度>
【解决方案2】:

在 matlab 中,索引操作通常比 for 循环快。
我要做的是首先构造一个2nx1 矩阵,然后使用索引来分配值:

C = zeros(2*n,1);
C(1:2:end) = A;
C(2:2:end) = B;

【讨论】:

  • c(2*n,1) = 0 初始化c 甚至更快(虽然公认是hackish)
  • 有趣...不知道。
  • this answer和链接的帖子@ThP
  • @LuisMendo 2015b 的新执行引擎似乎不再是这种情况了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-08
相关资源
最近更新 更多