LAMMP 4.1.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
multinomial.c 文件参考
+ multinomial.c 的引用(Include)关系图:

浏览源代码.

宏定义

#define MULTINOMIAL_INT_LIMIT   (0xffffffff)
 
#define MULTINOMIAL_SHORT_LIMIT   (0xffff)
 

函数

static uint count_factors (fac_ptr fac, uint nfactors, uint n, const uintp r, uint m, uint p)
 
static uint factor_size_int (mp_size_t rn, uint n)
 
static uint factor_size_short (mp_size_t rn)
 
mp_size_t lmmp_multinomial_ (mp_ptr restrict dst, mp_size_t rn, uint n, const uintp restrict r, uint m)
 
mp_size_t lmmp_multinomial_size_ (const uintp r, uint m, ulong *restrict n)
 
static mp_size_t lmmp_odd_multinomial_uint_ (mp_ptr restrict dst, mp_size_t rn, uint n, const uintp restrict r, uint m)
 
static mp_size_t lmmp_odd_multinomial_ushort_ (mp_ptr restrict dst, mp_size_t rn, uint n, const uintp restrict r, uint m)
 

宏定义说明

◆ MULTINOMIAL_INT_LIMIT

#define MULTINOMIAL_INT_LIMIT   (0xffffffff)

在文件 multinomial.c121 行定义.

◆ MULTINOMIAL_SHORT_LIMIT

#define MULTINOMIAL_SHORT_LIMIT   (0xffff)

在文件 multinomial.c120 行定义.

函数说明

◆ count_factors()

static uint count_factors ( fac_ptr  fac,
uint  nfactors,
uint  n,
const uintp  r,
uint  m,
uint  p 
)
inlinestatic

在文件 multinomial.c28 行定义.

28 {
29 uint pn = n;
30 uint e = 0;
31 ulong inv = MP_ULONG_MAX / p + 1;
32 while (pn > 0) {
33 _udiv32by32_q_preinv(pn, pn, inv);
34 e += pn;
35 }
36 for (uint i = 0; i < m; ++i) {
37 uint pn = r[i];
38 while (pn > 0) {
39 _udiv32by32_q_preinv(pn, pn, inv);
40 e -= pn;
41 }
42 }
43 if (e > 0) {
44 fac[nfactors].f = p;
45 fac[nfactors++].j = e;
46 }
47 return nfactors;
48}
uint f
Definition ele_mul.h:118
uint j
Definition ele_mul.h:119
#define _udiv32by32_q_preinv(q, n0, dinv)
Definition longlong.h:466
#define MP_ULONG_MAX
Definition mparam.h:140
uint32_t uint
Definition numth.h:35
uint64_t ulong
Definition numth.h:36

引用了 _udiv32by32_q_preinv, fac_t::f, fac_t::j , 以及 MP_ULONG_MAX.

被这些函数引用 lmmp_odd_multinomial_uint_() , 以及 lmmp_odd_multinomial_ushort_().

+ 这是这个函数的调用关系图:

◆ factor_size_int()

static uint factor_size_int ( mp_size_t  rn,
uint  n 
)
inlinestatic

在文件 multinomial.c50 行定义.

50 {
51 /*
52 使用类似组合数的思路来估计缓冲区大小。
53 */
54 uint approx1 = rn * 8;
55 uint approx2 = lmmp_prime_size_(n);
56 return approx1 < approx2 ? approx1 : approx2;
57}
ulong lmmp_prime_size_(ulong n)
估计 n 范围内的素数数量
Definition prime_table.c:11

引用了 lmmp_prime_size_().

被这些函数引用 lmmp_odd_multinomial_uint_().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ factor_size_short()

static uint factor_size_short ( mp_size_t  rn)
inlinestatic

在文件 multinomial.c59 行定义.

59 {
60 return rn * 10;
61}

被这些函数引用 lmmp_odd_multinomial_ushort_().

+ 这是这个函数的调用关系图:

◆ lmmp_multinomial_()

