MATLAB中未知长度的矩阵?

时间:2009-10-10 14:34:49

标签: matlab matrix variable-length

我正在尝试设置一个可变长度的零矩阵,其中有两列我可以输出while循环的结果(目的是使用它来存储来自Euler方法的步骤数据,并调整时间步长)。长度将由循环的迭代次数决定。

我想知道在我运行循环时是否有办法可以做到这一点,或者我是否需要将其设置为开始,以及如何去做。

4 个答案:

答案 0 :(得分:47)

在尝试节省空间时考虑性能的另一种方法是大批量预分配内存,根据需要添加更多批次。如果您必须在不知道预先确定的数量的情况下添加大量项目,这非常适合。

BLOCK_SIZE = 2000;                          % initial capacity (& increment size)
listSize = BLOCK_SIZE;                      % current list capacity
list = zeros(listSize, 2);                  % actual list
listPtr = 1;                                % pointer to last free position

while rand<1-1e-5                           % (around 1e5 iterations on avrg)
  % push items on list
  list(listPtr,:) = [rand rand];            % store new item
  listPtr = listPtr + 1;                    % increment position pointer

  % add new block of memory if needed
  if( listPtr+(BLOCK_SIZE/10) > listSize )  % less than 10%*BLOCK_SIZE free slots
    listSize = listSize + BLOCK_SIZE;       % add new BLOCK_SIZE slots
    list(listPtr+1:listSize,:) = 0;
  end
end
list(listPtr:end,:) = [];                   % remove unused slots

编辑:作为时间比较,请考虑以下情况:

  1. 与50000次迭代相同的代码。
  2. 事先预先分配整个矩阵:list = zeros(50000,2); list(k,:) = [x y];
  3. 动态向矢量添加矢量:list = []; list(k,:) = [x y];
  4. 在我的机器上,结果是:

      

    1)经过的时间 0.080214秒    2)经过的时间是0.065513秒    3)经过的时间是24.433315秒。


    更新

    在评论中讨论后,我使用最新的R2014b版本重新运行了一些测试。结论是最近版本的MATLAB大大提高了自动阵列增长的性能!

    然而有一个问题;数组必须在最后一个维度上增长(在2D矩阵的情况下为列)。这就是为什么在没有预分配的情况下追加原先预期的行仍然太慢的原因。这就是上面提出的解决方案真正有用的地方(通过批量扩展数组)。

    请参阅此处查看完整的测试集:https://gist.github.com/amroamroamro/0f104986796f2e0aa618

答案 1 :(得分:14)

如果列数固定,您可以随时向矩阵中添加行(在循环内)

e.g。

while (....)
   .....
   new_row =[x y] ; % new row with values x & y
   mat = [mat ; new_row]; 

当然,如果您知道while循环之前的迭代次数,那么预分配矩阵会更有效

答案 2 :(得分:7)

MATLAB使用动态类型和自动内存管理。这意味着,在使用之前不需要声明固定大小的矩阵 - 您可以随时更改它,MATLAB将为您动态分配内存。

但是首先为矩阵分配内存并然后使用它是方式更有效。但是如果你的程序需要这种灵活性,那就去吧。

我猜你需要继续向矩阵追加行。以下代码应该可以使用。

Matrix = [];

while size(Matrix,1) <= 10
    Matrix = [Matrix;rand(1,2)];
end

disp(Matrix);

在这里,每次添加新行时,我们都会动态地重新分配Matrix所需的空间。如果您事先知道,例如,您将要拥有的行数的上限,您可以声明Matrix = zeros(20,2),然后逐步将每行插入矩阵。

% Allocate space using the upper bound of rows (20)
Matrix = zeros(20,2);
k = 1;
for k = 1:10
   Matrix(k,:) = rand(1,2);
end
% Remove the rest of the dummy rows
Matrix(k+1:end,:) = [];

答案 3 :(得分:4)

雅各布发布的另一种同样的东西。

for counter = 1:10
    Matrix(counter,:) = rand(1,2);
end
disp(Matrix);

关于这一点,一个“好”的事情是你可以猜出最小尺寸来帮助表现。

这也可能是有意义的:http://www.mathworks.com/help/matlab/math/resizing-and-reshaping-matrices.html#f1-88760