如何从概率条形图生成随机向量?
How do I generate random vectors from a bar graph of probabilities?
我生成了一个条形图,用于计算 16 位二进制字符串的每一位中 1 的数量:
我想生成大致遵循上述分布的 300 个 16 位二进制向量。
最初,我的代码依赖于概率数组 gengen
,它计算每个位中 1 出现的次数。我生成了一个 300x16 值的随机矩阵,将值的每一位与概率进行比较并将其分配给 1 和 0。这类似于加权硬币方法。
然而,我收到的分布几乎是均匀的。
gengen = [30, 28, 30, 30, 30, 26, 28, 28, 29, 23, 17, 8, 10, 12, 7, 6]
len = 16; % string length
% probability for 1 in each bit
prob_gengen = gengen./30;
% generate 100 random strings
moreStrings = rand(300,len);
samplemore = []
for i = 1:300
for k = 1:16
disp(i)
disp(k)
if (prob_gengen(k) > moreStrings(i,k))
samplemore(i,k) = 1;
else
samplemore(i,k) = 0;
end
end
end
G = reshape(samplemore,[16,300])
这段代码绘制了最终分布:
colormap('default')
subplot(3,1,1)
bar(sum(G,2)); % summing along rows using DIM = 2
xlabel('Frequency Bin ');
title('Generator (16b) Generated');
如何才能得到类似于第一个条形图的分布?代码本身在 MATLAB 中,但我认为 Python 实现也可以。
我认为错误的主要原因是您为获得 G
所做的重塑步骤。如果您想将数据从 300×16 矩阵重组为 16×300 矩阵,您应该 transpose it. Using reshape
分解旧的 300 元素列并将它们分散到新的 16 元素列中.
但是,您可以使用 bsxfun
:
而无需循环来完成所有这些操作
gengen = [30, 28, 30, 30, 30, 26, 28, 28, 29, 23, 17, 8, 10, 12, 7, 6];
len = 16;
prob_gengen = gengen./30;
binvecs = bsxfun(@le, rand(300, len), prob_gengen);
bar(sum(binvecs, 1));
这是条形图,看起来很像上面的第一个条形图:
它是如何工作的...
首先,您使用 rand
. Next, you'll want to check the random values in each column against the probability in the prob_gengen
vector. For example, the 16th column has a probability of 0.2, which means (on average) you want one fifth of the values in that column to be 1 and four fifths to be zero. You can do this by simply checking if the randomly-generated value is less than or equal to 这个概率阈值创建一组 300×16 的均匀生成的随机值,这些随机值介于 0 和 1 之间。使用 bsxfun
根据需要扩展向量 prob_gengen
以对所有行进行比较。
我生成了一个条形图,用于计算 16 位二进制字符串的每一位中 1 的数量:
我想生成大致遵循上述分布的 300 个 16 位二进制向量。
最初,我的代码依赖于概率数组 gengen
,它计算每个位中 1 出现的次数。我生成了一个 300x16 值的随机矩阵,将值的每一位与概率进行比较并将其分配给 1 和 0。这类似于加权硬币方法。
然而,我收到的分布几乎是均匀的。
gengen = [30, 28, 30, 30, 30, 26, 28, 28, 29, 23, 17, 8, 10, 12, 7, 6]
len = 16; % string length
% probability for 1 in each bit
prob_gengen = gengen./30;
% generate 100 random strings
moreStrings = rand(300,len);
samplemore = []
for i = 1:300
for k = 1:16
disp(i)
disp(k)
if (prob_gengen(k) > moreStrings(i,k))
samplemore(i,k) = 1;
else
samplemore(i,k) = 0;
end
end
end
G = reshape(samplemore,[16,300])
这段代码绘制了最终分布:
colormap('default')
subplot(3,1,1)
bar(sum(G,2)); % summing along rows using DIM = 2
xlabel('Frequency Bin ');
title('Generator (16b) Generated');
如何才能得到类似于第一个条形图的分布?代码本身在 MATLAB 中,但我认为 Python 实现也可以。
我认为错误的主要原因是您为获得 G
所做的重塑步骤。如果您想将数据从 300×16 矩阵重组为 16×300 矩阵,您应该 transpose it. Using reshape
分解旧的 300 元素列并将它们分散到新的 16 元素列中.
但是,您可以使用 bsxfun
:
gengen = [30, 28, 30, 30, 30, 26, 28, 28, 29, 23, 17, 8, 10, 12, 7, 6];
len = 16;
prob_gengen = gengen./30;
binvecs = bsxfun(@le, rand(300, len), prob_gengen);
bar(sum(binvecs, 1));
这是条形图,看起来很像上面的第一个条形图:
它是如何工作的...
首先,您使用 rand
. Next, you'll want to check the random values in each column against the probability in the prob_gengen
vector. For example, the 16th column has a probability of 0.2, which means (on average) you want one fifth of the values in that column to be 1 and four fifths to be zero. You can do this by simply checking if the randomly-generated value is less than or equal to 这个概率阈值创建一组 300×16 的均匀生成的随机值,这些随机值介于 0 和 1 之间。使用 bsxfun
根据需要扩展向量 prob_gengen
以对所有行进行比较。