mp_size_t lmmp_multinomial_ ( mp_ptr restrict  dst,
mp_size_t  rn,
uint  n,
const uintp restrict  r,
uint  m 
)

在文件 multinomial.c123 行定义.

123 {
124 mp_size_t shl = n - lmmp_limb_popcnt_(n);
125 for (uint j = 0; j < m; ++j) {
126 shl += lmmp_limb_popcnt_(r[j]);
127 shl -= r[j];
128 }
129 mp_size_t shw = shl / LIMB_BITS;
130 shl %= LIMB_BITS;
131 lmmp_zero(dst, shw);
132 if (n <= MULTINOMIAL_SHORT_LIMIT) {
133 rn = lmmp_odd_multinomial_ushort_(dst + shw, rn - shw, n, r, m);
134 } else {
135 rn = lmmp_odd_multinomial_uint_(dst + shw, rn - shw, n, r, m);
136 }
137
138 if (shl > 0) {
139 dst[shw + rn] = lmmp_shl_(dst + shw, dst + shw, rn, shl);
140 rn += shw + 1;
141 rn -= dst[rn - 1] == 0 ? 1 : 0;
142 } else {
143 rn += shw;
144 }
145 return rn;
146}
#define lmmp_zero(dst, n)
Definition lmmp.h:366
uint64_t mp_size_t
Definition lmmp.h:212
#define LIMB_BITS
Definition lmmp.h:221
mp_limb_t lmmp_shl_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_size_t shl)
大数左移操作 [dst,na] = [numa,na]<<shl,dst的低shl位填充0
Definition shl.c:9
int lmmp_limb_popcnt_(mp_limb_t x)
计算一个64位无符号整数中1的个数
Definition tiny.c:20
static mp_size_t lmmp_odd_multinomial_ushort_(mp_ptr restrict dst, mp_size_t rn, uint n, const uintp restrict r, uint m)
Definition multinomial.c:63
#define MULTINOMIAL_SHORT_LIMIT
static mp_size_t lmmp_odd_multinomial_uint_(mp_ptr restrict dst, mp_size_t rn, uint n, const uintp restrict r, uint m)
Definition multinomial.c:97

引用了 LIMB_BITS, lmmp_limb_popcnt_(), lmmp_odd_multinomial_uint_(), lmmp_odd_multinomial_ushort_(), lmmp_shl_(), lmmp_zero , 以及 MULTINOMIAL_SHORT_LIMIT.

+ 函数调用图:

◆ lmmp_multinomial_size_()

mp_size_t lmmp_multinomial_size_ ( const uintp  r,
uint  m,
ulong *restrict  n 
)

在文件 multinomial.c12 行定义.

12 {
13 *n = 0;
14 uint i = 0;
15 for (; i < m; ++i) *n += r[i];
16
17 double logr = lgamma(*n + 1.0);
18
19 for (i = 0; i < m; ++i)
20 logr -= lgamma(r[i] + 1.0);
21
22 logr /= LOG2_;
23
24 mp_size_t rn = ceil(logr / LIMB_BITS) + 2;
25 return rn;
26}
#define LOG2_
Definition mparam.h:165

引用了 LIMB_BITS , 以及 LOG2_.

◆ lmmp_odd_multinomial_uint_()

static mp_size_t lmmp_odd_multinomial_uint_ ( mp_ptr restrict  dst,
mp_size_t  rn,
uint  n,
const uintp restrict  r,
uint  m 
)
static

在文件 multinomial.c97 行定义.

