LAMMP 4.1.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
matrix.h
浏览该文件的文档.
1/*
2 * [LAMMP]
3 * Copyright (C) [2025-2026] [HJimmyK(Jericho Knox)]
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
18
19#ifndef LAMMP_MATRIX_H
20#define LAMMP_MATRIX_H
21
22/*
23 一些约定:
24 mat表示矩阵,为matrix简称。umat表示unsigned matrix,u表示unsigned
25 smat表示signed matrix,s表示signed。由于我们只对有符号的进行计算,大部分场合
26 都使用signed matrix,所以我们用mat表示signed mat。数字字面量或者m,n表示行列数,
27 单数字字面量或者n表示为方阵的阶数。
28
29 vec表示向量,vector简称。uvec表示unsigned vector,u表示unsigned。
30 svec表示signed vector,s表示signed。由于我们只对有符号的进行计算,大部分场合
31 都使用signed vector,所以我们用vec表示signed vec。数字字面量或者n表示向量长度。
32 向量参与运算时默认为列向量,等价于矩阵的列。
33
34 我们使用有符号整数类型表示limb长度,符号表明这个数的正负性,指针存储的是绝对值。
35 同时需要注意的是,在此处,mp_ptr若为空和limb长度为0,这两个情况均称之为语义0,
36 计算行为等价为0。同时,需要注意的是,在无明确要求的情况下,我们不希望指针非空的
37 同时limb长度为0,因为这可能导致未定义行为。
38
39 矩阵或向量的各个元素的地址我们并不要求完全分离或相同,当sep或eqsep用于矩阵或向量时,
40 语义和意义与sep或eqsep的一般用法相同。sep表示mat和vec指针分离,eqsep表示mat和vec
41 指针分离或相同,elemsep表示mat或vec各元素指针分离,eqelemsep表示mat或vec各元素指针
42 分离或相同。sep和eqsep用于矩阵或向量时,通常分别隐含了elemsep和eqelemsep。
43
44 nonull()表示矩阵或向量中的各元素指针全部不为NULL
45
46*/
47
48#include "lmmp.h"
49
50#ifndef INLINE_
51#define INLINE_ static inline
52#endif
53
54#ifdef __cplusplus
55extern "C" {
56#endif
57
69
79
80typedef struct {
83 size_t n;
87
88/**
89 * @brief 计算向量的累乘
90 * @param dst 结果向量,将会被覆盖为累乘结果指针,将会自动分配内存
91 * @param vec 被累乘向量
92 * @warning dst!=NULL, vec!=NULL, nonull(vec), vec->n>0
93 * @note 当vec中存在语义0时,*dst将会被置为NULL,并返回0。其余情况,*dst会被置为结果指针,并返回实际长度。
94 * @return 结果dst的实际长度(为负数表示此数为负数,绝对值表示实际长度)
95 */
97
98/**
99 * @brief 计算limb向量的累乘
100 * @param dst 结果向量,将会被覆盖为累乘结果指针,将会自动分配内存
101 * @param limb 被累乘向量
102 * @warning dst!=NULL, limb!=NULL, n>0
103 * @note 当limb数组存在0值时,*dst将会被置为NULL,并返回0。其余情况,*dst会被置为结果指针,并返回实际长度。
104 * @return 结果dst的实际长度
105 */
107
108/**
109 * @brief 计算slimb向量的累乘
110 * @param dst 结果向量,将会被覆盖为累乘结果指针,将会自动分配内存
111 * @param slimb 被累乘向量
112 * @warning dst!=NULL, slimb!=NULL
113 * @note 当slimb数组存在0值时,*dst将会被置为NULL,并返回0。其余情况,*dst会被置为结果指针,并返回实际长度。
114 * @return 结果dst的实际长度(为负数表示此数为负数,绝对值表示实际长度)
115 */
117
118/**
119 * @brief 计算2x2矩阵和2x2矩阵的乘积需要分配的内存
120 * @param dst 结果矩阵,dst中的n将会被覆盖为对应位置需要的limb长度,此函数不分配内存。
121 * @param matA 矩阵A
122 * @param matB 矩阵B
123 * @param tn 输出参数,将会被覆盖为缓冲区需要的limb长度,正数
124 * @param maxa 如果被覆盖,即matA中最大的元素的limb长度+1,此参数只有当确认使用STRASSEN算法时才需要
125 * @warning dst!=NULL, [matA|matB]!=NULL, nonull([matA|matB]), sep(dst,[matA|matB]), tn!=NULL, maxa!=NULL
126 * @note 如果你可以确认一定不使用STRASSEN算法,则不需要maxa参数,其可以为NULL。
127 * @return 0表示选择basecase算法,1表示选择STRASSEN算法。
128 */
130 const lmmp_mat22_t* matA,
131 const lmmp_mat22_t* matB,
132 mp_size_t* tn,
133 mp_size_t* maxa);
134
135/**
136 * @brief 计算2x2矩阵和2x2矩阵的乘积
137 * @param dst 结果矩阵。
138 * @param matA 矩阵A
139 * @param matB 矩阵B
140 * @param tp 临时缓冲区,用于存储中间结果,需要分配2*tn个limb,若为NULL,则会自动分配。
141 * @param tn 缓冲区的limb长度
142 * @warning dst!=NULL, nonull(dst), [matA|matB]!=NULL, nonull([matA|matB]), sep(dst,[matA|matB]), tn>0
143 */
145 const lmmp_mat22_t* matA,
146 const lmmp_mat22_t* matB,
147 mp_ptr tp,
148 mp_size_t tn);
149
150/**
151 * @brief 计算2x2矩阵平方
152 * @param dst 结果矩阵。
153 * @param matA 矩阵A
154 * @param tp 临时缓冲区,用于存储中间结果,需要分配2*tn个limb,若为NULL,则会自动分配。
155 * @param tn 缓冲区的limb长度
156 * @param maxa matA中最大的元素的limb长度+1,建议由lmmp_mat22_mul_size_确定
157 * @warning dst!=NULL, nonull(dst), matA!=NULL, nonull(matA), sep(dst,matA), tn>0
158 */
160
161/**
162 * @brief 计算(稠密)2x2矩阵和(稠密)2x2矩阵的乘积(STRASSEN算法)
163 * @param dst 结果矩阵。
164 * @param matA 矩阵A
165 * @param matB 矩阵B
166 * @param tp 临时缓冲区,用于存储中间结果,需要分配7*(tn+1)个limb,若为NULL,则会自动分配。
167 * @param tn 缓冲区的limb长度
168 * @param maxa matA中最大的元素的limb长度+1,建议由lmmp_mat22_mul_size_确定
169 * @warning dst!=NULL, nonull(dst), [matA|matB]!=NULL, nonull([matA|matB]), sep(dst,[matA|matB]), tn>0
170 */
172 mp_ptr tp, mp_size_t tn, mp_size_t maxa);
173
174/**
175 * @brief 计算(稠密)2x2矩阵平方(STRASSEN算法)
176 * @param dst 结果矩阵。
177 * @param matA 矩阵A
178 * @param tp 临时缓冲区,用于存储中间结果,需要分配7*(tn+1)个limb,若为NULL,则会自动分配。
179 * @param tn 缓冲区的limb长度
180 * @warning dst!=NULL, nonull(dst), matA!=NULL, nonull(matA), sep(dst,matA), tn>0
181 */
183
184/**
185 * @brief 计算2x2矩阵和2x2矩阵的乘积
186 * @param dst 结果矩阵。
187 * @param matA 矩阵A
188 * @param matB 矩阵B
189 * @param choose 选择算法,0表示basecase算法,1表示STRASSEN算法
190 * @param tn 缓冲区的limb长度,建议由lmmp_mat22_mul_size_确定
191 * @param maxa matA中最大的元素的limb长度+1,建议由lmmp_mat22_mul_size_确定
192 * @warning dst!=NULL, nonull(dst), [matA|matB]!=NULL, nonull([matA|matB]), sep(dst,[matA|matB]), choose==[0|1]
193 */
194INLINE_ void
195lmmp_mat22_mul_(lmmp_mat22_t* dst, const lmmp_mat22_t* matA, const lmmp_mat22_t* matB, int choose, mp_size_t tn,
196 mp_size_t maxa) {
197 lmmp_param_assert(dst != NULL);
198 lmmp_param_assert(matA != NULL);
199 lmmp_param_assert(matB != NULL);
200 lmmp_param_assert(choose == 0 || choose == 1);
201 if (choose == 0) {
202 lmmp_mat22_mul_basecase_(dst, matA, matB, NULL, tn);
203 } else {
204 lmmp_mat22_mul_strassen_(dst, matA, matB, NULL, tn, maxa);
205 }
206}
207
208/**
209 * @brief 计算(稠密)2x2矩阵平方
210 * @param dst 结果矩阵。
211 * @param matA 矩阵A
212 * @param tn 缓冲区的limb长度,建议由lmmp_mat22_mul_size_确定
213 * @param choose 选择算法,0表示basecase算法,1表示STRASSEN算法
214 * @warning dst!=NULL, nonull(dst), matA!=NULL, nonull(matA), sep(dst,matA), tn>0
215 */
216INLINE_ void
217lmmp_mat22_sqr_(lmmp_mat22_t* dst, const lmmp_mat22_t* mat, int choose, mp_size_t tn) {
218 lmmp_param_assert(dst != NULL);
219 lmmp_param_assert(mat != NULL);
220 lmmp_param_assert(choose == 0 || choose == 1);
221 if (choose == 0) {
222 lmmp_mat22_sqr_basecase_(dst, mat, NULL, tn);
223 } else {
224 lmmp_mat22_sqr_strassen_(dst, mat, NULL, tn);
225 }
226}
227
228
229#ifdef __cplusplus
230}
231#endif
232
233#endif // LAMMP_MATRIX_H
mp_limb_t * mp_ptr
Definition lmmp.h:215
uint64_t mp_size_t
Definition lmmp.h:212
int64_t mp_slimb_t
Definition lmmp.h:213
int64_t mp_ssize_t
Definition lmmp.h:214
uint64_t mp_limb_t
Definition lmmp.h:211
#define LAMMP_API
Definition lmmp.h:64
#define lmmp_param_assert(x)
Definition lmmp.h:398
mp_ptr a01
Definition matrix.h:60
mp_ssize_t n10
Definition matrix.h:65
lmmp_mat21_t lmmp_svec2_t
Definition matrix.h:78
lmmp_mat21_t lmmp_vec2_t
Definition matrix.h:76
mp_ptr a11
Definition matrix.h:62
void lmmp_mat22_mul_strassen_(lmmp_mat22_t *dst, const lmmp_mat22_t *matA, const lmmp_mat22_t *matB, mp_ptr tp, mp_size_t tn, mp_size_t maxa)
计算(稠密)2x2矩阵和(稠密)2x2矩阵的乘积(STRASSEN算法)
Definition mat22_mul.c:194
int lmmp_mat22_mul_size_(lmmp_mat22_t *dst, const lmmp_mat22_t *matA, const lmmp_mat22_t *matB, mp_size_t *tn, mp_size_t *maxa)
计算2x2矩阵和2x2矩阵的乘积需要分配的内存
Definition mat22_mul.c:13
void lmmp_mat22_mul_basecase_(lmmp_mat22_t *dst, const lmmp_mat22_t *matA, const lmmp_mat22_t *matB, mp_ptr tp, mp_size_t tn)
计算2x2矩阵和2x2矩阵的乘积
Definition mat22_mul.c:83
mp_ptr a0
Definition matrix.h:71
mp_ssize_t n11
Definition matrix.h:66
mp_ssize_t n1
Definition matrix.h:74
void lmmp_mat22_sqr_strassen_(lmmp_mat22_t *dst, const lmmp_mat22_t *matA, mp_ptr tp, mp_size_t tn)
计算(稠密)2x2矩阵平方(STRASSEN算法)
Definition mat22_mul.c:346
lmmp_svecn_t lmmp_vecn_t
Definition matrix.h:86
#define INLINE_
Definition matrix.h:51
static void lmmp_mat22_mul_(lmmp_mat22_t *dst, const lmmp_mat22_t *matA, const lmmp_mat22_t *matB, int choose, mp_size_t tn, mp_size_t maxa)
计算2x2矩阵和2x2矩阵的乘积
Definition matrix.h:195
mp_ssize_t lmmp_vec_elem_mul_(mp_ptr *dst, const lmmp_vecn_t *vec)
计算向量的累乘
Definition elem_mul.c:18
lmmp_mat22_t lmmp_smat22_t
Definition matrix.h:68
mp_ssize_t n0
Definition matrix.h:73
mp_ptr * num
Definition matrix.h:81
mp_size_t lmmp_limb_elem_mul_(mp_ptr *dst, const mp_limb_t *limb, mp_size_t n)
计算limb向量的累乘
mp_ssize_t lmmp_slimb_elem_mul_(mp_ptr *dst, const mp_slimb_t *slimb, mp_size_t n)
计算slimb向量的累乘
static void lmmp_mat22_sqr_(lmmp_mat22_t *dst, const lmmp_mat22_t *mat, int choose, mp_size_t tn)
计算(稠密)2x2矩阵平方
Definition matrix.h:217
void lmmp_mat22_sqr_basecase_(lmmp_mat22_t *dst, const lmmp_mat22_t *matA, mp_ptr tp, mp_size_t tn)
计算2x2矩阵平方
Definition mat22_mul.c:119
mp_ptr a1
Definition matrix.h:72
size_t n
Definition matrix.h:83
lmmp_mat21_t lmmp_smat21_t
Definition matrix.h:77
mp_ssize_t n01
Definition matrix.h:64
lmmp_svecn_t lmmp_matn1_t
Definition matrix.h:85
mp_ssize_t n00
Definition matrix.h:63
mp_ptr a00
Definition matrix.h:59
mp_ptr a10
Definition matrix.h:61
mp_ssize_t * len
Definition matrix.h:82
#define tp