7#include "../../../include/lammp/impl/ele_mul.h"
8#include "../../../include/lammp/impl/mparam.h"
9#include "../../../include/lammp/impl/prime_table.h"
10#include "../../../include/lammp/impl/longlong.h"
11#include "../../../include/lammp/numth.h"
14 double ln_comb = lgamma(n + 1.0) - lgamma(r + 1.0) - lgamma(n - r + 1.0);
15 double log2_comb = ln_comb /
LOG2_;
34 uint approx1 = rn * 8;
36 return approx1 < approx2? approx1 : approx2;
67 fac[nfactors++].
j = e;
89 rn -= dst[rn - 1] == 0 ? 1 : 0;
92 if (r <= 4 || n > 0xfff) {
97 for (
ulong i = 1; i <= r; ++i) {
102 rn -= dst[rn - 1] == 0 ? 1 : 0;
105 rn -= dst[rn - 1] == 0 ? 1 : 0;
112 ulong t = 1, d = 1, v;
114 for (; i <= (
ulong)r - 4; i += 4) {
116 d = i * (i + 1) * (i + 2) * (i + 3);
118 t = (n - i + 1) * (n - i) * (n - i - 1) * (n - i - 2);
123 rn -= dst[rn - 1] == 0 ? 1 : 0;
126 rn -= dst[rn - 1] == 0 ? 1 : 0;
128 for (; i <= r; ++i) {
133 rn -= dst[rn - 1] == 0 ? 1 : 0;
136 rn -= dst[rn - 1] == 0 ? 1 : 0;
144 nfactors = primen < nfactors ? primen : nfactors;
148 for (
uint i = 1; i < primen; ++i) {
167 for (
ulong i = 1; i <= r; ++i) {
172 rn -= dst[rn - 1] == 0 ? 1 : 0;
175 rn -= dst[rn - 1] == 0 ? 1 : 0;
182 ulong t = 1, d = 1, v;
184 for (; i <= (
ulong)r - 2; i += 2) {
186 t = (n - i + 1) * (n - i);
190 rn -= dst[rn - 1] == 0 ? 1 : 0;
193 rn -= dst[rn - 1] == 0 ? 1 : 0;
195 for (; i <= r; ++i) {
200 rn -= dst[rn - 1] == 0 ? 1 : 0;
203 rn -= dst[rn - 1] == 0 ? 1 : 0;
216 while (cache.
is_end == 0) {
218 for (
uint i = 0; i < cache.
size; ++i) {
241 dst[shw + rn] =
lmmp_shl_(dst + shw, dst + shw, rn, bits);
243 rn -= dst[rn - 1] == 0;
mp_size_t lmmp_factors_mul_(mp_ptr dst, mp_size_t rn, fac_ptr fac, uint nfactors)
计算因子的累乘,并将结果放入dst中
#define lmmp_zero(dst, n)
#define lmmp_debug_assert(x)
#define lmmp_param_assert(x)
mp_limb_t lmmp_div_1_(mp_ptr dstq, mp_srcptr numa, mp_size_t na, mp_limb_t x)
单精度数除法
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
int lmmp_limb_popcnt_(mp_limb_t x)
计算一个64位无符号整数中1的个数
mp_limb_t lmmp_mul_1_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_limb_t x)
大数乘以单limb操作 [dst,na] = [numa,na] * x
#define ctz_shl(r, x, cnt)
#define _udiv32by32_q_preinv(q, n0, dinv)
#define BINOMIAL_RN_BASECASE_THRESHOLD
#define ODD_FACTORIAL_SIZE
mp_size_t lmmp_odd_nCr_ushort_(mp_ptr restrict dst, mp_size_t rn, uint n, uint r)
static uint factor_size_int(mp_size_t rn, uint n)
mp_size_t lmmp_nCr_size_(uint n, uint r, mp_bitcnt_t *restrict bits)
static uint factor_size_short(mp_size_t rn)
static uint count_factors(fac_ptr fac, uint nfactors, uint n, uint r, uint nr, uint p)
mp_size_t lmmp_nCr_(mp_ptr dst, mp_bitcnt_t bits, mp_size_t rn, uint n, uint r)
计算 nCr 组合数 ( nCr = n! / (r!(n-r)!) )
mp_size_t lmmp_odd_nCr_uint_(mp_ptr restrict dst, mp_size_t rn, uint n, uint r)
mp_size_t lmmp_odd_nPr_ushort_(mp_ptr dst, mp_size_t rn, ulong n, ulong r)
计算 nPr 排列数的奇数部分
void lmmp_prime_cache_free_(prime_cache_t *cache)
释放素数表缓存
ulong lmmp_prime_size_(ulong n)
估计 n 范围内的素数数量
void lmmp_prime_cache_next_(prime_cache_t *cache)
素数表缓存更新(从小到大遍历全局质数表)
const ushort prime_short_table[6542]
void lmmp_prime_int_table_init_(uint n)
初始化全局素数表
ushort lmmp_prime_cnt16_(ushort n)
计算小于等于 n 的素数数量
void lmmp_prime_cache_init_(prime_cache_t *cache, uint n)
初始化素数表缓存
#define TALLOC_TYPE(n, type)
#define BALLOC_TYPE(n, type)