1

在Matlab 中,我试图将任意位长度的无符号整数(例如,3 位整数数组)打包成一个uint8 数组。鉴于此处的提示,我可以生成适用于“小型”数组(例如 10,000 个元素)的代码,但它会占用大型数组(例如 1600 万个元素)的所有内存。我使用的代码如下,借鉴了以前的帖子:

function x_bytes = stuff_bits(x, n)
    r = dec2bin(x,n);                 % bitstring for each uint in x
    s = reshape(r',[],1);             % one continuous string of bits
    t = reshape(str2num(s),8,[])';    % array of 8-bit numbers (stuffed)
    u = t*(2.^(size(t,2)-1:-1:0))';   % array of bytes representing all the bits stuffed together
    x_bytes = uint8(u);              % should be compressed byte stream
end

我意识到我正在使用一个 uint,将其转换为字符串,然后将其转换回位;我还读到 dec2bin 效率不是很高。

当我用 1600 万个元素(在具有 8 GB 内存的 64 位 Windows 机器上)尝试这个时,所有内存都被消耗掉了。废话。所以我循环遍历小节,完成 1600 万个元素大约需要 10 分钟。所以,有些东西是非常低效的。

有人有更好的方法来生成像 python 的 BitArray 这样的位字符串吗?

谢谢,

4

2 回答 2

1

它似乎与这个这个相似

在第一个中,建议在 for 循环中使用 dec2bitvec。这对你来说可能已经足够了(虽然很慢)。

第二个建议使用 bitget 创建一个查找表,然后使用它(而不是使用 dec2bit 或 dec2bitvec)

您可以尝试使用“中间”的东西。

B = 3; % Number of bits per int.
A = randi(7, 16000000, 1); % 16M random elements between 1 and 7 (3bits).

tic
% get each group of bits in a column of K.
K = cell2mat(arrayfun(@(bit)bitget(A, B+1-bit), 1:B, 'UniformOutput', 0))';
% reshape to have them in 8 packs
K = reshape(K, [8, numel(K)/8])';
% get the uint8 vec.
U = K*(2.^(size(K,2)-1:-1:0))';
toc

我的时间是 3.5 秒。(Win8 64 位,i5 4GB 内存)

此代码不是创建查找表,而是创建一个矩阵 (K),其中包含每个整数的位值(存储在列中),对其进行整形(以创建 8bin 值),然后使用与之前使用相同的数学来创建 uint8向量。

于 2013-01-23T23:59:52.737 回答
0

这是我为将位矩阵转换为 n 位长数字而创建的代码:

function [ uD10 ] = bits_to_n_bit_integers( A, n)
%bits_to_n_bit_integersTurns vector matrix of bits in A into a vector matrix of 
%n bits long numbers. 
%B is 1 for a bit matrix
%   Detailed explanation goes here

B = 1;
% get each group of bits in a column of K.
K = cell2mat(arrayfun(@(bit)bitget(A, B+1-bit), 1:B, 'UniformOutput', 0))';
%make sure there is multiple of B
K = K(:);
while ~(mod(numel(K),n) == 0)
    K = [0;K];
end
K = K(:);
% reshape to have them in 8 packs
K = reshape(K, [n, numel(K)/n])';
% get the uint8 vec.
UD = K*(2.^(size(K,2)-1:-1:0))';

uD10=bi2de(K);

end

:)

于 2014-12-17T19:11:56.420 回答