97 {
100 uint nfactors = factor_size_int(rn, n);
101 fac_ptr restrict fac = BALLOC_TYPE(nfactors, fac_t);
102
103 nfactors = 0;
104 prime_cache_t cache;
105 lmmp_prime_cache_init_(&cache, n);
106 while (cache.is_end == 0) {
108 for (uint i = 0; i < cache.size; ++i) {
109 nfactors = count_factors(fac, nfactors, n, r, m, cache.pp[i]);
110 }
111 }
113
114 rn = lmmp_factors_mul_(dst, rn, fac, nfactors);
115
117 return rn;
118}
mp_size_t lmmp_factors_mul_(mp_ptr dst, mp_size_t rn, fac_ptr fac, uint nfactors)
计算因子的累乘,并将结果放入dst中
static uint factor_size_int(mp_size_t rn, uint n)
Definition multinomial.c:50
static uint count_factors(fac_ptr fac, uint nfactors, uint n, const uintp r, uint m, uint p)
Definition multinomial.c:28
void lmmp_prime_cache_free_(prime_cache_t *cache)
释放素数表缓存
void lmmp_prime_cache_next_(prime_cache_t *cache)
素数表缓存更新(从小到大遍历全局质数表)
void lmmp_prime_int_table_init_(uint n)
初始化全局素数表
Definition prime_table.c:70
void lmmp_prime_cache_init_(prime_cache_t *cache, uint n)
初始化素数表缓存
#define TEMP_B_DECL
Definition tmp_alloc.h:75
#define BALLOC_TYPE(n, type)
Definition tmp_alloc.h:89
#define TEMP_B_FREE
Definition tmp_alloc.h:100

引用了 BALLOC_TYPE, count_factors(), factor_size_int(), prime_cache_t::is_end, lmmp_factors_mul_(), lmmp_prime_cache_free_(), lmmp_prime_cache_init_(), lmmp_prime_cache_next_(), lmmp_prime_int_table_init_(), prime_cache_t::pp, prime_cache_t::size, TEMP_B_DECL , 以及 TEMP_B_FREE.

被这些函数引用 lmmp_multinomial_().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ lmmp_odd_multinomial_ushort_()

static mp_size_t lmmp_odd_multinomial_ushort_ ( mp_ptr restrict  dst,
mp_size_t  rn,
uint  n,
const uintp restrict  r,
uint  m 
)
static

在文件 multinomial.c63 行定义.

69 {
70 if (n < ODD_FACTORIAL_SIZE) {
71 lmmp_odd_nPr_ushort_(dst, rn, n, n);
72 mp_limb_t t = 0;
73 for (uint i = 0; i < m; ++i) {
74 lmmp_odd_nPr_ushort_(&t, 1, r[i], r[i]);
75 dst[0] /= t;
76 }
77 return 1;
78 } else {
80 uint primen = lmmp_prime_cnt16_(n);
81 uint nfactors = factor_size_short(rn);
82 nfactors = primen < nfactors ? primen : nfactors;
83 fac_ptr restrict fac = TALLOC_TYPE(nfactors, fac_t);
84 nfactors = 0;
85 for (uint i = 1; i < primen; ++i) {
87 nfactors = count_factors(fac, nfactors, n, r, m, p);
88 }
89
90 rn = lmmp_factors_mul_(dst, rn, fac, nfactors);
91
93 return rn;
94 }
95}
uint64_t mp_limb_t
Definition lmmp.h:211
#define ODD_FACTORIAL_SIZE
Definition mparam.h:152
static uint factor_size_short(mp_size_t rn)
Definition multinomial.c:59
mp_size_t lmmp_odd_nPr_ushort_(mp_ptr dst, mp_size_t rn, ulong n, ulong r)
计算 nPr 排列数的奇数部分
const ushort prime_short_table[6542]
ushort lmmp_prime_cnt16_(ushort n)
计算小于等于 n 的素数数量
#define TEMP_DECL
Definition tmp_alloc.h:72
#define TEMP_FREE
Definition tmp_alloc.h:93
#define TALLOC_TYPE(n, type)
Definition tmp_alloc.h:91

引用了 count_factors(), factor_size_short(), lmmp_factors_mul_(), lmmp_odd_nPr_ushort_(), lmmp_prime_cnt16_(), ODD_FACTORIAL_SIZE, prime_short_table, TALLOC_TYPE, TEMP_DECL , 以及 TEMP_FREE.

被这些函数引用 lmmp_multinomial_().

+ 函数调用图:
+ 这是这个函数的调用关系图: