【问题标题】:MATLAB list manipulationMATLAB 列表操作
【发布时间】:2016-10-14 07:54:10
【问题描述】:

假设我有如下代码段:

案例 1

n = 20;
for i = 2 : n
    mat = rand([2,i]);
    mat = [mat, mat(:,1)]; %add the first column to the last
    %feed the variable 'mat' to a function 
end 

案例 2

n = 10;
list = [];
for i = 1 : n
    a = rand([2,1]);
    b = rand([2,2])
    list = [list, [a,b]];
end

这样,MATLAB 给出如下建议:

变量“mat”似乎在每个循环中都会改变大小。考虑预分配以加快速度。

变量“列表”似乎在每个循环中都会改变大小。考虑预分配以加快速度。

我是 MATLAB 新手,所以我想知道如何处理这个问题。如何以原生 MATLAB 风格做到这一点?提前致谢。

【问题讨论】:

  • 你能展示更多你的代码吗?缺少一些重要的部分,尤其是循环。另外,您是什么意思:“将第一列添加到最后一列”?您要添加,如plus,还是替换最后一列,或者将其添加为单独的列,扩展矩阵(这就是您现在所做的)?
  • 问题是什么?
  • @StewieGriffin 感谢您的建议。确实我忘记了循环。
  • 这个 sn-p 没有意义。您在每个迭代步骤中创建一个新矩阵,然后附加一列,然后在下一个迭代步骤中再次覆盖。这相当于:mat = rand([2,20]); mat = [mat, mat(:,1)];,因此实际上不需要循环,您可以忘记警告...或者您可以指定要执行的操作。
  • 关于您的问题... google-ing MATLAB + preallocation 将您带到这里:de.mathworks.com/help/matlab/matlab_prog/…

标签: matlab matrix


【解决方案1】:

我将专注于第二种情况,因为它是唯一有意义的:

n = 10;
list = [];
for i = 1 : n
    a = rand([2,1]);
    b = rand([2,2])
    list = [list, [a,b]];
end

您在这里为每个循环创建两个带有随机数的向量,a 和 b。 a 的维度为 2x1,b 的维度为 2x2。然后,将这两者与矩阵 list 连接起来。

请注意,对rand 的每次调用都是独立的,因此rand(2,3) 的行为方式与[rand(2,2), rand(2,1)] 的行为方式相同。

现在,由于您循环了 10 次,并且每次都添加 rand(2,3),因此您实际上是在执行 [rand(2,2), rand(2,1), rand(2,2), rand(2,1) ...]。这相当于rand(2,30),速度要快很多。因此,“考虑预分配以加快速度。”


现在,如果您的连接不包含随机矩阵,但实际上是某个函数的输出,无法输出您想要的整个矩阵,那么使用索引将其预分配并插入到矩阵中:

让我们定义几个函数:

function x = loopfun(n)
x = n*[1; 2];
end


function list = myfun1(n)
list = zeros(2, n);
for ii = 1:n
    list(:,ii) = loopfun(ii);
end
end

function list = myfun2(n)    
list = [];
for ii = 1:n
    list = [list, loopfun(ii)];
end
end

f1 = @() myfun1(100000); f2 = @() myfun2(100000);
fprintf('Preallocated: %f\nNot preallocated: %f\n', timeit(f1), timeit(f2))

Preallocated: 0.141617
Not preallocated: 0.318272

如您所见,预分配函数的速度是矩阵大小增加的函数的两倍。如果迭代次数少,差异会更小,但大体思路是一样的。

f1 = @() myfun1(5); f2 = @() myfun2(5);
fprintf('Preallocated: %f\nNot preallocated: %f\n', timeit(f1), timeit(f2))

Preallocated: 0.000010
Not preallocated: 0.000018

【讨论】:

  • 感谢您的回答。我使用rand 来回答我的问题。事实上,a 和b来自其他函数的返回值。根据我的实现,a是2 x i的矩阵,b是2 x j的矩阵,其中i和j的取值范围是1到5。
猜你喜欢
  • 1970-01-01
  • 2013-04-30
  • 2016-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-03
  • 2012-03-17
  • 1970-01-01
相关资源
最近更新 更多