在 Python 中创建数字食谱随机数生成器
Creating Numerical Recipes random number generator in Python
我想从 U[0,1] 分布生成随机数。我正在尝试重新创建 Numerical Recipes 第 7.1 章中的随机数生成器。不幸的是,我的 C++ 不是特别强大,所以我在遵循代码时遇到了一些问题!我想知道是否有人可以帮助澄清我对这里发生的事情的理解。在 C++ 中,代码提供为:
struct Ran {
Ullong u, v, w;
Ran(Ullong j) : v(4101842887655102017LL), w(1) {
u = j ^ v; int64();
v = u; int64();
w = v; int64();
}
inline Ullong int64() {
u = u * 2862933555777941757LL + 7046029254386353087LL;
v ^= v >> 17; v ^= v << 31; v ^= v >> 8;
w = 4294957665U*(w & 0xffffffff) + (w >> 32);
Ullong x = u ^ (u << 21); x ^= x >> 35; x ^= x << 4;
return (x + v) ^ w;
}
inline Doub doub() { return 5.42101086242752217E-20 * int64(); }
inline Uint int32() { return (Uint)int64(); }
};
我的理解是这样的:
Ran(Ullong j) : v(4101842887655102017LL), w(1) {
u = j ^ v; int64();
v = u; int64();
w = v; int64();
}
这是我们的初始化。 j
这是我们的种子。 v
被设置为一个非常大的素数。 ^
是按位 XOR 运算符,因此当我们洗牌 u
、v
和 w
.
时,这提供了我们的第一级随机性
除此之外,我开始感到困惑。
inline Ullong int64() {
u = u * 2862933555777941757LL + 7046029254386353087LL;
v ^= v >> 17; v ^= v << 31; v ^= v >> 8;
w = 4294957665U*(w & 0xffffffff) + (w >> 32);
Ullong x = u ^ (u << 21); x ^= x >> 35; x ^= x << 4;
return (x + v) ^ w;
}
具体是什么我不明白
v ^= v >> 17;
确实如此。我认为它是将 v
向右移动 17 位,然后对原始 v
执行异或运算,然后将此输出保存为 v
.
我也不明白
w = 4294957665U*(w & 0xffffffff) + (w >> 32);
完全没有。快速搜索 here 说 0xffffffff
要么是 -1 要么是一个大数字,但我仍然不太明白这一行在做什么(除了一些按位操作)。
最后,我相信这一行:
inline Doub doub() { return 5.42101086242752217E-20 * int64(); }
正在返回 0 到 1 之间的随机数。
如果有人能纠正、澄清或确认我在这里的内容,我将不胜感激。
感谢 Scheff 的猫,所有超级有用的答案。我已经搞定了一些似乎在 Python 中有效的东西,但我也采纳了你的建议,暂时对我的随机数生成稍微不那么冒险了。
我想从 U[0,1] 分布生成随机数。我正在尝试重新创建 Numerical Recipes 第 7.1 章中的随机数生成器。不幸的是,我的 C++ 不是特别强大,所以我在遵循代码时遇到了一些问题!我想知道是否有人可以帮助澄清我对这里发生的事情的理解。在 C++ 中,代码提供为:
struct Ran {
Ullong u, v, w;
Ran(Ullong j) : v(4101842887655102017LL), w(1) {
u = j ^ v; int64();
v = u; int64();
w = v; int64();
}
inline Ullong int64() {
u = u * 2862933555777941757LL + 7046029254386353087LL;
v ^= v >> 17; v ^= v << 31; v ^= v >> 8;
w = 4294957665U*(w & 0xffffffff) + (w >> 32);
Ullong x = u ^ (u << 21); x ^= x >> 35; x ^= x << 4;
return (x + v) ^ w;
}
inline Doub doub() { return 5.42101086242752217E-20 * int64(); }
inline Uint int32() { return (Uint)int64(); }
};
我的理解是这样的:
Ran(Ullong j) : v(4101842887655102017LL), w(1) {
u = j ^ v; int64();
v = u; int64();
w = v; int64();
}
这是我们的初始化。 j
这是我们的种子。 v
被设置为一个非常大的素数。 ^
是按位 XOR 运算符,因此当我们洗牌 u
、v
和 w
.
除此之外,我开始感到困惑。
inline Ullong int64() {
u = u * 2862933555777941757LL + 7046029254386353087LL;
v ^= v >> 17; v ^= v << 31; v ^= v >> 8;
w = 4294957665U*(w & 0xffffffff) + (w >> 32);
Ullong x = u ^ (u << 21); x ^= x >> 35; x ^= x << 4;
return (x + v) ^ w;
}
具体是什么我不明白
v ^= v >> 17;
确实如此。我认为它是将 v
向右移动 17 位,然后对原始 v
执行异或运算,然后将此输出保存为 v
.
我也不明白
w = 4294957665U*(w & 0xffffffff) + (w >> 32);
完全没有。快速搜索 here 说 0xffffffff
要么是 -1 要么是一个大数字,但我仍然不太明白这一行在做什么(除了一些按位操作)。
最后,我相信这一行:
inline Doub doub() { return 5.42101086242752217E-20 * int64(); }
正在返回 0 到 1 之间的随机数。
如果有人能纠正、澄清或确认我在这里的内容,我将不胜感激。
感谢 Scheff 的猫,所有超级有用的答案。我已经搞定了一些似乎在 Python 中有效的东西,但我也采纳了你的建议,暂时对我的随机数生成稍微不那么冒险了。