LAMMP 4.2.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
ele_mul.c
浏览该文件的文档.
1/**
2 * Copyright (C) 2026 HJimmyK(Jericho Knox)
3 *
4 * This file is part of LAMMP.
5 *
6 * LAMMP is free software: you can redistribute it and/or modify it under
7 * the terms of the GNU Lesser General Public License (LGPL) as published
8 * by the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed WITHOUT ANY WARRANTY.
12 *
13 * See <https://www.gnu.org/licenses/>.
14 */
15
16#include "../../../include/lammp/impl/ele_mul.h"
17#include "../../../include/lammp/impl/mparam.h"
18
19#define INSERTION_SORT_THRESHOLD 16
20
21static inline void swap_huff_node(huff_node* a, huff_node* b) {
22 mp_srcptr tp = a->np;
23 mp_size_t tn = a->nn;
24 a->np = b->np;
25 a->nn = b->nn;
26 b->np = tp;
27 b->nn = tn;
28}
29
30/**
31 * @brief 在闭区间 [low, high] 上进行插入排序
32 */
34 for (sint i = low + 1; i <= high; ++i) {
35 mp_srcptr np = arr[i].np;
36 mp_size_t nn = arr[i].nn;
37 sint j = i - 1;
38 while (j >= low && arr[j].nn > nn) {
39 arr[j + 1].np = arr[j].np;
40 arr[j + 1].nn = arr[j].nn;
41 --j;
42 }
43 arr[j + 1].np = np;
44 arr[j + 1].nn = nn;
45 }
46}
47
48/**
49 * @brief 返回 arr[a]、arr[b]、arr[c] 三个索引中对应值的中位数的索引
50 */
51static inline sint median_of_three(const huff_node arr[], sint a, sint b, sint c) {
52 mp_size_t va = arr[a].nn, vb = arr[b].nn, vc = arr[c].nn;
53 if (va < vb) {
54 if (vb < vc)
55 return b;
56 else if (va < vc)
57 return c;
58 else
59 return a;
60 } else {
61 if (va < vc)
62 return a;
63 else if (vb < vc)
64 return c;
65 else
66 return b;
67 }
68}
69
70/**
71 * @brief 递归的三路快速排序,对闭区间 [low, high] 排序
72 */
74 if (high - low + 1 <= INSERTION_SORT_THRESHOLD) {
76 return;
77 }
78
79 sint mid = low + (high - low) / 2;
81 if (pivot_index != low) {
83 }
84 mp_size_t pivot = arr[low].nn;
85
86 sint lt = low; // 小于区域的右边界(开)
87 sint gt = high; // 大于区域的左边界(开)
88 sint i = low + 1;
89
90 while (i <= gt) {
91 if (arr[i].nn < pivot) {
93 ++lt;
94 ++i;
95 } else if (arr[i].nn > pivot) {
97 --gt;
98 } else {
99 ++i;
100 }
101 }
102
103 quicksort_rec(arr, low, lt - 1);
104 quicksort_rec(arr, gt + 1, high);
105}
106
109 lmmp_param_assert(ht->root != NULL && ht->size > 0);
110 sint n = ht->size;
111 huff_node* arr = ht->root;
112
113 if (n == 1) {
114 return 0;
115 }
116
117 quicksort_rec(arr, 0, n - 1);
118
119 sint i = 0, j = n, k = n;
120
121 while (k < (2 * n - 1)) {
122 sint idx1, idx2;
123
124 if (i < n && (j >= k || arr[i].nn <= arr[j].nn)) {
125 idx1 = i++;
126 } else {
127 idx1 = j++;
128 }
129
130 if (i < n && (j >= k || arr[i].nn <= arr[j].nn)) {
131 idx2 = i++;
132 } else {
133 idx2 = j++;
134 }
135 // 非叶子节点的np不会被访问,此赋值不会影响结果
136 //arr[k].np = NULL;
137 arr[k].nn = arr[idx1].nn + arr[idx2].nn;
138 arr[k].left = idx1;
139 arr[k].right = idx2;
140 k++;
141 }
142
143 return 2 * n - 2;
144}
145
147 if (ht->root[ridx].left == -1) {
148 lmmp_copy(dst, ht->root[ridx].np, ht->root[ridx].nn);
149 return ht->root[ridx].nn;
150 } else {
151 sint idx = ht->root[ridx].left;
152 mp_size_t halfn = ht->root[idx].nn; // 左子树的limb缓冲区长度
153 mp_size_t n1 = lmmp_huff_tree_mul_(ht, ht->root[ridx].left, tp, dst);
154 mp_size_t n2 = lmmp_huff_tree_mul_(ht, ht->root[ridx].right, tp + halfn, dst + halfn);
155 if (n1 > n2)
156 lmmp_mul_(dst, tp, n1, tp + halfn, n2);
157 else
158 lmmp_mul_(dst, tp + halfn, n2, tp, n1);
159 n1 += n2;
160 n1 -= dst[n1 - 1] == 0 ? 1 : 0;
161 return n1;
162 }
163}
164
167 lmmp_debug_assert(n > 0);
168 dst[0] = limbs[0];
169 mp_size_t rn = 1;
170 for (mp_size_t i = 1; i < n; i++) {
171 dst[rn] = lmmp_mul_1_(dst, dst, rn, limbs[i]);
172 rn++;
173 rn -= dst[rn - 1] == 0 ? 1 : 0;
174 }
175 return rn;
176 }
177 mp_size_t halfn = n / 2;
180 if (n1 > n2)
181 lmmp_mul_(dst, tp, n1, tp + halfn, n2);
182 else
183 lmmp_mul_(dst, tp + halfn, n2, tp, n1);
184 n = n1 + n2;
185 n -= dst[n - 1] == 0 ? 1 : 0;
186 return n;
187}
#define k
#define c
#define INSERTION_SORT_THRESHOLD
Copyright (C) 2026 HJimmyK(Jericho Knox)
Definition ele_mul.c:19
mp_size_t lmmp_huff_tree_mul_(huff_tree *restrict ht, sint ridx, mp_ptr restrict dst, mp_ptr restrict tp)
Definition ele_mul.c:146
sint lmmp_huff_tree_build_(huff_tree *restrict ht)
Definition ele_mul.c:107
static void insertion_sort(huff_node arr[], sint low, sint high)
在闭区间 [low, high] 上进行插入排序
Definition ele_mul.c:33
static void quicksort_rec(huff_node arr[], sint low, sint high)
递归的三路快速排序,对闭区间 [low, high] 排序
Definition ele_mul.c:73
static sint median_of_three(const huff_node arr[], sint a, sint b, sint c)
返回 arr[a]、arr[b]、arr[c] 三个索引中对应值的中位数的索引
Definition ele_mul.c:51
mp_size_t lmmp_elem_mul_ulong_(mp_ptr restrict dst, const ulongp restrict limbs, mp_size_t n, mp_ptr restrict tp)
Definition ele_mul.c:165
static void swap_huff_node(huff_node *a, huff_node *b)
Definition ele_mul.c:21
Copyright (C) 2026 HJimmyK(Jericho Knox)
Definition ele_mul.h:24
mp_limb_t * mp_ptr
Definition lmmp.h:80
#define lmmp_copy(dst, src, n)
Definition lmmp.h:367
uint64_t mp_size_t
Definition lmmp.h:77
#define lmmp_debug_assert(x)
Definition lmmp.h:390
const mp_limb_t * mp_srcptr
Definition lmmp.h:81
#define lmmp_param_assert(x)
Definition lmmp.h:401
void lmmp_mul_(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_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 ELEM_MUL_BASECASE_THRESHOLD
Definition mparam.h:118
#define tp
#define n
uint64_t * ulongp
Definition numth.h:41
int32_t sint
Definition numth.h:33