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

浏览源代码.

宏定义

#define COPY(tp, src, n)
 
#define POP_THRESHOLD   5
 

函数

mp_size_t lmmp_limb_elem_mul_ (mp_ptr *dst, const mp_limb_t *restrict limb, mp_size_t n)
 
mp_ssize_t lmmp_slimb_elem_mul_ (mp_ptr *dst, const mp_slimb_t *restrict slimb, mp_size_t n)
 
mp_ssize_t lmmp_vec_elem_mul_ (mp_ptr *dst, const lmmp_vecn_t *vec)
 计算向量的累乘
 

宏定义说明

◆ COPY

#define COPY (   tp,
  src,
 
)
值:
lmmp_copy(tp, src, n)
uint64_t mp_limb_t
Definition lmmp.h:211
#define tp
#define ALLOC_TYPE(n, type)
Definition tmp_alloc.h:112

在文件 elem_mul.c12 行定义.

◆ POP_THRESHOLD

#define POP_THRESHOLD   5

在文件 elem_mul.c16 行定义.

函数说明

◆ lmmp_limb_elem_mul_()

mp_size_t lmmp_limb_elem_mul_ ( mp_ptr dst,
const mp_limb_t *restrict  limb,
mp_size_t  n 
)

在文件 elem_mul.c97 行定义.

97 {
98 lmmp_param_assert(dst != NULL && limb != NULL);
99 lmmp_param_assert(n > 0);
100 mp_ptr mp = ALLOC_TYPE(n, mp_limb_t);
102
103 n = lmmp_elem_mul_ulong_(mp, (const ulongp)limb, n, tp);
104 *dst = mp;
105 lmmp_free(tp);
106 return n;
107}
mp_size_t lmmp_elem_mul_ulong_(mp_ptr dst, const ulongp limbs, mp_size_t n, mp_ptr tp)
计算limbs数组的累乘积
mp_limb_t * mp_ptr
Definition lmmp.h:215
void lmmp_free(void *ptr)
内存释放函数(调用lmmp_heap_free_fn)
Definition memory.c:204
#define lmmp_param_assert(x)
Definition lmmp.h:398
uint64_t * ulongp
Definition numth.h:45

引用了 ALLOC_TYPE, lmmp_elem_mul_ulong_(), lmmp_free(), lmmp_param_assert , 以及 tp.

+ 函数调用图:

◆ lmmp_slimb_elem_mul_()

mp_ssize_t lmmp_slimb_elem_mul_ ( mp_ptr dst,
const mp_slimb_t *restrict  slimb,
mp_size_t  n 
)

在文件 elem_mul.c109 行定义.

109 {
110 lmmp_debug_assert(dst != NULL && slimb != NULL);
111 lmmp_debug_assert(n > 0);
112 TEMP_DECL;
113 ulongp limbs = TALLOC_TYPE(n, ulong);
114 bool sign = true;
115 for (mp_size_t i = 0; i < n; ++i) {
116 if (slimb[i] < 0) {
117 sign = !sign;
118 limbs[i] = -slimb[i];
119 } else {
120 limbs[i] = slimb[i];
121 }
122 }
123 mp_ptr mp = ALLOC_TYPE(n, mp_limb_t);
125
126 n = lmmp_elem_mul_ulong_(mp, limbs, n, tp);
127 *dst = mp;
128 TEMP_FREE;
129 return sign ? n : -n;
130}
uint64_t mp_size_t
Definition lmmp.h:212
#define lmmp_debug_assert(x)
Definition lmmp.h:387
uint64_t ulong
Definition numth.h:36
#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

引用了 ALLOC_TYPE, lmmp_debug_assert, lmmp_elem_mul_ulong_(), TALLOC_TYPE, TEMP_DECL, TEMP_FREE , 以及 tp.

+ 函数调用图:

◆ lmmp_vec_elem_mul_()

mp_ssize_t lmmp_vec_elem_mul_ ( mp_ptr dst,
const lmmp_vecn_t vec 
)

计算向量的累乘

参数
dst结果向量,将会被覆盖为累乘结果指针,将会自动分配内存
vec被累乘向量
警告
dst!=NULL, vec!=NULL, nonull(vec), vec->n>0
注解
当vec中存在语义0时,*dst将会被置为NULL,并返回0。其余情况,*dst会被置为结果指针,并返回实际长度。
返回
结果dst的实际长度(为负数表示此数为负数,绝对值表示实际长度)

在文件 elem_mul.c18 行定义.

18 {
19 lmmp_param_assert(dst != NULL && vec != NULL);
20 lmmp_param_assert(vec->n > 0);
21
22 num_heap heap;
23 lmmp_num_heap_init_(&heap, vec->n);
24
25 mp_size_t mpn = 1, len;
26 mp_ptr tp;
29 mp1[0] = 1;
30 bool imp = true; // true 表示当前mp1存储连乘结果
31
32 bool sign = true;
33 for (size_t i = 0; i < vec->n; ++i) {
34 if (vec->num[i] == NULL || vec->len[i] == 0) {
35 *dst = NULL;
36 return 0;
37 } else if (vec->len[i] < 0) {
38 sign = !sign;
39 }
40 len = LMMP_ABS(vec->len[i]);
41 if (len > VEC_ELEMMUL_MP_THRESHOLD || (len + mpn > VEC_ELEMMUL_MP_THRESHOLD)) {
42 COPY(tp, vec->num[i], len);
43 lmmp_num_heap_push_(&heap, tp, len);
44 } else {
45 if (imp) {
46 if (mpn >= len)
47 lmmp_mul_basecase_(mp2, mp1, mpn, vec->num[i], len);
48 else
49 lmmp_mul_basecase_(mp2, vec->num[i], len, mp1, mpn);
50 mpn += len;
51 mpn -= mp2[mpn - 1] == 0 ? 1 : 0;
52 imp = false;
53 } else {
54 if (mpn >= len)
55 lmmp_mul_basecase_(mp1, mp2, mpn, vec->num[i], len);
56 else
57 lmmp_mul_basecase_(mp1, vec->num[i], len, mp2, mpn);
58 mpn += len;
59 mpn -= mp1[mpn - 1] == 0 ? 1 : 0;
60 imp = true;
61 }
62 }
64 if (imp) {
65 lmmp_num_heap_push_(&heap, mp1, mpn);
67 mpn = 1;
68 mp1[0] = 1;
69 } else {
70 lmmp_num_heap_push_(&heap, mp2, mpn);
72 mpn = 1;
73 mp2[0] = 1;
74 }
75 }
76 }
77 if (imp) {
78 if (!(mpn == 1 && mp1[0] == 1))
79 lmmp_num_heap_push_(&heap, mp1, mpn);
80 else
81 lmmp_free(mp1);
82 lmmp_free(mp2);
83 } else {
84 if (!(mpn == 1 && mp2[0] == 1))
85 lmmp_num_heap_push_(&heap, mp2, mpn);
86 else
87 lmmp_free(mp2);
88 lmmp_free(mp1);
89 }
90
91 tp = lmmp_num_heap_mul_(&heap, &mpn);
93 *dst = tp;
94 return sign ? mpn : -mpn;
95}
void lmmp_num_heap_push_(num_heap *pq, mp_ptr elem, mp_size_t n)
入队
static void lmmp_num_heap_init_(num_heap *restrict pq, size_t capa)
初始化优先队列
Definition ele_mul.h:58
static void lmmp_num_heap_free_(num_heap *restrict pq)
释放优先队列
Definition ele_mul.h:72
mp_ptr lmmp_num_heap_mul_(num_heap *pq, mp_size_t *rn)
将队列中所有元素相乘
#define POP_THRESHOLD
Definition elem_mul.c:16
#define COPY(tp, src, n)
Definition elem_mul.c:12
#define LMMP_ABS(x)
Definition lmmp.h:346
void lmmp_mul_basecase_(mp_ptr dst, mp_srcptr numa, mp_size_t na, mp_srcptr numb, mp_size_t nb)
基础乘法运算 [dst,na+nb] = [numa,na] * [numb,nb]
mp_ptr * num
Definition matrix.h:81
size_t n
Definition matrix.h:83
mp_ssize_t * len
Definition matrix.h:82
#define VEC_ELEMMUL_MP_THRESHOLD
Definition mparam.h:95

引用了 ALLOC_TYPE, COPY, lmmp_svecn_t::len, LMMP_ABS, lmmp_free(), lmmp_mul_basecase_(), lmmp_num_heap_free_(), lmmp_num_heap_init_(), lmmp_num_heap_mul_(), lmmp_num_heap_push_(), lmmp_param_assert, lmmp_svecn_t::n, lmmp_svecn_t::num, POP_THRESHOLD, tp , 以及 VEC_ELEMMUL_MP_THRESHOLD.

+ 函数调用图: