MATLAB中的矩阵数组

40

我正在寻找一种在MATLAB中将大量矩阵存储在数组中的方法。

是否有任何方法可以实现这一点?

示例:

for i: 1:unknown
  myArray(i) = zeros(500,800);
end

如果数组长度未知,如需更多信息,我可以进行修改。

更新: 性能是我尝试实现这一目标的主要原因。之前,它会将数据作为单个矩阵获取,在实时显示后继续处理下一组数据。

我尝试了下面Rocco建议的使用多维数组的方法,但我的数据太大了,导致内存不足,我可能需要寻找另一种解决方案。我会在尝试其他建议后进行更新。

更新2: 感谢所有人的建议,但我应该事先指定,精度和速度都是重要因素,我可能需要考虑回到原始方法,然后重新评估导入数据的方法,而不是尝试3D数组。


我猜使用单元矩阵不会对性能产生影响。因为它们本质上包含指向实际矩阵的指针,扩展它们(即使使用动态索引)不应该产生性能开销(除了最小限度地重新分配指针数组,这是可以忽略的)。 - Hosam Aly
6个回答

72

使用单元数组。这比3D数组具有优势,因为它不需要一个连续的内存空间来存储所有矩阵。实际上,每个矩阵可以存储在不同的内存空间中,如果您的可用内存是碎片化的,这将使您免受内存不足错误的困扰。下面是一个示例函数,用于在单元数组中创建矩阵:

function result = createArrays(nArrays, arraySize)
    result = cell(1, nArrays);
    for i = 1 : nArrays
        result{i} = zeros(arraySize);
    end
end

使用它:

myArray = createArrays(requiredNumberOfArrays, [500 800]);

访问你的元素:

myArray{1}(2,3) = 10;
如果你事先不知道矩阵数量,可以使用MATLAB的动态索引来使数组大小与需要的大小相同。性能开销将与cell数组的大小成比例,而不受矩阵本身大小的影响。例如:
myArray{1} = zeros(500, 800);
if twoRequired, myArray{2} = zeros(500, 800); end

@HosamAly 根据您的建议,我正在创建基于矩阵的2D数组。然后,有人建议我创建一个单一的4D数组,它比前者快9倍,但是当矩阵大小很大时,我遇到了内存限制问题。您有什么建议吗?线程在这里http://stackoverflow.com/q/40052664/54964 - Léo Léopold Hertz 준영
1
@Masi 抱歉,我不知道。 - Hosam Aly

45

如果所有的矩阵大小都相同(即500x800),那么你可以创建一个三维数组:

nUnknown;  % The number of unknown arrays
myArray = zeros(500,800,nUnknown);
要访问一个数组,您需要使用以下语法:

To access one array, you would use the following syntax:

subMatrix = myArray(:,:,3);  % Gets the third matrix

你可以用以下几种方法向myArray中添加更多的矩阵:

myArray = cat(3,myArray,zeros(500,800));
% OR
myArray(:,:,nUnknown+1) = zeros(500,800);
如果每个矩阵的大小不相同,您需要像Hosam建议的那样使用cell数组。

编辑:我错过了关于内存耗尽的部分。我猜你的nUnknown相当大。您可能需要切换矩阵的数据类型(single或甚至uintXX类型(如果您使用整数))。您可以在调用zeros时执行此操作:

myArray = zeros(500,800,nUnknown,'single');

3
使用3D数组的问题在于它需要在内存中占用连续的空间。虽然它可能比cell数组性能更好,但后者允许在不同的内存空间中分配2D矩阵,因此如果使用了碎片化的内存,则更适合使用cell数组。 - Hosam Aly

1
myArrayOfMatrices = zeros(unknown,500,800);

如果你的内存不足,请在系统中增加更多的RAM,并确保你使用的是64位操作系统。此外,尝试减少你的精度(你是否真的需要双精度浮点数,还是可以用单精度浮点数?):

myArrayOfMatrices = zeros(unknown,500,800,'single');

要向该数组追加,请尝试:

myArrayOfMatrices(unknown+1,:,:) = zeros(500,800);

0

我在Octave(Matlab克隆版)中进行一些体渲染,并使用以下方法构建我的3D数组(即2D切片的数组):

buffer=zeros(1,512*512*512,"uint16");
vol=reshape(buffer,512,512,512);

内存消耗似乎是高效的。(但计算速度就不能这么说了 : ^)


你可以直接使用zeros(512,512,512,'uint16'),这里不需要reshape,只需要多调用一个函数。 - Cris Luengo

-2

就像这样做

x=zeros(100,200);
for i=1:100
  for j=1:200
    x(i,j)=input('enter the number');
  end
end

这并没有回答问题。 - Keivan

-2

1
你需要一个三维数组来完成这个任务。你的例子会导致数组维度不匹配的错误。你可能是想要使用 myArray(:,:,i),但我不确定它的行为如何(因为我现在没有 MATLAB)。 - Hosam Aly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接