LAMMP 4.1.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
mprand.h 文件参考
#include "lmmp.h"
+ mprand.h 的引用(Include)关系图:
+ 此图展示该文件直接或间接的被哪些文件引用了:

浏览源代码.

类型定义

typedef struct lmmp_strong_rng_t lmmp_strong_rng_t
 强随机数生成器结构体
 

函数

void lmmp_global_rng_init_ (int seed, int seed_type)
 初始化全局随机数生成器
 
mp_size_t lmmp_random_ (mp_ptr dst, mp_size_t n)
 生成随机大整数(0 - B^n-1 均匀分布)
 
mp_size_t lmmp_seed_random_ (mp_ptr dst, mp_size_t n, mp_limb_t seed, int seed_type)
 生成随机大整数(0 - B^n-1 均匀分布)
 
mp_size_t lmmp_strong_random_ (mp_ptr dst, mp_size_t n, lmmp_strong_rng_t *rng)
 生成n维度强随机数(0 - B^n-1 均匀分布)
 
void lmmp_strong_rng_extern_ (lmmp_strong_rng_t *rng, mp_size_t k)
 将rng内部状态拓展至k维度
 
void lmmp_strong_rng_free_ (lmmp_strong_rng_t *rng)
 销毁强随机数生成器
 
lmmp_strong_rng_tlmmp_strong_rng_init_ (mp_size_t k, int seed)
 创建k维度强随机数生成器
 

类型定义说明

◆ lmmp_strong_rng_t

强随机数生成器结构体

注解
内部状态为一个长度为 k 的limb数组,初始状态由种子决定,每生成一次,内部状态将会更新, 内部状态的每个维度都是一个64位无符号整数,且可以认为是独立的。故通常情况下,此生成器得到的 随机数拥有极好的k-维均匀性。对于每个独立的limb,为了提高生成速度,我们使用pcg64-le随机数发生器 虽然各个limb间算法相同,但初始化状态几乎完全不同。

在文件 mprand.h105 行定义.

函数说明

◆ lmmp_global_rng_init_()

void lmmp_global_rng_init_ ( int  seed,
int  seed_type 
)

初始化全局随机数生成器

参数
seed种子
seed_type随机数发生器类型(0:pcg64_128,1:xoshiro256++)
警告
seed_type 必须在0到1之间,如果不是,则使用 seed_type%2 作为seed_type, 如果全局种子已经初始化,则会更新全局种子,或更新发生器类型
注解
由于使用int类型作为种子,我们将会维护一个全局种子随机序列,丰富种子的随机性。

在文件 mprand.c20 行定义.

20 {
21 lmmp_global_rng.state = lmmp_seed_generator(seed + seed_type);
22 lmmp_global_rng.seed_type = seed_type % 2;
23}
static _Thread_local lmmp_global_rng_t lmmp_global_rng
Definition mprand.c:18
mp_limb_t state
Definition mprand.c:12
static mp_limb_t lmmp_seed_generator(mp_limb_t seed)
种子生成器
Definition rand_state.h:46

引用了 lmmp_global_rng, lmmp_seed_generator(), lmmp_global_rng_t::seed_type , 以及 lmmp_global_rng_t::state.

+ 函数调用图:

◆ lmmp_random_()

mp_size_t lmmp_random_ ( mp_ptr  dst,
mp_size_t  n 
)

生成随机大整数(0 - B^n-1 均匀分布)

参数
dst随机数存储位置
ndst的 limb 长度
警告
如果dst==NULL或n==0,则返回0,无其他操作。种子由 lmmp_global_rng_init() 设置,发生器类型由 lmmp_global_rng_init() 设置,如果没有进行全局初始化,则使用默认种子(默认等价设置全局种子为0, 并不代表全局种子为0)和默认发生器类型(默认为xoshiro256++),即未设置全局种子,行为等价于 执行了 lmmp_global_rng_init_(0, 1)
注解
每调用一次此函数,种子将会进行一次更新,以确保多次调用时的种子不同,但是只要每次调用的方式 和顺序相同,在同一个进程中,每次生成的随机数序列相同。
返回
随机数的 limb 长度(由于可能存在生成随机数为0的情况,所以返回值可能小于n,但不会大于n)

◆ lmmp_seed_random_()

mp_size_t lmmp_seed_random_ ( mp_ptr  dst,
mp_size_t  n,
mp_limb_t  seed,
int  seed_type 
)

生成随机大整数(0 - B^n-1 均匀分布)

参数
dst随机数存储位置
ndst的 limb 长度
seed种子(建议使用有效位数较多的随机数,以保证随机数质量)
seed_type随机数发生器类型(0:pcg64_128,1:xoshiro256++)
警告
seed_type 必须在0到1之间,如果不是,则使用 seed_type%2 作为seed_type
返回
随机数的 limb 长度(这是由于可能存在生成随机数为0的情况(虽然几乎不可能), 所以返回值可能小于n,但不会大于n)

