長さNのバイナリベクトルがあり、そのベクトル内の次の16個のシーケンスのそれぞれの頻度を探しているとします。
0000, 0001, 0010, 0011, ..., 1111
ベクトル内のこれらの各シーケンスのこれらの頻度をカウントする最も簡単な方法は何ですか?理想的には、MatLabでこれを行う方法を知りたいです。
これを解決する簡単な方法は、2 進数を 10 進数に変換してから、hist
またはaccumarray
を使用して出現回数を数えることです。配列を (N-3) 行 4 列の配列に再形成することから始めます。これにより、すべての計算をベクトル化できます。
%# make up some test data
data = [0 0 1 1 0 1 0 1 1 1 1 1 0 0 1 1];
%# reshape into a (N-3)-by-4 array
%# idx is [1 2 3 4;2 3 4 5;...]
idx = bsxfun(@plus,(1:length(data)-3)',0:3); %'#
data = data(idx);
%# convert binary numbers to decimals
%# use matrix multiplication
decData = data * [8;4;2;1];
%# count number of occurences - possible values are 0 through 15
counts = hist(decData,0:15);
counts(1)
シーケンスがリストに表示された回数をカウントし0 0 0 0
ます。
これらは 0x0 から 0xF までの数値であり、サイズ 0xF の配列へのインデックスとして ++ を付けただけです。配列要素の合計、および A[i]/N は頻度です。
count = zeros(1,16);
vector = [1 0 0 1 1 1 1 0 0];
N = length(vector);
for ii = 1:(N-3)
cur_seq = vector(ii:ii+3); % Grab the running set of four entries
cur_num = cur_seq*[8; 4; 2; 1]; % Convert these entries to non-binary.
% Update the count of the sequence that has cur_num
% as its non-binary integer representation. Note that
% you must use cur_num+1 as the index since Matlab is
% 1-based, but the integers from your sequences are 0
% through 15.
count(cur_num+1) = count(cur_num+1) + 1;
end
count(1)
の出現回数をカウントするようになり[0,0,0,0]
、 の出現回数をcount(2)
カウントするようになりまし[0,0,0,1]
た。
データとブロックの長さを次のように定義します。
x = [ 1 0 1 0 0 0 0 0 1 1];
M = 4;
次に、次のように 1 行で結果を取得できます。
result = histc(conv(x, 2.^(0:M-1), 'valid'), 0:2^M-1);
この例では、
result =
2 1 0 1 1 0 0 0 1 0 1 0 0 0 0 0
、の発生など2
の発生があったことを意味します。[0 0 0 0]
1
[0 0 0 1]
これがどのように機能するか:
データを保持している場合a
:
c = []
for el = a,
c = [c, sum(a==el)];
end
これは2次式ですが、カウントはと同じインデックスになりa
ます。事前に範囲がわからなくても動作します。