如何在matlab中预先分配外部数据结构列表?

如何在matlab中预先分配外部数据结构列表?,matlab,Matlab,我的问题与外部定义的数据结构:张量有关。张量是一个多维数组。在中,张量是一个具有两个字段的类:t.data,t.size: % Create the tensor t.data = data; t.size = siz; t = class(t, 'tensor'); return; 与Matlab中的内置函数zeros()一样,我可以使用tenzeros(),创建一个充满零的张量,例如,tenzeros([2,3,4])。这个工具箱中还有其他类型的张量数

我的问题与外部定义的数据结构:张量有关。张量是一个多维数组。在中,张量是一个具有两个字段的类:t.data,t.size:

   % Create the tensor
    t.data = data;
    t.size = siz;
    t = class(t, 'tensor');
    return;
与Matlab中的内置函数
zeros()
一样,我可以使用
tenzeros()
,创建一个充满零的张量,例如,tenzeros([2,3,4])。这个工具箱中还有其他类型的张量数据结构:张量、sptensor、ktensor、ttensor等

我的问题是,如果每个张量大小相同[100200300],如何预先分配200个十零或其他张量类型?也就是说,为200个张量预先分配内存。原因是目前我使用for循环一个接一个地创建200个张量,内存要求非常高。有些人建议我在真正计算大型数据结构之前,为它们预先分配内存

因此,我想在开始时预先分配200个张量的数组;然后在一个for循环parfor循环)中,我计算每个张量的实际结果,并将其发送到预分配的空间

为什么我不能使用:

 c=repmat(tenzeros([100, 200, 300]),200,1)
它抛出:

Error using tensor.size
Too many output arguments.

Error in repmat (line 73)
    [m,n] = size(A);
----------
更新:

我为200个张量预分配内存,因为我听说内存预分配可以使内存中的数据连续,从而可以缓解OutOfMemory问题。实际上,我只需要将每个计算出的张量写入for循环中的每个txt文件,这意味着我不需要将200个张量一起作为最终结果

因此,目前我正在使用@Andrew Janke的第三段代码为开头的200个张量预先分配内存:

%Memory pre-allocation
c = cell([200, 1]);
parfor i = 1:numel(c)
    c{i} = tenrand([100,200,300]); %This is just a tensor with random values to fill in the memory space
end
然后,我虚拟地计算parfor循环中的200个张量,并填充预先分配的内存空间(即c):

  • 第二部分是否会用预先分配的内存覆盖c中的空间?
  • 体验
    a传感器=c{i}
    :它不会复制副本,对吗?(我不更改传感器)

您可以使用
repmat
基本上与您相同的方式预先分配初始化的
张量对象的单元格数组,但需要将每个张量粘贴到单元格中

c=repmat( { tenzeros([100, 200, 300]) }, 200, 1);
{}
调用周围的大括号将其括在一个1乘1的单元格中

如果
repmat
发生故障,您可以通过自己从重复使用的临时变量分配单元格内容来解决问题。这基本上与repmat的速度一样快,并且具有相同的内存使用特性

sz = [200, 1];
c = cell(sz);
% Construct initial value *once* outside the loop
tmp = tensor(...);
for i = 1:numel(c)
    c{i} = tmp;
end    
请注意,这对性能的影响不如预分配基元数组,因为只有组合类型的顶级“容器”级别得到预分配,并且可能会进行适当的修改。存储在对象字段(如张量)中的数组在函数内更改其值时仍然会被复制,甚至可能在最初创建它们的本地工作区中也会被复制

这将有助于提高峰值内存使用率,因为所有初始零张量都将通过写时复制优化共享内存。因此,通过多次构造函数调用在循环中使用新的张量初始化单元数组更有效。但是,由于您无论如何都要丢弃这些初始零值,因此最有效的内存使用方法是使用空单元格初始化它

sz = [200, 1];
c = cell(sz);
parfor i = 1:numel(c)
    c{i} = calculate_your_result(...);
end

因为
张量是一种复合类型(对象),所以预分配对它们占用的空间没有多大帮助。您可能应该估算出在最佳情况下您的数据集需要多少内存,并查看它与您看到的实际使用情况的比较。此应用程序可能只需要更多内存。

这是
repmat()
调用引发错误吗?这就是通常预分配非特殊值数组(如0、1或NaN)的方法。尽管可能发生的情况是,
tensor
类已经实现为数组,因此只会产生更大的张量。填充单元格时使用了什么语法?要分配单元格内容,您需要执行
c{i,j,…}=t
而不是
c(i,j,…)=t
repmat
中的错误看起来像是Tensor工具箱中的一个bug,它们没有实现
size()
的所有调用形式和相关函数来完全支持数组样式的行为。你能不能再详细介绍一下你想要得到的预分配数据结构,以及为什么要预分配它?我刚试过,但还是出现了错误:尝试引用非结构数组的字段。tensor/isequal(第21行)中的错误如果repmat(第21行)中的~isequal(x.size,y.size)错误,这是否意味着内存的预分配对内存问题没有帮助,因为tensor不是内置类型?语法错误-这很奇怪。可能是Tensor工具箱中的另一个bug,或者是一个混乱的对象。您是否使用工具箱提供的构造函数创建了
tensor
对象(而不是自己设置一个结构并调用
class()
)?关于内存使用-是的,恐怕差不多。等一下-您是否实际使用200x100x200x300作为张量的数组大小?这是巨大的,大约十亿个元素;这永远不会适合一个典型的PC内存。
sz = [200, 1];
c = cell(sz);
parfor i = 1:numel(c)
    c{i} = calculate_your_result(...);
end