MATLAB中的未知长度矩阵?

MATLAB中的未知长度矩阵?,matlab,matrix,variable-length,Matlab,Matrix,Variable Length,我试图建立一个可变长度的零矩阵,它有两列,我可以在其中输出while循环的结果(目的是用它来存储Euler方法中的步长数据,并调整时间步长)。长度将由循环的迭代次数决定 我想知道在运行循环时是否有一种方法可以做到这一点,或者是否需要首先设置它,以及如何进行设置 MATLAB使用带有自动内存管理的动态类型。这意味着,在使用之前,您不需要声明固定大小的矩阵-您可以在使用过程中对其进行更改,MATLAB将为您动态分配内存 但是首先为矩阵分配内存,然后再使用它是一种更有效的方法。但是如果你的程序需要这种

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


我想知道在运行循环时是否有一种方法可以做到这一点,或者是否需要首先设置它,以及如何进行设置

MATLAB使用带有自动内存管理的动态类型。这意味着,在使用之前,您不需要声明固定大小的矩阵-您可以在使用过程中对其进行更改,MATLAB将为您动态分配内存

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

我猜你需要继续在矩阵中添加行。下面的代码应该可以工作

Matrix = [];

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

disp(Matrix);

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

e、 g


当然,如果您知道while循环之前的迭代次数,那么预先分配矩阵会更有效,因为它是Jacob发布的另一种类型

for counter = 1:10
    Matrix(counter,:) = rand(1,2);
end
disp(Matrix);
一个“好”的地方是你可以猜出一个最小的尺寸来帮助你的表现


这可能也很有趣:

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

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
BLOCK_SIZE=2000;%初始容量(&增量大小)
listSize=块大小;%当前列表容量
列表=零(列表大小,2);%实际清单
listPtr=1;%指向最后自由位置的指针
而rand listSize)%10%以下*块大小的空闲插槽
listSize=listSize+块大小;%添加新的块大小插槽
列表(listPtr+1:listSize,:)=0;
结束
结束
列表(listPtr:end,:)=[];%移除未使用的插槽

<强>编辑< /强>:作为时间比较,考虑以下情况:

  • 与上面代码相同的代码进行了50000次迭代
  • 预先分配整个矩阵:
    list=0(50000,2);列表(k,:)=[xy]
  • 向矩阵动态添加向量:
    list=[];列表(k,:)=[xy]
  • 在我的机器上,结果是:

    1) 运行时间为0.080214秒
    2) 运行时间为0.065513秒。
    3) 运行时间为24.433315秒


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

    然而,有一个陷阱;数组必须在最后一个维度上增长(对于二维矩阵,为列)。这就是为什么在没有预分配的情况下,像最初预期的那样追加行仍然太慢的原因。这正是上述建议的解决方案真正有帮助的地方(通过成批扩展阵列)


    有关完整的测试集,请参见此处:

    +1我一直在使用它。请注意,您也可以只使用一个计数器,Matlab将增长数组。我开始了解您正在做什么,以及为什么它是有效的。非常有帮助,谢谢。非常感谢!这对我来说很有意义。你认为作为一个编程单元,他们会教我们一些,但他们却把我们丢到了狼群中。谢谢你救了我:)对上面代码的最后一行使用替代语法可以更明确地表示你在扩展矩阵:
    mat(end+1,:)=new_row如果这是一个类分配,并且您需要显示迭代,那么也可以查看上的一些速度提示;您可以在Euler实现中使用sprintf。另一个相关问题:呜呜!一个有见地的点+测量来证实它。谢谢。大多数可变大小的方法(如字符串类)不使用固定的块大小,而是通过乘法因子K(通常K=2)增加大小。这将分配步骤的#限制为O(logn),如果您关心内存效率,您可以选择K=1.2或1.1,并处理数学计算,以权衡分配步骤的效率。您可能是对的。。您可以很容易地修改代码来实现这一点。还可以调整一些参数:何时增加大小,增加多少,甚至可能是一个增长因子(从K=1.1开始,增加到2)。关于这一点,我有一个问题,这个可以转换为类吗?@masad:当然可以!我在文件交换上看到了一些类似的提交。下面是约翰·德里科(John D'Errico)的一篇文章,他简要地讨论了一下:。在内部,它的实现方式与我的不同,但您可以模拟接口。
    
    for counter = 1:10
        Matrix(counter,:) = rand(1,2);
    end
    disp(Matrix);
    
    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