假设我有一个长度为 N 的二进制向量,我正在寻找该向量中以下 16 个序列中每个序列的频率:
0000, 0001, 0010, 0011, ..., 1111
计算向量中每个序列的频率的最简单方法是什么?理想情况下,我想知道如何在 MatLab 中做到这一点。
解决此问题的一种简单方法是将二进制数转换为十进制数,然后使用其中一个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;
然后可以用一行得到结果如下:
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
这是二次的,但计数与 相同a
。如果您事先不知道范围,它也会起作用。