MATLAB:双重和逻辑数据分配之间的区别

时间:2015-09-04 16:27:50

标签: arrays matlab memory type-conversion

我需要创建一个超过MATLAB数组大小限制的大型二进制矩阵。 默认情况下,MATLAB将整数数组创建为双精度数组。但由于我的矩阵是二进制的,我希望有一种方法来创建一个位数组而不是双精度数并消耗更少的内存。 我创建了一个随机二进制矩阵B并将其转换为逻辑数组A = randi([0 1], 1000, 1000); B=logical(A);

{{1}}

我将两个都保存为.mat文件。它们占用了我计算机上相同的空间,所以我不认为MATLAB使用更紧凑的逻辑数据类型,这看起来非常浪费。有什么想法吗?

2 个答案:

答案 0 :(得分:3)

肯定这些变量是否占用相同的空间? logical数据矩阵/数组本身就是每个数字1个字节,其中randidouble精度,即每个数字8个字节。对whos的简单调用将显示每个变量占用多少内存:

>> A = randi([0 1], 1000, 1000);
>> B = logical(A);
>> whos
  Name         Size                Bytes  Class      Attributes

  A         1000x1000            8000000  double               
  B         1000x1000            1000000  logical 

如您所见,A需要8 x 1000 x 1000 = 8M字节,其中B占用1 x 1000 x 1000 = 1M字节。他们之间肯定会节省内存。

逻辑的缺点是每个数字需要1个字节,而您正在寻找1 。我能想到的最好的事情是使用无符号整数类型和N交错块 - 其中N是数据类型的关联位精度,所以{ {1}}等成为单个交错数组。因此,每个数字可以交错32位,您可以保存这个最终矩阵。

在切线上移动 - 图像

事实上,这就是Java在使用uint8, uint16, uint32类读取图像时打包彩色像素的方式。 RGB图像中的每个像素是24位,每个颜色通道有8位 - 红色,绿色和蓝色。每个像素表示为红色,绿色和蓝色的比例,并且它们将8位的三个连接成单个24位整数。通常,整数表示为32位,因此您可能认为有8个额外位被浪费。事实上, alpha通道表示每个颜色像素的透明度,而另一个8位代表这一点。如果不使用透明度,则假设这些都是1,因此这4对8位的集合构成每像素32位。但是,有一些压缩算法可以将每个像素的平均大小减小到每像素大小不到32位,但这超出了我所说的范围。

回到我们的讨论,以位形式表示这个二进制矩阵的一种方法可能是BufferedImage循环,如下所示:

for

请记住,这只适用于元素总数可以被32整除的矩阵。我不会讨论如何处理它不是因为我只想说明你的观点可以做你所要求的,但它需要一些操纵。你的1000 x 1000 = 1M的情况肯定可以被32整除(你得到1M / 32 = 31250),所以这将有效。

这可能不是最优化的代码,但它得到了重点。基本上,我们从左到右依次列出32个数字(0/1)的块,并确定该数字的32位无符号整数表示。然后,我们将其存储在矩阵Abin = zeros(1, ceil(numel(A)/32), 'uint32'); for ii = 1 : numel(Abin) val = A((ii-1)*32 + 1:ii*32); dec = bin2dec(sprintf('%d', val)); Abin(ii) = dec; end 中的单个位置。考虑到1000 x 1000矩阵,最终得到的是31250 32位无符号整数,对应于1000 x 1000 ,或1M位= 125,000字节。

现在尝试查看每个变量的大小:

Abin

要执行重建,请尝试:

>> whos
  Name         Size                 Bytes  Class      Attributes

  A         1000x1000             8000000  double               
  Abin        1x31250              125000  uint32                           
  B         1000x1000             1000000  logical              

也不是最优化的,但它得到了重点。给定我们之前计算的“压缩”矩阵Arec = zeros(size(A)); for ii = 1 : numel(Abin) val = dec2bin(Abin(ii), 32) - '0'; Arec((ii-1)*32 + 1:ii*32) = val(:); end ,对于每个元素,我们重建原始32位数,然后将这些数字分配给存储在Abin中的32位块。

您可以验证Arec确实等于原始矩阵Arec

A

另外,请使用>> isequal(A, Arec) ans = 1

查看工作区
whos

答案 1 :(得分:1)

您正在以压缩文件格式存储数据。对于版本7.0和7.3中的mat文件,使用gzip压缩。未压缩的数据具有不同的大小,但在压缩之后,两者都被压缩到大致相同的大小。发生这种情况是因为两个数据只包含0和1,可以高效压缩。