如何创建一个向量,其中非零元素的索引服从分布
How to create a vector where indices of non-zero elements follow a distribution
我需要编写一个程序,根据以下要求创建一个包含 K 个非零元素的大小为 N 的向量:
- 非零元素应该主要集中在向量的中间元素附近(在位置N/2)。
- 距中间元素(两侧)距离 D 或更远的元素应为零。
- 随着我们远离中间元素,元素非零的概率应该会降低。
下面是我想要完成的一个相当小的例子,其中 N = 40(中间元素为 20),K = 11 个非零元素,并且 D = 8。由于 D = 8,位置处的元素> 20 + 8 = 28 且位置 < 20 - 8 = 12 的元素应始终为零。在允许非零的区域(从 12 到 28 的位置),存在 K = 11 个非零元素。靠近位置 20 的非零元素越来越多,并且随着我们远离中间元素,它们变得越来越稀疏。
Position
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
Vector
0
0
0
0
0
0
0
0
0
0
0
0
1
0
1
1
0
1
1
1
1
1
0
1
1
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
我还没有编写任何代码,因为我什至不知道如何开始。我的一个想法是以某种方式使用二项式分布来生成随机索引并设置非零元素。然而,这种分布可以给出多次相同的索引,因此将产生少于 K 个非零元素。如果我使用循环生成新的随机数,直到找到未使用的索引,结果是否仍然遵循二项分布,以便更多的非零元素围绕中间元素?
将使用的编程语言并不那么重要,但我更喜欢 Matlab、Python、C++ 或 C,因为我更熟悉它们。
希望有人能指点一下and/or例子。
这是 numpy 中的现有功能(选择)
import numpy as np
from scipy import stats
N = 40
K = 11
你对你想要的分布的模糊描述是不够的,所以我将使用平均值为 N/2
和标准差为 sqrt(N/2)
的正态概率分布。
center = int(N / 2)
scale = np.sqrt(N / 2)
从概率密度函数为每个可能的索引(最多 N
)创建一个概率向量:
p = stats.norm(loc=center, scale=scale).pdf(np.arange(N))
确保总和为 1:
p /= np.sum(p)
初始化随机数生成器并在可能的索引上调用.choice()
,概率分布p
,设置replace
为False
:
rng = np.random.default_rng()
nz_indices = rng.choice(np.arange(N), size=K, p=p, replace=False)
>>> nz_indices
array([27, 20, 23, 19, 16, 24, 13, 25, 26, 22, 21])
我需要编写一个程序,根据以下要求创建一个包含 K 个非零元素的大小为 N 的向量:
- 非零元素应该主要集中在向量的中间元素附近(在位置N/2)。
- 距中间元素(两侧)距离 D 或更远的元素应为零。
- 随着我们远离中间元素,元素非零的概率应该会降低。
下面是我想要完成的一个相当小的例子,其中 N = 40(中间元素为 20),K = 11 个非零元素,并且 D = 8。由于 D = 8,位置处的元素> 20 + 8 = 28 且位置 < 20 - 8 = 12 的元素应始终为零。在允许非零的区域(从 12 到 28 的位置),存在 K = 11 个非零元素。靠近位置 20 的非零元素越来越多,并且随着我们远离中间元素,它们变得越来越稀疏。
Position | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Vector | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
我还没有编写任何代码,因为我什至不知道如何开始。我的一个想法是以某种方式使用二项式分布来生成随机索引并设置非零元素。然而,这种分布可以给出多次相同的索引,因此将产生少于 K 个非零元素。如果我使用循环生成新的随机数,直到找到未使用的索引,结果是否仍然遵循二项分布,以便更多的非零元素围绕中间元素?
将使用的编程语言并不那么重要,但我更喜欢 Matlab、Python、C++ 或 C,因为我更熟悉它们。
希望有人能指点一下and/or例子。
这是 numpy 中的现有功能(选择)
import numpy as np
from scipy import stats
N = 40
K = 11
你对你想要的分布的模糊描述是不够的,所以我将使用平均值为 N/2
和标准差为 sqrt(N/2)
的正态概率分布。
center = int(N / 2)
scale = np.sqrt(N / 2)
从概率密度函数为每个可能的索引(最多 N
)创建一个概率向量:
p = stats.norm(loc=center, scale=scale).pdf(np.arange(N))
确保总和为 1:
p /= np.sum(p)
初始化随机数生成器并在可能的索引上调用.choice()
,概率分布p
,设置replace
为False
:
rng = np.random.default_rng()
nz_indices = rng.choice(np.arange(N), size=K, p=p, replace=False)
>>> nz_indices
array([27, 20, 23, 19, 16, 24, 13, 25, 26, 22, 21])