1

Matlab では、任意のビット長の符号なし整数 (3 ビット整数の配列など) を uint8 の配列にパックしようとしています。hereのヒントがあれば、 「小さな」配列 (たとえば 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 はそれほど効率的ではないことも読みました。

これを 16mil 要素 (8 GB のメモリを搭載した 64 ビット Windows ボックス) で試すと、すべてのメモリが消費されます。何とか。したがって、サブセクションをループすると、16mil の要素を完了するのに約 10 分かかります。だから、何かが非常に非効率的です。

python の BitArray のようなビット文字列を生成するより良い方法はありますか?

ありがとう、

4

2 に答える 2

1

これこれに似てる気がする

最初のものでは、for ループ内で dec2bitvec を使用することが提案されました。これで十分かもしれません(遅いと思います)。

2 つ目は、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 RAM)

ルックアップ テーブルを作成する代わりに、このコードは各整数のビット値 (列に格納されている) を含む行列 (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 に答える