MATLAB 中未知长度的矩阵?

发布于 2024-08-07 05:49:56 字数 155 浏览 5 评论 0原文

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

我想知道是否有一种方法可以在运行循环时执行此操作,或者是否需要首先对其进行设置,以及如何执行此操作。

I'm trying to set up a zero matrix of variable length with two columns into which I can output the results of a while loop (with the intention of using it to store the step data from Euler's method with adjusted time-steps). The length will be determined by the number of iterations of the loop.

I'm wondering if there's a way I can do this while I'm running the loop or whether I need to set it up to begin with, and how to go about doing that.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

眼眸里的快感 2024-08-14 05:49:56

另一种在考虑性能的同时仍努力提高空间效率的方法是大批量预分配内存,根据需要添加更多批次。如果您必须添加大量项目但事先不知道有多少项目,那么这非常适合。

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,:) = [xy];
  3. 动态添加向量到矩阵:list = []; list(k,:) = [xy];

在我的机器上,结果是:

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


更新:

根据评论中的讨论,我使用最新的 R2014b 版本重新运行了一些测试。结论是,最新版本的 MATLAB 极大地提高了自动数组增长的性能!

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

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

Another approach that has performance in mind while still trying to be space-efficient, is to preallocate memory in large batches, adding more batches as needed. This is well suited if you have to add a large number of items without knowing how many beforehand.

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

EDIT: As a time comparison, consider the following cases:

  1. The same code as above done for 50000 iterations.
  2. Preallocating the entire matrix beforehand: list = zeros(50000,2); list(k,:) = [x y];
  3. Dynamically adding vectors to matrix: list = []; list(k,:) = [x y];

On my machine, the results were:

1) Elapsed time is 0.080214 seconds.
2) Elapsed time is 0.065513 seconds.
3) Elapsed time is 24.433315 seconds.


Update:

Following discussions in the comments, I've rerun some tests using the latest R2014b release. The conclusion is that recent versions of MATLAB has greatly improved the performance of automatic array growth!

However there is a catch; the array must be growing across the last dimension (columns in the case of 2D matrices). That's why appending rows like originally intended is still too slow without preallocation. This is where the above proposed solution can really help (by extending the array in batches).

See here for the full set of tests: https://gist.github.com/amroamroamro/0f104986796f2e0aa618

哀由 2024-08-14 05:49:56

如果列数是固定的,您始终可以向矩阵添加行(在循环内)

,例如,

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

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

if the number of columns is fixed you can always add rows to your matrix (inside the loop)

e.g.

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

of course if you know the number of iterations before the while loop it's more efficient to pre-allocate the matrix

骷髅 2024-08-14 05:49:56

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,:) = [];

MATLAB uses dynamic typing with automatic memory management. This means, you don't need to declare a matrix of a fixed size before using it - you can change it as you go along and MATLAB will dynamically allocate memory for you.

BUT it is way more efficient to allocate memory for the matrix first and then use it. But if your programs needs this kind of flexibility, go for it.

I'm guessing you need to keep appending rows to your matrix. The following code should work.

Matrix = [];

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

disp(Matrix);

Here, we're dynamically reallocating the space required for Matrix every time you add a new row. If you know beforehand, say, an upper bound on the number of rows you're going to have, you can declare Matrix = zeros(20,2) and then insert each row into the matrix incrementally.

% 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,:) = [];

雅各布发布的同一件事的另一种风味。

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

Another flavor of the same thing that Jacob posted.

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

One "nice" thing about this is you can guess a minimum size to help the performance along.

This might be of interest as well: http://www.mathworks.com/help/matlab/math/resizing-and-reshaping-matrices.html#f1-88760

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文