MATLAB中未知长度的矩阵?

Fli*_*ick 24 matlab matrix variable-length

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

我想知道是否有一种方法可以在我运行循环时执行此操作,或者是否需要将其设置为开始,以及如何执行此操作.

Amr*_*mro 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
Run Code Online (Sandbox Code Playgroud)

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

  1. 与上述50000次迭代相同的代码.
  2. 事先预先分配整个矩阵: list = zeros(50000,2); list(k,:) = [x y];
  3. 动态向矩阵添加向量: list = []; list(k,:) = [x y];

在我的机器上,结果是:

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


更新:

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

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

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

  • ps大多数可变大小的方法(如字符串类)不使用固定的块大小,而是通过乘法因子K(通常K = 2)增加大小.这将分配步骤的数量限制为O(log N),如果您关心内存效率,您可以选择K = 1.2或1.1并处理数学计算命中以权衡效率/分配步骤数. (8认同)
  • 你可能是对的..你可以很容易地修改代码来做到这一点.还可以调整许多参数:何时增加尺寸,增加多少,甚至增加因子(从K = 1.1开始并增加到2) (5认同)
  • 哇噢!一个富有洞察力的点+测量来证实它.谢谢. (4认同)

Lio*_*orH 14

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

例如

while (....)
   .....
   new_row =[x y] ; % new row with values x & y
   mat = [mat ; new_row]; 
Run Code Online (Sandbox Code Playgroud)

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

  • 对上面代码的最后一行使用替代语法可以更明确地扩展矩阵:`mat(end + 1,:) = new_row;` (2认同)

Jac*_*cob 7

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

它是方式更有效地对矩阵进行第一分配内存和然后使用它.但是如果你的程序需要这种灵活性,那就去吧.

我猜你需要继续向矩阵追加行.以下代码应该有效.

Matrix = [];

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

disp(Matrix);
Run Code Online (Sandbox Code Playgroud)

在这里,我们动态地重新分配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,:) = [];
Run Code Online (Sandbox Code Playgroud)