◆ lmmp_strong_random_()

mp_size_t lmmp_strong_random_ ( mp_ptr  dst,
mp_size_t  n,
lmmp_strong_rng_t rng 
)

生成n维度强随机数(0 - B^n-1 均匀分布)

参数
dst随机数存储位置(长度为k个limb)
ndst的 limb 长度(n<=k)
rng强随机数生成器指针,每生成一次,内部状态将会更新
警告
rng!=NULL, dst!=NULL, 0<n<=k,
注解
rng为强随机数生成器指针,每调用一次此函数,内部状态将会更新,以进行重复生成长度相同的随机大整数序列 此方法生成的随机数序列具有极好的k-维均匀性,单个随机大整数间的各个limb都是几乎完全独立的序列。
返回
随机数的 limb 长度(由于可能存在生成随机数为0的情况,所以返回值可能小于n,但不会大于n)

◆ lmmp_strong_rng_extern_()

void lmmp_strong_rng_extern_ ( lmmp_strong_rng_t rng,
mp_size_t  k 
)

将rng内部状态拓展至k维度

参数
rng强随机数生成器指针
k随机数长度(单位:limb)
警告
rng!=NULL, k>0
注解
若k<=rng->stream.k,则不进行任何操作。否则,将rng内部状态拓展至k维度。

在文件 mprand.c87 行定义.

87 {
88 lmmp_param_assert(rng != NULL);
90 if (k <= rng->stream.k) return;
91 rng->stream.state = (mp_limb_t*)lmmp_realloc(rng->stream.state, k * sizeof(mp_limb_t));
92
93 mp_limb_t new_seed = lmmp_seed_generator(rng->stream.k);
94 new_seed = rotl(new_seed, 37) ^ lmmp_seed_generator(k);
95 pcg64_le_seq_init(&rng->stream, rng->stream.k, new_seed);
96 rng->stream.k = k;
97}
#define k
void * lmmp_realloc(void *ptr, size_t size)
内存重分配函数(调用lmmp_realloc_fn)
Definition memory.c:186
uint64_t mp_limb_t
Definition lmmp.h:211
#define lmmp_param_assert(x)
Definition lmmp.h:398
pcg64_le_seq_t stream
Definition mprand.c:71
static void pcg64_le_seq_init(pcg64_le_seq_t *rng, mp_size_t i, mp_limb_t seed)
Definition rand_state.h:138
mp_limb_t *restrict state
Definition rand_state.h:135
mp_size_t k
Definition rand_state.h:134
static mp_limb_t rotl(const mp_limb_t x, int k)
Definition rand_state.h:89

引用了 pcg64_le_seq_t::k, k, lmmp_param_assert, lmmp_realloc(), lmmp_seed_generator(), pcg64_le_seq_init(), rotl(), pcg64_le_seq_t::state , 以及 lmmp_strong_rng_t::stream.

+ 函数调用图:

◆ lmmp_strong_rng_free_()

void lmmp_strong_rng_free_ ( lmmp_strong_rng_t rng)

销毁强随机数生成器

参数
rng强随机数生成器指针

在文件 mprand.c99 行定义.

99 {
100 if (rng != NULL) {
101 if (rng->stream.state != NULL) {
102 lmmp_free(rng->stream.state);
103 }
104 lmmp_free(rng);
105 }
106}
void lmmp_free(void *ptr)
内存释放函数(调用lmmp_heap_free_fn)
Definition memory.c:204

引用了 lmmp_free(), pcg64_le_seq_t::state , 以及 lmmp_strong_rng_t::stream.

+ 函数调用图:

◆ lmmp_strong_rng_init_()

lmmp_strong_rng_t * lmmp_strong_rng_init_ ( mp_size_t  k,
int  seed 
)

创建k维度强随机数生成器

参数
k随机数长度(单位:limb)
seed种子
警告
k>0
注解
请注意,此操作是一个开销很大的操作,且会分配内存,在仅生成一次的情况下,甚至初始化时间会慢于生成 一个随机数的时间。
返回
强随机数生成器指针

在文件 mprand.c74 行定义.

74 {
76
78 rng->stream.k = k;
80
81 mp_limb_t new_seed = lmmp_seed_generator(seed);
82 new_seed = rotl(new_seed, 17) ^ lmmp_seed_generator(k);
83 pcg64_le_seq_init(&rng->stream, 0, new_seed);
84 return rng;
85}
void * lmmp_alloc(size_t size)
内存分配函数(调用lmmp_heap_alloc_fn)
Definition memory.c:166
#define ALLOC_TYPE(n, type)
Definition tmp_alloc.h:112

引用了 ALLOC_TYPE, pcg64_le_seq_t::k, k, lmmp_alloc(), lmmp_param_assert, lmmp_seed_generator(), pcg64_le_seq_init(), rotl(), pcg64_le_seq_t::state , 以及 lmmp_strong_rng_t::stream.

+ 函数调用图: