LMMC
Lamina Mathematic core
载入中...
搜索中...
未找到
stdlib_linalg_elementwise.c
浏览该文件的文档.
1#include "lmmc/stdlib.h"
2
3#include "lmmc/dense.h"
4
5#include "stdlib_internal.h"
6
8 const lmmc_vec_t* b,
9 lmmc_vec_t* out)
10{
11 lmmc_status_t status;
12 lmmc_vec_t result = {0};
13 if (!lmmc_std_vec_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
14 status = lmmc_std_require_finite_vec(a);
15 if (status != LMMC_STATUS_OK) { return status; }
16 status = lmmc_std_require_finite_vec(b);
17 if (status != LMMC_STATUS_OK) { return status; }
18 if (a->size != b->size) { return LMMC_STATUS_DIMENSION_MISMATCH; }
19 status = lmmc_std_copy_vec(a, &result);
20 if (status != LMMC_STATUS_OK) { return status; }
21 status = lmmc_vec_axpy((lmmc_real_t)1, b, &result);
22 if (status == LMMC_STATUS_OK) {
23 status = lmmc_std_require_finite_vec(&result);
24 }
25 if (status != LMMC_STATUS_OK) {
26 lmmc_vec_destroy(&result);
27 } else {
28 *out = result;
29 }
30 return status;
31}
32
34 lmmc_real_t scalar,
35 lmmc_vec_t* out)
36{
37 lmmc_status_t status;
38 lmmc_vec_t result = {0};
39 if (!lmmc_std_vec_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
40 if (!lmmc_std_real_is_finite(scalar)) {
42 }
43 status = lmmc_std_copy_vec(x, &result);
44 if (status != LMMC_STATUS_OK) { return status; }
45 for (size_t i = 0; i < result.size; ++i) {
46 result.data[i] += scalar;
47 }
48 status = lmmc_std_require_finite_vec(&result);
49 if (status != LMMC_STATUS_OK) {
50 lmmc_vec_destroy(&result);
51 } else {
52 *out = result;
53 }
54 return status;
55}
56
58 const lmmc_vec_t* b,
59 lmmc_vec_t* out)
60{
61 lmmc_status_t status;
62 lmmc_vec_t result = {0};
63 if (!lmmc_std_vec_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
64 status = lmmc_std_require_finite_vec(a);
65 if (status != LMMC_STATUS_OK) { return status; }
66 status = lmmc_std_require_finite_vec(b);
67 if (status != LMMC_STATUS_OK) { return status; }
68 if (a->size != b->size) { return LMMC_STATUS_DIMENSION_MISMATCH; }
69 status = lmmc_std_copy_vec(a, &result);
70 if (status != LMMC_STATUS_OK) { return status; }
71 status = lmmc_vec_axpy((lmmc_real_t)-1, b, &result);
72 if (status == LMMC_STATUS_OK) {
73 status = lmmc_std_require_finite_vec(&result);
74 }
75 if (status != LMMC_STATUS_OK) {
76 lmmc_vec_destroy(&result);
77 } else {
78 *out = result;
79 }
80 return status;
81}
82
84 lmmc_real_t scalar,
85 lmmc_vec_t* out)
86{
87 return lmmc_std_linalg_vec_add_scalar(x, -scalar, out);
88}
89
91 const lmmc_vec_t* x,
92 lmmc_vec_t* out)
93{
94 lmmc_status_t status;
95 lmmc_vec_t result = {0};
96 if (!lmmc_std_vec_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
97 if (!lmmc_std_real_is_finite(scalar)) {
99 }
100 status = lmmc_std_require_finite_vec(x);
101 if (status != LMMC_STATUS_OK) { return status; }
102 status = lmmc_vec_create(x->size, &result);
103 if (status != LMMC_STATUS_OK) { return status; }
104 for (size_t i = 0; i < result.size; ++i) {
105 result.data[i] = scalar - x->data[i];
106 }
107 status = lmmc_std_require_finite_vec(&result);
108 if (status != LMMC_STATUS_OK) {
109 lmmc_vec_destroy(&result);
110 } else {
111 *out = result;
112 }
113 return status;
114}
115
117 const lmmc_vec_t* b,
118 lmmc_vec_t* out)
119{
120 lmmc_status_t status;
121 lmmc_vec_t result = {0};
122 if (!lmmc_std_vec_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
123 status = lmmc_std_require_finite_vec(a);
124 if (status != LMMC_STATUS_OK) { return status; }
125 status = lmmc_std_require_finite_vec(b);
126 if (status != LMMC_STATUS_OK) { return status; }
127 if (a->size != b->size) { return LMMC_STATUS_DIMENSION_MISMATCH; }
128 status = lmmc_vec_create(a->size, &result);
129 if (status != LMMC_STATUS_OK) { return status; }
130 for (size_t i = 0; i < result.size; ++i) {
131 result.data[i] = a->data[i] * b->data[i];
132 }
133 status = lmmc_std_require_finite_vec(&result);
134 if (status != LMMC_STATUS_OK) {
135 lmmc_vec_destroy(&result);
136 } else {
137 *out = result;
138 }
139 return status;
140}
141
143 const lmmc_vec_t* b,
144 lmmc_vec_t* out)
145{
146 lmmc_status_t status;
147 lmmc_vec_t result = {0};
148 if (!lmmc_std_vec_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
149 status = lmmc_std_require_finite_vec(a);
150 if (status != LMMC_STATUS_OK) { return status; }
151 status = lmmc_std_require_finite_vec(b);
152 if (status != LMMC_STATUS_OK) { return status; }
153 if (a->size != b->size) { return LMMC_STATUS_DIMENSION_MISMATCH; }
154 for (size_t i = 0; i < b->size; ++i) {
155 if (b->data[i] == (lmmc_real_t)0) { return LMMC_STATUS_NUMERICAL_FAILURE; }
156 }
157 status = lmmc_vec_create(a->size, &result);
158 if (status != LMMC_STATUS_OK) { return status; }
159 for (size_t i = 0; i < result.size; ++i) {
160 result.data[i] = a->data[i] / b->data[i];
161 }
162 status = lmmc_std_require_finite_vec(&result);
163 if (status != LMMC_STATUS_OK) {
164 lmmc_vec_destroy(&result);
165 } else {
166 *out = result;
167 }
168 return status;
169}
170
172 lmmc_real_t scalar,
173 lmmc_vec_t* out)
174{
175 lmmc_status_t status;
176 lmmc_vec_t result = {0};
177 if (!lmmc_std_vec_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
178 if (scalar == (lmmc_real_t)0) { return LMMC_STATUS_NUMERICAL_FAILURE; }
179 if (!lmmc_std_real_is_finite(scalar)) { return LMMC_STATUS_NUMERICAL_FAILURE; }
180 status = lmmc_std_require_finite_vec(x);
181 if (status != LMMC_STATUS_OK) { return status; }
182 status = lmmc_vec_create(x->size, &result);
183 if (status != LMMC_STATUS_OK) { return status; }
184 for (size_t i = 0; i < result.size; ++i) {
185 result.data[i] = x->data[i] / scalar;
186 }
187 status = lmmc_std_require_finite_vec(&result);
188 if (status != LMMC_STATUS_OK) {
189 lmmc_vec_destroy(&result);
190 } else {
191 *out = result;
192 }
193 return status;
194}
195
197 const lmmc_vec_t* x,
198 lmmc_vec_t* out)
199{
200 lmmc_status_t status;
201 lmmc_vec_t result = {0};
202 if (!lmmc_std_vec_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
203 if (!lmmc_std_real_is_finite(scalar)) {
205 }
206 status = lmmc_std_require_finite_vec(x);
207 if (status != LMMC_STATUS_OK) { return status; }
208 for (size_t i = 0; i < x->size; ++i) {
209 if (x->data[i] == (lmmc_real_t)0) { return LMMC_STATUS_NUMERICAL_FAILURE; }
210 }
211 status = lmmc_vec_create(x->size, &result);
212 if (status != LMMC_STATUS_OK) { return status; }
213 for (size_t i = 0; i < result.size; ++i) {
214 result.data[i] = scalar / x->data[i];
215 }
216 status = lmmc_std_require_finite_vec(&result);
217 if (status != LMMC_STATUS_OK) {
218 lmmc_vec_destroy(&result);
219 } else {
220 *out = result;
221 }
222 return status;
223}
224
226 const lmmc_vec_t* exponent,
227 lmmc_vec_t* out)
228{
229 lmmc_status_t status;
230 lmmc_vec_t result = {0};
231 if (!lmmc_std_vec_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
232 status = lmmc_std_require_finite_vec(base);
233 if (status != LMMC_STATUS_OK) { return status; }
234 status = lmmc_std_require_finite_vec(exponent);
235 if (status != LMMC_STATUS_OK) { return status; }
236 if (base->size != exponent->size) { return LMMC_STATUS_DIMENSION_MISMATCH; }
237 status = lmmc_vec_create(base->size, &result);
238 if (status != LMMC_STATUS_OK) { return status; }
239 for (size_t i = 0; i < result.size; ++i) {
240 status =
241 lmmc_std_pow_finite(base->data[i], exponent->data[i], &result.data[i]);
242 if (status != LMMC_STATUS_OK) {
243 lmmc_vec_destroy(&result);
244 return status;
245 }
246 }
247 status = lmmc_std_require_finite_vec(&result);
248 if (status != LMMC_STATUS_OK) {
249 lmmc_vec_destroy(&result);
250 } else {
251 *out = result;
252 }
253 return status;
254}
255
257 lmmc_real_t exponent,
258 lmmc_vec_t* out)
259{
260 lmmc_status_t status;
261 lmmc_vec_t result = {0};
262 if (!lmmc_std_vec_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
263 status = lmmc_std_require_finite_vec(base);
264 if (status != LMMC_STATUS_OK) { return status; }
265 if (!lmmc_std_real_is_finite(exponent)) {
267 }
268 status = lmmc_vec_create(base->size, &result);
269 if (status != LMMC_STATUS_OK) { return status; }
270 for (size_t i = 0; i < result.size; ++i) {
271 status = lmmc_std_pow_finite(base->data[i], exponent, &result.data[i]);
272 if (status != LMMC_STATUS_OK) {
273 lmmc_vec_destroy(&result);
274 return status;
275 }
276 }
277 status = lmmc_std_require_finite_vec(&result);
278 if (status != LMMC_STATUS_OK) {
279 lmmc_vec_destroy(&result);
280 } else {
281 *out = result;
282 }
283 return status;
284}
285
287 lmmc_real_t alpha,
288 lmmc_vec_t* out)
289{
290 lmmc_status_t status;
291 lmmc_vec_t result = {0};
292 if (!lmmc_std_vec_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
293 if (!lmmc_std_real_is_finite(alpha)) { return LMMC_STATUS_NUMERICAL_FAILURE; }
294 status = lmmc_std_copy_vec(x, &result);
295 if (status != LMMC_STATUS_OK) { return status; }
296 status = lmmc_vec_scale(&result, alpha);
297 if (status == LMMC_STATUS_OK) {
298 status = lmmc_std_require_finite_vec(&result);
299 }
300 if (status != LMMC_STATUS_OK) {
301 lmmc_vec_destroy(&result);
302 } else {
303 *out = result;
304 }
305 return status;
306}
307
309 lmmc_real_t scalar,
310 lmmc_vec_t* out)
311{
312 return lmmc_std_linalg_vec_scale(x, scalar, out);
313}
314
316 const lmmc_mat_t* b,
317 lmmc_mat_t* out)
318{
319 lmmc_status_t status;
320 lmmc_mat_t result = {0};
321 if (!lmmc_std_mat_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
322 status = lmmc_std_require_finite_mat(a);
323 if (status != LMMC_STATUS_OK) { return status; }
324 status = lmmc_std_require_finite_mat(b);
325 if (status != LMMC_STATUS_OK) { return status; }
326 if (a->rows != b->rows || a->cols != b->cols) {
328 }
329 status = lmmc_mat_create(a->rows, a->cols, &result);
330 if (status != LMMC_STATUS_OK) { return status; }
331 status = lmmc_mat_add(a, b, &result);
332 if (status == LMMC_STATUS_OK) {
333 status = lmmc_std_require_finite_mat(&result);
334 }
335 if (status != LMMC_STATUS_OK) {
336 lmmc_mat_destroy(&result);
337 } else {
338 *out = result;
339 }
340 return status;
341}
342
344 lmmc_real_t scalar,
345 lmmc_mat_t* out)
346{
347 lmmc_status_t status;
348 lmmc_mat_t result = {0};
349 if (!lmmc_std_mat_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
350 if (!lmmc_std_real_is_finite(scalar)) {
352 }
353 status = lmmc_std_copy_mat(a, &result);
354 if (status != LMMC_STATUS_OK) { return status; }
355 for (size_t i = 0; i < result.rows; ++i) {
356 for (size_t j = 0; j < result.cols; ++j) {
357 result.data[i * result.stride + j] += scalar;
358 }
359 }
360 status = lmmc_std_require_finite_mat(&result);
361 if (status != LMMC_STATUS_OK) {
362 lmmc_mat_destroy(&result);
363 } else {
364 *out = result;
365 }
366 return status;
367}
368
370 const lmmc_mat_t* b,
371 lmmc_mat_t* out)
372{
373 lmmc_status_t status;
374 lmmc_mat_t result = {0};
375 if (!lmmc_std_mat_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
376 status = lmmc_std_require_finite_mat(a);
377 if (status != LMMC_STATUS_OK) { return status; }
378 status = lmmc_std_require_finite_mat(b);
379 if (status != LMMC_STATUS_OK) { return status; }
380 if (a->rows != b->rows || a->cols != b->cols) {
382 }
383 status = lmmc_mat_create(a->rows, a->cols, &result);
384 if (status != LMMC_STATUS_OK) { return status; }
385 status = lmmc_mat_sub(a, b, &result);
386 if (status == LMMC_STATUS_OK) {
387 status = lmmc_std_require_finite_mat(&result);
388 }
389 if (status != LMMC_STATUS_OK) {
390 lmmc_mat_destroy(&result);
391 } else {
392 *out = result;
393 }
394 return status;
395}
396
398 lmmc_real_t scalar,
399 lmmc_mat_t* out)
400{
401 return lmmc_std_linalg_mat_add_scalar(a, -scalar, out);
402}
403
405 const lmmc_mat_t* a,
406 lmmc_mat_t* out)
407{
408 lmmc_status_t status;
409 lmmc_mat_t result = {0};
410 if (!lmmc_std_mat_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
411 if (!lmmc_std_real_is_finite(scalar)) {
413 }
414 status = lmmc_std_require_finite_mat(a);
415 if (status != LMMC_STATUS_OK) { return status; }
416 status = lmmc_mat_create(a->rows, a->cols, &result);
417 if (status != LMMC_STATUS_OK) { return status; }
418 for (size_t i = 0; i < result.rows; ++i) {
419 for (size_t j = 0; j < result.cols; ++j) {
420 result.data[i * result.stride + j] =
421 scalar - a->data[i * a->stride + j];
422 }
423 }
424 status = lmmc_std_require_finite_mat(&result);
425 if (status != LMMC_STATUS_OK) {
426 lmmc_mat_destroy(&result);
427 } else {
428 *out = result;
429 }
430 return status;
431}
432
434 const lmmc_mat_t* b,
435 lmmc_mat_t* out)
436{
437 lmmc_status_t status;
438 lmmc_mat_t result = {0};
439 if (!lmmc_std_mat_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
440 status = lmmc_std_require_finite_mat(a);
441 if (status != LMMC_STATUS_OK) { return status; }
442 status = lmmc_std_require_finite_mat(b);
443 if (status != LMMC_STATUS_OK) { return status; }
444 if (a->rows != b->rows || a->cols != b->cols) {
446 }
447 status = lmmc_mat_create(a->rows, a->cols, &result);
448 if (status != LMMC_STATUS_OK) { return status; }
449 for (size_t i = 0; i < result.rows; ++i) {
450 for (size_t j = 0; j < result.cols; ++j) {
451 result.data[i * result.stride + j] =
452 a->data[i * a->stride + j] * b->data[i * b->stride + j];
453 }
454 }
455 status = lmmc_std_require_finite_mat(&result);
456 if (status != LMMC_STATUS_OK) {
457 lmmc_mat_destroy(&result);
458 } else {
459 *out = result;
460 }
461 return status;
462}
463
465 const lmmc_mat_t* b,
466 lmmc_mat_t* out)
467{
468 lmmc_status_t status;
469 lmmc_mat_t result = {0};
470 if (!lmmc_std_mat_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
471 status = lmmc_std_require_finite_mat(a);
472 if (status != LMMC_STATUS_OK) { return status; }
473 status = lmmc_std_require_finite_mat(b);
474 if (status != LMMC_STATUS_OK) { return status; }
475 if (a->rows != b->rows || a->cols != b->cols) {
477 }
478 for (size_t i = 0; i < b->rows; ++i) {
479 for (size_t j = 0; j < b->cols; ++j) {
480 if (b->data[i * b->stride + j] == (lmmc_real_t)0) {
482 }
483 }
484 }
485 status = lmmc_mat_create(a->rows, a->cols, &result);
486 if (status != LMMC_STATUS_OK) { return status; }
487 for (size_t i = 0; i < result.rows; ++i) {
488 for (size_t j = 0; j < result.cols; ++j) {
489 lmmc_real_t denom = b->data[i * b->stride + j];
490 result.data[i * result.stride + j] =
491 a->data[i * a->stride + j] / denom;
492 }
493 }
494 status = lmmc_std_require_finite_mat(&result);
495 if (status != LMMC_STATUS_OK) {
496 lmmc_mat_destroy(&result);
497 } else {
498 *out = result;
499 }
500 return status;
501}
502
504 lmmc_real_t scalar,
505 lmmc_mat_t* out)
506{
507 lmmc_status_t status;
508 lmmc_mat_t result = {0};
509 if (!lmmc_std_mat_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
510 if (scalar == (lmmc_real_t)0) { return LMMC_STATUS_NUMERICAL_FAILURE; }
511 if (!lmmc_std_real_is_finite(scalar)) { return LMMC_STATUS_NUMERICAL_FAILURE; }
512 status = lmmc_std_require_finite_mat(a);
513 if (status != LMMC_STATUS_OK) { return status; }
514 status = lmmc_mat_create(a->rows, a->cols, &result);
515 if (status != LMMC_STATUS_OK) { return status; }
516 for (size_t i = 0; i < result.rows; ++i) {
517 for (size_t j = 0; j < result.cols; ++j) {
518 result.data[i * result.stride + j] =
519 a->data[i * a->stride + j] / scalar;
520 }
521 }
522 status = lmmc_std_require_finite_mat(&result);
523 if (status != LMMC_STATUS_OK) {
524 lmmc_mat_destroy(&result);
525 } else {
526 *out = result;
527 }
528 return status;
529}
530
532 const lmmc_mat_t* a,
533 lmmc_mat_t* out)
534{
535 lmmc_status_t status;
536 lmmc_mat_t result = {0};
537 if (!lmmc_std_mat_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
538 if (!lmmc_std_real_is_finite(scalar)) {
540 }
541 status = lmmc_std_require_finite_mat(a);
542 if (status != LMMC_STATUS_OK) { return status; }
543 for (size_t i = 0; i < a->rows; ++i) {
544 for (size_t j = 0; j < a->cols; ++j) {
545 if (a->data[i * a->stride + j] == (lmmc_real_t)0) {
547 }
548 }
549 }
550 status = lmmc_mat_create(a->rows, a->cols, &result);
551 if (status != LMMC_STATUS_OK) { return status; }
552 for (size_t i = 0; i < result.rows; ++i) {
553 for (size_t j = 0; j < result.cols; ++j) {
554 lmmc_real_t denom = a->data[i * a->stride + j];
555 result.data[i * result.stride + j] = scalar / denom;
556 }
557 }
558 status = lmmc_std_require_finite_mat(&result);
559 if (status != LMMC_STATUS_OK) {
560 lmmc_mat_destroy(&result);
561 } else {
562 *out = result;
563 }
564 return status;
565}
566
568 const lmmc_mat_t* exponent,
569 lmmc_mat_t* out)
570{
571 lmmc_status_t status;
572 lmmc_mat_t result = {0};
573 if (!lmmc_std_mat_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
574 status = lmmc_std_require_finite_mat(base);
575 if (status != LMMC_STATUS_OK) { return status; }
576 status = lmmc_std_require_finite_mat(exponent);
577 if (status != LMMC_STATUS_OK) { return status; }
578 if (base->rows != exponent->rows || base->cols != exponent->cols) {
580 }
581 status = lmmc_mat_create(base->rows, base->cols, &result);
582 if (status != LMMC_STATUS_OK) { return status; }
583 for (size_t i = 0; i < result.rows; ++i) {
584 for (size_t j = 0; j < result.cols; ++j) {
585 status = lmmc_std_pow_finite(base->data[i * base->stride + j],
586 exponent->data[i * exponent->stride + j],
587 &result.data[i * result.stride + j]);
588 if (status != LMMC_STATUS_OK) {
589 lmmc_mat_destroy(&result);
590 return status;
591 }
592 }
593 }
594 status = lmmc_std_require_finite_mat(&result);
595 if (status != LMMC_STATUS_OK) {
596 lmmc_mat_destroy(&result);
597 } else {
598 *out = result;
599 }
600 return status;
601}
602
604 lmmc_real_t exponent,
605 lmmc_mat_t* out)
606{
607 lmmc_status_t status;
608 lmmc_mat_t result = {0};
609 if (!lmmc_std_mat_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
610 status = lmmc_std_require_finite_mat(base);
611 if (status != LMMC_STATUS_OK) { return status; }
612 if (!lmmc_std_real_is_finite(exponent)) {
614 }
615 status = lmmc_mat_create(base->rows, base->cols, &result);
616 if (status != LMMC_STATUS_OK) { return status; }
617 for (size_t i = 0; i < result.rows; ++i) {
618 for (size_t j = 0; j < result.cols; ++j) {
619 status = lmmc_std_pow_finite(base->data[i * base->stride + j],
620 exponent,
621 &result.data[i * result.stride + j]);
622 if (status != LMMC_STATUS_OK) {
623 lmmc_mat_destroy(&result);
624 return status;
625 }
626 }
627 }
628 status = lmmc_std_require_finite_mat(&result);
629 if (status != LMMC_STATUS_OK) {
630 lmmc_mat_destroy(&result);
631 } else {
632 *out = result;
633 }
634 return status;
635}
636
637static lmmc_status_t lmmc_std_replace_with_product(
638 lmmc_mat_t* target, const lmmc_mat_t* factor)
639{
640 lmmc_mat_t product = {0, 0, 0, NULL, 0};
641 lmmc_status_t status = lmmc_mat_create(target->rows, factor->cols, &product);
642 if (status != LMMC_STATUS_OK) {
643 return status;
644 }
645 status = lmmc_mat_mul(target, factor, &product);
646 if (status == LMMC_STATUS_OK) {
647 status = lmmc_std_require_finite_mat(&product);
648 }
649 if (status != LMMC_STATUS_OK) {
650 lmmc_mat_destroy(&product);
651 return status;
652 }
653 lmmc_mat_destroy(target);
654 *target = product;
655 return LMMC_STATUS_OK;
656}
657
659 int64_t exponent,
660 lmmc_mat_t* out)
661{
662 lmmc_status_t status;
663 lmmc_mat_t factor = {0, 0, 0, NULL, 0};
664 lmmc_mat_t result = {0, 0, 0, NULL, 0};
665
666 if (!lmmc_std_mat_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
667 status = lmmc_std_require_finite_mat(base);
668 if (status != LMMC_STATUS_OK) { return status; }
669 if (base->rows != base->cols) { return LMMC_STATUS_DIMENSION_MISMATCH; }
670
671 uint64_t power;
672 if (exponent < 0) {
673 status = lmmc_std_linalg_inv(base, &factor);
674 if (status != LMMC_STATUS_OK) { return status; }
675 power = (uint64_t)(-(exponent + 1)) + UINT64_C(1);
676 } else {
677 status = lmmc_std_copy_mat(base, &factor);
678 if (status != LMMC_STATUS_OK) { return status; }
679 power = (uint64_t)exponent;
680 }
681
682 status = lmmc_mat_identity(base->rows, &result);
683 if (status != LMMC_STATUS_OK) {
684 lmmc_mat_destroy(&factor);
685 return status;
686 }
687
688 while (power > 0) {
689 if ((power & UINT64_C(1)) != 0) {
690 status = lmmc_std_replace_with_product(&result, &factor);
691 if (status != LMMC_STATUS_OK) {
692 lmmc_mat_destroy(&result);
693 lmmc_mat_destroy(&factor);
694 return status;
695 }
696 }
697
698 power >>= 1;
699 if (power > 0) {
700 status = lmmc_std_replace_with_product(&factor, &factor);
701 if (status != LMMC_STATUS_OK) {
702 lmmc_mat_destroy(&result);
703 lmmc_mat_destroy(&factor);
704 return status;
705 }
706 }
707 }
708
709 lmmc_mat_destroy(&factor);
710 *out = result;
711 return LMMC_STATUS_OK;
712}
713
715 lmmc_real_t alpha,
716 lmmc_mat_t* out)
717{
718 lmmc_status_t status;
719 lmmc_mat_t result = {0};
720 if (!lmmc_std_mat_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
721 if (!lmmc_std_real_is_finite(alpha)) { return LMMC_STATUS_NUMERICAL_FAILURE; }
722 status = lmmc_std_copy_mat(a, &result);
723 if (status != LMMC_STATUS_OK) { return status; }
724 status = lmmc_mat_scale(&result, alpha);
725 if (status == LMMC_STATUS_OK) {
726 status = lmmc_std_require_finite_mat(&result);
727 }
728 if (status != LMMC_STATUS_OK) {
729 lmmc_mat_destroy(&result);
730 } else {
731 *out = result;
732 }
733 return status;
734}
735
737 lmmc_real_t scalar,
738 lmmc_mat_t* out)
739{
740 return lmmc_std_linalg_mat_scale(a, scalar, out);
741}
742
744 const lmmc_vec_t* b,
747{
748 lmmc_status_t status;
749 lmmc_std_bool_vec_t result = {0};
750 uint8_t ignored;
751 if (!lmmc_std_bool_vec_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
752 status = lmmc_std_require_finite_vec(a);
753 if (status != LMMC_STATUS_OK) { return status; }
754 status = lmmc_std_require_finite_vec(b);
755 if (status != LMMC_STATUS_OK) { return status; }
756 if (a->size != b->size) { return LMMC_STATUS_DIMENSION_MISMATCH; }
757 if (!lmmc_std_compare_eval(0, op, 0, &ignored)) {
759 }
760 status = lmmc_std_bool_vec_create(a->size, &result);
761 if (status != LMMC_STATUS_OK) { return status; }
762 for (size_t i = 0; i < result.size; ++i) {
763 (void)lmmc_std_compare_eval(a->data[i], op, b->data[i], &result.data[i]);
764 }
765 *out = result;
766 return LMMC_STATUS_OK;
767}
768
771 lmmc_real_t scalar,
773{
774 lmmc_status_t status;
775 lmmc_std_bool_vec_t result = {0};
776 uint8_t ignored;
777 if (!lmmc_std_bool_vec_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
778 status = lmmc_std_require_finite_vec(a);
779 if (status != LMMC_STATUS_OK) { return status; }
780 if (!lmmc_std_real_is_finite(scalar)) {
782 }
783 if (!lmmc_std_compare_eval(0, op, 0, &ignored)) {
785 }
786 status = lmmc_std_bool_vec_create(a->size, &result);
787 if (status != LMMC_STATUS_OK) { return status; }
788 for (size_t i = 0; i < result.size; ++i) {
789 (void)lmmc_std_compare_eval(a->data[i], op, scalar, &result.data[i]);
790 }
791 *out = result;
792 return LMMC_STATUS_OK;
793}
794
796 const lmmc_mat_t* b,
799{
800 lmmc_status_t status;
801 lmmc_std_bool_mat_t result = {0};
802 uint8_t ignored;
803 if (!lmmc_std_bool_mat_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
804 status = lmmc_std_require_finite_mat(a);
805 if (status != LMMC_STATUS_OK) { return status; }
806 status = lmmc_std_require_finite_mat(b);
807 if (status != LMMC_STATUS_OK) { return status; }
808 if (a->rows != b->rows || a->cols != b->cols) {
810 }
811 if (!lmmc_std_compare_eval(0, op, 0, &ignored)) {
813 }
814 status = lmmc_std_bool_mat_create(a->rows, a->cols, &result);
815 if (status != LMMC_STATUS_OK) { return status; }
816 for (size_t i = 0; i < result.rows; ++i) {
817 for (size_t j = 0; j < result.cols; ++j) {
818 (void)lmmc_std_compare_eval(a->data[i * a->stride + j],
819 op, b->data[i * b->stride + j],
820 &result.data[i * result.stride + j]);
821 }
822 }
823 *out = result;
824 return LMMC_STATUS_OK;
825}
826
829 lmmc_real_t scalar,
831{
832 lmmc_status_t status;
833 lmmc_std_bool_mat_t result = {0};
834 uint8_t ignored;
835 if (!lmmc_std_bool_mat_is_empty(out)) { return LMMC_STATUS_INVALID_ARGUMENT; }
836 status = lmmc_std_require_finite_mat(a);
837 if (status != LMMC_STATUS_OK) { return status; }
838 if (!lmmc_std_real_is_finite(scalar)) {
840 }
841 if (!lmmc_std_compare_eval(0, op, 0, &ignored)) {
843 }
844 status = lmmc_std_bool_mat_create(a->rows, a->cols, &result);
845 if (status != LMMC_STATUS_OK) { return status; }
846 for (size_t i = 0; i < result.rows; ++i) {
847 for (size_t j = 0; j < result.cols; ++j) {
848 (void)lmmc_std_compare_eval(a->data[i * a->stride + j],
849 op, scalar,
850 &result.data[i * result.stride + j]);
851 }
852 }
853 *out = result;
854 return LMMC_STATUS_OK;
855}
856
double lmmc_real_t
Public and internal LMMC real type.
lmmc_status_t lmmc_mat_scale(lmmc_mat_t *a, lmmc_real_t alpha)
就地矩阵标量乘: 。
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_axpy(lmmc_real_t alpha, const lmmc_vec_t *x, lmmc_vec_t *y)
向量 AXPY 运算: 。
lmmc_status_t lmmc_vec_scale(lmmc_vec_t *x, lmmc_real_t alpha)
就地向量缩放: 。
lmmc_status_t lmmc_mat_mul(const lmmc_mat_t *a, const lmmc_mat_t *b, lmmc_mat_t *c)
计算矩阵乘积:c = a * b。
lmmc_status_t lmmc_mat_create(size_t rows, size_t cols, lmmc_mat_t *out_mat)
创建 rows x cols 的零矩阵。
lmmc_status_t lmmc_vec_create(size_t size, lmmc_vec_t *out_vec)
创建长度为 size 的零向量。
lmmc_status_t lmmc_mat_identity(size_t n, lmmc_mat_t *out_mat)
创建 nxn 单位矩阵,对角线为 1,其余元素为 0。
void lmmc_mat_destroy(lmmc_mat_t *mat)
销毁矩阵,释放其拥有的缓冲区并清零结构体字段。
void lmmc_vec_destroy(lmmc_vec_t *vec)
销毁向量,释放其拥有的缓冲区并清零字段。
lmmc_real_t * data
lmmc_real_t * data
行优先存储的稠密矩阵。
一维稠密向量。
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_OK
@ LMMC_STATUS_NUMERICAL_FAILURE
@ LMMC_STATUS_DIMENSION_MISMATCH
@ LMMC_STATUS_INVALID_ARGUMENT
lmmc_status_t lmmc_std_linalg_mat_add(const lmmc_mat_t *a, const lmmc_mat_t *b, lmmc_mat_t *out)
lmmc_status_t lmmc_std_linalg_mat_sub_scalar(const lmmc_mat_t *a, lmmc_real_t scalar, lmmc_mat_t *out)
lmmc_status_t lmmc_std_linalg_mat_div_scalar(const lmmc_mat_t *a, lmmc_real_t scalar, lmmc_mat_t *out)
lmmc_status_t lmmc_std_linalg_mat_scale(const lmmc_mat_t *a, lmmc_real_t alpha, lmmc_mat_t *out)
lmmc_status_t lmmc_std_linalg_mat_compare_scalar(const lmmc_mat_t *a, lmmc_std_compare_op_t op, lmmc_real_t scalar, lmmc_std_bool_mat_t *out)
lmmc_status_t lmmc_std_linalg_mat_mul_scalar(const lmmc_mat_t *a, lmmc_real_t scalar, lmmc_mat_t *out)
lmmc_status_t lmmc_std_linalg_scalar_div_mat(lmmc_real_t scalar, const lmmc_mat_t *a, lmmc_mat_t *out)
lmmc_status_t lmmc_std_linalg_inv(const lmmc_mat_t *a, lmmc_mat_t *out)
lmmc_status_t lmmc_std_linalg_scalar_sub_vec(lmmc_real_t scalar, const lmmc_vec_t *x, lmmc_vec_t *out)
lmmc_status_t lmmc_std_linalg_mat_add_scalar(const lmmc_mat_t *a, lmmc_real_t scalar, lmmc_mat_t *out)
lmmc_status_t lmmc_std_linalg_scalar_div_vec(lmmc_real_t scalar, const lmmc_vec_t *x, lmmc_vec_t *out)
lmmc_status_t lmmc_std_linalg_vec_scale(const lmmc_vec_t *x, lmmc_real_t alpha, lmmc_vec_t *out)
lmmc_status_t lmmc_std_linalg_mat_compare(const lmmc_mat_t *a, const lmmc_mat_t *b, lmmc_std_compare_op_t op, lmmc_std_bool_mat_t *out)
lmmc_status_t lmmc_std_linalg_vec_pow_scalar(const lmmc_vec_t *base, lmmc_real_t exponent, lmmc_vec_t *out)
lmmc_status_t lmmc_std_linalg_vec_pow(const lmmc_vec_t *base, const lmmc_vec_t *exponent, lmmc_vec_t *out)
lmmc_status_t lmmc_std_linalg_mat_pow_int(const lmmc_mat_t *base, int64_t exponent, lmmc_mat_t *out)
lmmc_status_t lmmc_std_linalg_vec_sub(const lmmc_vec_t *a, const lmmc_vec_t *b, lmmc_vec_t *out)
lmmc_status_t lmmc_std_linalg_mat_pow_elem(const lmmc_mat_t *base, const lmmc_mat_t *exponent, lmmc_mat_t *out)
lmmc_status_t lmmc_std_linalg_vec_mul_scalar(const lmmc_vec_t *x, lmmc_real_t scalar, lmmc_vec_t *out)
lmmc_status_t lmmc_std_linalg_mat_mul_elem(const lmmc_mat_t *a, const lmmc_mat_t *b, lmmc_mat_t *out)
lmmc_status_t lmmc_std_linalg_vec_div_scalar(const lmmc_vec_t *x, lmmc_real_t scalar, lmmc_vec_t *out)
lmmc_status_t lmmc_std_linalg_mat_div(const lmmc_mat_t *a, const lmmc_mat_t *b, lmmc_mat_t *out)
lmmc_status_t lmmc_std_linalg_vec_sub_scalar(const lmmc_vec_t *x, lmmc_real_t scalar, lmmc_vec_t *out)
lmmc_status_t lmmc_std_linalg_vec_mul(const lmmc_vec_t *a, const lmmc_vec_t *b, lmmc_vec_t *out)
lmmc_status_t lmmc_std_linalg_scalar_sub_mat(lmmc_real_t scalar, const lmmc_mat_t *a, lmmc_mat_t *out)
lmmc_status_t lmmc_std_linalg_vec_compare(const lmmc_vec_t *a, const lmmc_vec_t *b, lmmc_std_compare_op_t op, lmmc_std_bool_vec_t *out)
lmmc_status_t lmmc_std_linalg_vec_div(const lmmc_vec_t *a, const lmmc_vec_t *b, lmmc_vec_t *out)
lmmc_status_t lmmc_std_linalg_vec_compare_scalar(const lmmc_vec_t *a, lmmc_std_compare_op_t op, lmmc_real_t scalar, lmmc_std_bool_vec_t *out)
lmmc_status_t lmmc_std_linalg_vec_add_scalar(const lmmc_vec_t *x, lmmc_real_t scalar, lmmc_vec_t *out)
lmmc_status_t lmmc_std_linalg_mat_sub(const lmmc_mat_t *a, const lmmc_mat_t *b, lmmc_mat_t *out)
lmmc_status_t lmmc_std_linalg_vec_add(const lmmc_vec_t *a, const lmmc_vec_t *b, lmmc_vec_t *out)
lmmc_status_t lmmc_std_linalg_mat_pow_scalar(const lmmc_mat_t *base, lmmc_real_t exponent, lmmc_mat_t *out)
lmmc_std_compare_op_t