LMMC
Lamina Mathematic core
载入中...
搜索中...
未找到
dense_arithmetic.c
浏览该文件的文档.
1
5
6#include <math.h>
7#include <string.h>
8#include "memory_bridge.h"
9#include "internal.h"
10#include "lmmc/config.h"
11#include "lmmc/dense.h"
12#include "lmmc/linear_algebra.h"
13
16
17 if (!lmmc_mat_descriptor_is_valid(a) || out_norm == NULL) {
19 }
20
21 lmmc_scaled_sumsq_init(&acc);
22 for (size_t i = 0; i < a->rows; ++i) {
23 for (size_t j = 0; j < a->cols; ++j) {
24 lmmc_scaled_sumsq_add(
25 &acc, a->data[i * a->stride + j]);
26 }
27 }
28 *out_norm = lmmc_scaled_sumsq_norm(&acc);
29 return LMMC_STATUS_OK;
30}
31
34
35 if (!lmmc_vec_descriptor_is_valid(x) || out_norm == NULL) {
37 }
38
39 lmmc_scaled_sumsq_init(&acc);
40 for (size_t i = 0; i < x->size; ++i) {
41 lmmc_scaled_sumsq_add(&acc, x->data[i]);
42 }
43 *out_norm = lmmc_scaled_sumsq_norm(&acc);
44 return LMMC_STATUS_OK;
45}
46
48 if (!lmmc_vec_descriptor_is_valid(x) || out_norm == NULL) {
50 }
51
52 lmmc_real_t max_val; LMMC_REAL_INIT(&max_val);
53 lmmc_real_t abs_val; LMMC_REAL_INIT(&abs_val);
54 LMMC_REAL_SET_D(&max_val, 0.0);
55
56 for (size_t i = 0; i < x->size; ++i) {
57 LMMC_REAL_ABS(&abs_val, &x->data[i]);
58 max_val = lmmc_max(max_val, abs_val);
59 }
60 LMMC_REAL_SET(out_norm, &max_val);
61
62 LMMC_REAL_CLEAR(&max_val);
63 LMMC_REAL_CLEAR(&abs_val);
64 return LMMC_STATUS_OK;
65}
66
68 if (!lmmc_vec_descriptor_is_valid(x)) {
70 }
71
72 lmmc_real_t tmp_mul; LMMC_REAL_INIT(&tmp_mul);
73
74 for (size_t i = 0; i < x->size; ++i) {
75 LMMC_REAL_MUL(&tmp_mul, &x->data[i], &alpha);
76 LMMC_REAL_SET(&x->data[i], &tmp_mul);
77 }
78
79 LMMC_REAL_CLEAR(&tmp_mul);
80 return LMMC_STATUS_OK;
81}
82
84 if (!lmmc_vec_descriptor_is_valid(x) || out_asum == NULL) {
86 }
87
88 lmmc_real_t sum; LMMC_REAL_INIT(&sum);
89 lmmc_real_t abs_val; LMMC_REAL_INIT(&abs_val);
90 lmmc_real_t tmp_sum; LMMC_REAL_INIT(&tmp_sum);
91 LMMC_REAL_SET_D(&sum, 0.0);
92
93 for (size_t i = 0; i < x->size; ++i) {
94 LMMC_REAL_ABS(&abs_val, &x->data[i]);
95 LMMC_REAL_ADD(&tmp_sum, &sum, &abs_val);
96 LMMC_REAL_SET(&sum, &tmp_sum);
97 }
98 LMMC_REAL_SET(out_asum, &sum);
99
100 LMMC_REAL_CLEAR(&sum);
101 LMMC_REAL_CLEAR(&abs_val);
102 LMMC_REAL_CLEAR(&tmp_sum);
103 return LMMC_STATUS_OK;
104}
105
106lmmc_status_t lmmc_vec_iamax(const lmmc_vec_t* x, size_t* out_idx) {
107 if (!lmmc_vec_descriptor_is_valid(x) || out_idx == NULL) {
109 }
110
111 lmmc_real_t max_val; LMMC_REAL_INIT(&max_val);
112 lmmc_real_t abs_val; LMMC_REAL_INIT(&abs_val);
113 size_t max_idx = 0;
114
115 LMMC_REAL_ABS(&max_val, &x->data[0]);
116
117 for (size_t i = 1; i < x->size; ++i) {
118 LMMC_REAL_ABS(&abs_val, &x->data[i]);
119 if (LMMC_REAL_CMP(&abs_val, &max_val) > 0) {
120 LMMC_REAL_SET(&max_val, &abs_val);
121 max_idx = i;
122 }
123 }
124 *out_idx = max_idx;
125
126 LMMC_REAL_CLEAR(&max_val);
127 LMMC_REAL_CLEAR(&abs_val);
128 return LMMC_STATUS_OK;
129}
130
132 if (!lmmc_mat_descriptor_is_valid(a) ||
133 !lmmc_mat_descriptor_is_valid(b) ||
134 !lmmc_mat_descriptor_is_valid(c)) {
136 }
137 if (a->rows != b->rows || a->cols != b->cols ||
138 a->rows != c->rows || a->cols != c->cols) {
140 }
141
142 lmmc_real_t tmp_sum; LMMC_REAL_INIT(&tmp_sum);
143
144 for (size_t i = 0; i < a->rows; ++i) {
145 for (size_t j = 0; j < a->cols; ++j) {
146 LMMC_REAL_ADD(&tmp_sum,
147 &a->data[i * a->stride + j],
148 &b->data[i * b->stride + j]);
149 LMMC_REAL_SET(&c->data[i * c->stride + j], &tmp_sum);
150 }
151 }
152
153 LMMC_REAL_CLEAR(&tmp_sum);
154 return LMMC_STATUS_OK;
155}
156
158 if (!lmmc_mat_descriptor_is_valid(a) ||
159 !lmmc_mat_descriptor_is_valid(b) ||
160 !lmmc_mat_descriptor_is_valid(c)) {
162 }
163 if (a->rows != b->rows || a->cols != b->cols ||
164 a->rows != c->rows || a->cols != c->cols) {
166 }
167
168 lmmc_real_t tmp_sub; LMMC_REAL_INIT(&tmp_sub);
169
170 for (size_t i = 0; i < a->rows; ++i) {
171 for (size_t j = 0; j < a->cols; ++j) {
172 LMMC_REAL_SUB(&tmp_sub,
173 &a->data[i * a->stride + j],
174 &b->data[i * b->stride + j]);
175 LMMC_REAL_SET(&c->data[i * c->stride + j], &tmp_sub);
176 }
177 }
178
179 LMMC_REAL_CLEAR(&tmp_sub);
180 return LMMC_STATUS_OK;
181}
182
184 if (!lmmc_mat_descriptor_is_valid(a)) {
186 }
187
188 lmmc_real_t tmp_mul; LMMC_REAL_INIT(&tmp_mul);
189
190 for (size_t i = 0; i < a->rows; ++i) {
191 for (size_t j = 0; j < a->cols; ++j) {
192 LMMC_REAL_MUL(&tmp_mul, &a->data[i * a->stride + j], &alpha);
193 LMMC_REAL_SET(&a->data[i * a->stride + j], &tmp_mul);
194 }
195 }
196
197 LMMC_REAL_CLEAR(&tmp_mul);
198 return LMMC_STATUS_OK;
199}
200
202 if (out_mat == NULL || n == 0) {
204 }
205
206 lmmc_status_t status = lmmc_mat_create(n, n, out_mat);
207 if (status != LMMC_STATUS_OK) {
208 return status;
209 }
210
211 lmmc_real_t one; LMMC_REAL_INIT(&one);
212 LMMC_REAL_SET_D(&one, 1.0);
213
214 for (size_t i = 0; i < n; ++i) {
215 LMMC_REAL_SET(&out_mat->data[i * out_mat->stride + i], &one);
216 }
217
218 LMMC_REAL_CLEAR(&one);
219 return LMMC_STATUS_OK;
220}
221
223 if (!lmmc_mat_descriptor_is_valid(a) || out_trace == NULL) {
225 }
226 if (a->rows != a->cols) {
228 }
229
230 lmmc_real_t sum; LMMC_REAL_INIT(&sum);
231 lmmc_real_t tmp_sum; LMMC_REAL_INIT(&tmp_sum);
232 LMMC_REAL_SET_D(&sum, 0.0);
233
234 for (size_t i = 0; i < a->rows; ++i) {
235 LMMC_REAL_ADD(&tmp_sum, &sum, &a->data[i * a->stride + i]);
236 LMMC_REAL_SET(&sum, &tmp_sum);
237 }
238 LMMC_REAL_SET(out_trace, &sum);
239
240 LMMC_REAL_CLEAR(&sum);
241 LMMC_REAL_CLEAR(&tmp_sum);
242 return LMMC_STATUS_OK;
243}
244
246 size_t i, j;
247 lmmc_real_t col_sum;
248 lmmc_real_t abs_val;
249 lmmc_real_t tmp_sum;
250 lmmc_real_t max_val;
251
252 if (!lmmc_mat_descriptor_is_valid(a) || out_norm == NULL) {
254 }
255
256 LMMC_REAL_INIT(&col_sum);
257 LMMC_REAL_INIT(&abs_val);
258 LMMC_REAL_INIT(&tmp_sum);
259 LMMC_REAL_INIT(&max_val);
260 LMMC_REAL_SET_D(&max_val, 0.0);
261
262 for (j = 0; j < a->cols; ++j) {
263 LMMC_REAL_SET_D(&col_sum, 0.0);
264 for (i = 0; i < a->rows; ++i) {
265 LMMC_REAL_ABS(&abs_val, &a->data[i * a->stride + j]);
266 LMMC_REAL_ADD(&tmp_sum, &col_sum, &abs_val);
267 LMMC_REAL_SET(&col_sum, &tmp_sum);
268 }
269 if (LMMC_REAL_CMP(&col_sum, &max_val) > 0) {
270 LMMC_REAL_SET(&max_val, &col_sum);
271 }
272 }
273
274 LMMC_REAL_SET(out_norm, &max_val);
275
276 LMMC_REAL_CLEAR(&col_sum);
277 LMMC_REAL_CLEAR(&abs_val);
278 LMMC_REAL_CLEAR(&tmp_sum);
279 LMMC_REAL_CLEAR(&max_val);
280 return LMMC_STATUS_OK;
281}
282
284 size_t i, j;
285 lmmc_real_t row_sum;
286 lmmc_real_t abs_val;
287 lmmc_real_t tmp_sum;
288 lmmc_real_t max_val;
289
290 if (!lmmc_mat_descriptor_is_valid(a) || out_norm == NULL) {
292 }
293
294 LMMC_REAL_INIT(&row_sum);
295 LMMC_REAL_INIT(&abs_val);
296 LMMC_REAL_INIT(&tmp_sum);
297 LMMC_REAL_INIT(&max_val);
298 LMMC_REAL_SET_D(&max_val, 0.0);
299
300 for (i = 0; i < a->rows; ++i) {
301 LMMC_REAL_SET_D(&row_sum, 0.0);
302 for (j = 0; j < a->cols; ++j) {
303 LMMC_REAL_ABS(&abs_val, &a->data[i * a->stride + j]);
304 LMMC_REAL_ADD(&tmp_sum, &row_sum, &abs_val);
305 LMMC_REAL_SET(&row_sum, &tmp_sum);
306 }
307 if (LMMC_REAL_CMP(&row_sum, &max_val) > 0) {
308 LMMC_REAL_SET(&max_val, &row_sum);
309 }
310 }
311
312 LMMC_REAL_SET(out_norm, &max_val);
313
314 LMMC_REAL_CLEAR(&row_sum);
315 LMMC_REAL_CLEAR(&abs_val);
316 LMMC_REAL_CLEAR(&tmp_sum);
317 LMMC_REAL_CLEAR(&max_val);
318 return LMMC_STATUS_OK;
319}
320
LMMC binary real type and arithmetic spelling.
#define LMMC_REAL_CLEAR(x)
释放一个 lmmc_real_t 变量(POD 类型为空操作)。
#define LMMC_REAL_INIT(x)
初始化一个 lmmc_real_t 变量(POD 类型为空操作)。
#define LMMC_REAL_ADD(res, a, b)
计算 *res = *a + *b 。
#define LMMC_REAL_SUB(res, a, b)
计算 *res = *a - *b 。
double lmmc_real_t
Public and internal LMMC real type.
#define LMMC_REAL_SET(dst, src)
将一个 lmmc_real_t 赋值到另一个:*dst = *src 。
#define LMMC_REAL_MUL(res, a, b)
计算 *res = *a * *b 。
#define LMMC_REAL_ABS(res, a)
计算绝对值,*res = |*a| 。
#define LMMC_REAL_CMP(a, b)
比较 *a 与 *b ,返回 -1/0/1 。
#define LMMC_REAL_SET_D(dst, dbl)
将一个 double 字面量赋值到 lmmc_real_t 。
lmmc_status_t lmmc_mat_scale(lmmc_mat_t *a, lmmc_real_t alpha)
就地矩阵标量乘: 。
lmmc_status_t lmmc_vec_iamax(const lmmc_vec_t *x, size_t *out_idx)
返回绝对值最大元素的下标。
lmmc_status_t lmmc_mat_norm_fro(const lmmc_mat_t *a, lmmc_real_t *out_norm)
计算矩阵的 Frobenius 范数: 。
lmmc_status_t lmmc_vec_asum(const lmmc_vec_t *x, lmmc_real_t *out_asum)
计算向量元素绝对值之和(L1 范数): 。
lmmc_status_t lmmc_mat_sub(const lmmc_mat_t *a, const lmmc_mat_t *b, lmmc_mat_t *c)
同维矩阵逐元素减法:c = a - b。
lmmc_status_t lmmc_mat_add(const lmmc_mat_t *a, const lmmc_mat_t *b, lmmc_mat_t *c)
同维矩阵逐元素加法:c = a + b。
lmmc_status_t lmmc_vec_scale(lmmc_vec_t *x, lmmc_real_t alpha)
就地向量缩放: 。
lmmc_status_t lmmc_mat_norm1(const lmmc_mat_t *a, lmmc_real_t *out_norm)
计算矩阵的 1-范数(最大绝对列和): 。
lmmc_status_t lmmc_mat_norm_inf(const lmmc_mat_t *a, lmmc_real_t *out_norm)
计算矩阵的无穷范数(最大绝对行和): 。
lmmc_status_t lmmc_vec_norm2(const lmmc_vec_t *x, lmmc_real_t *out_norm)
计算向量的欧几里得(L2)范数: 。 采用缩放平方和累加;最终结果超出 binary64 范围时可为无穷。
lmmc_status_t lmmc_vec_norm_inf(const lmmc_vec_t *x, lmmc_real_t *out_norm)
计算向量的无穷范数: 。
lmmc_status_t lmmc_mat_trace(const lmmc_mat_t *a, lmmc_real_t *out_trace)
计算方阵的迹: 。
lmmc_status_t lmmc_mat_create(size_t rows, size_t cols, lmmc_mat_t *out_mat)
创建 rows x cols 的零矩阵。
lmmc_status_t lmmc_mat_identity(size_t n, lmmc_mat_t *out_mat)
创建 nxn 单位矩阵,对角线为 1,其余元素为 0。
lmmc_real_t * data
lmmc_real_t * data
行优先存储的稠密矩阵。
一维稠密向量。
LMMC 内部使用的公共工具(仅源文件可见).
稠密矩阵直接分解接口(LU、Cholesky、QR)。
Private recoverable allocator for persistent LMMC ownership.
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_OK
@ LMMC_STATUS_DIMENSION_MISMATCH
@ LMMC_STATUS_INVALID_ARGUMENT