LMMC
Lamina Mathematic core
载入中...
搜索中...
未找到
eigen_internal.c
浏览该文件的文档.
1
5
6#include <math.h>
7#include <string.h>
8#include "memory_bridge.h"
9#include "internal.h"
10#include "eigen_internal.h"
11#include "lmmc/config.h"
12#include "lmmc/dense.h"
13#include "lmmc/eigen.h"
14#include "lmmc/linear_algebra.h"
15
17 lmmc_real_t* scale)
18{
19 *scale = 0.0;
20 for (size_t i = 0; i < a->rows; ++i) {
21 for (size_t j = 0; j < a->cols; ++j) {
22 lmmc_real_t magnitude = fabs(MAT_ELEM(a, i, j));
23 if (!isfinite(magnitude)) {
25 }
26 if (magnitude > *scale) {
27 *scale = magnitude;
28 }
29 }
30 }
31 if (*scale == 0.0) {
32 *scale = 1.0;
33 }
34 return LMMC_STATUS_OK;
35}
36
37void householder_make(lmmc_real_t *x, size_t len, lmmc_real_t *tau_out,
38 lmmc_real_t *beta_out) {
40 lmmc_real_t alpha;
41 lmmc_real_t tail_norm;
42 lmmc_real_t norm;
43 lmmc_real_t beta;
44 lmmc_real_t denominator_scaled;
45
46 if (len == 0) { *tau_out = 0.0; *beta_out = 0.0; return; }
47 if (len == 1) { *tau_out = 0.0; *beta_out = x[0]; return; }
48
49 lmmc_scaled_sumsq_init(&acc);
50 for (size_t i = 1; i < len; ++i) {
51 lmmc_scaled_sumsq_add(&acc, x[i]);
52 }
53 tail_norm = lmmc_scaled_sumsq_norm(&acc);
54 alpha = x[0];
55 if (tail_norm == 0.0) {
56 *tau_out = 0.0;
57 *beta_out = alpha;
58 return;
59 }
60
61 norm = hypot(alpha, tail_norm);
62 beta = -copysign(norm, alpha);
63 *beta_out = beta;
64 *tau_out = 1.0 - alpha / beta;
65 denominator_scaled = alpha / norm - beta / norm;
66 for (size_t i = 1; i < len; ++i) {
67 x[i] = (x[i] / norm) / denominator_scaled;
68 }
69 x[0] = 1.0;
70}
71
72void householder_apply_left(lmmc_mat_t *M, size_t i0, size_t len,
73 size_t j0, size_t j1,
74 const lmmc_real_t *v, lmmc_real_t tau) {
75 size_t i, j;
76 if (tau == 0.0) return;
77 for (j = j0; j < j1; j++) {
78 lmmc_real_t s = MAT_ELEM(M, i0, j);
79 for (i = 1; i < len; i++) s += v[i] * MAT_ELEM(M, i0 + i, j);
80 s *= tau;
81 MAT_ELEM(M, i0, j) -= s;
82 for (i = 1; i < len; i++) MAT_ELEM(M, i0 + i, j) -= s * v[i];
83 }
84}
85
86void householder_apply_right(lmmc_mat_t *M, size_t i0, size_t i1,
87 size_t j0, size_t len,
88 const lmmc_real_t *v, lmmc_real_t tau) {
89 size_t i, j;
90 if (tau == 0.0) return;
91 for (i = i0; i < i1; i++) {
92 lmmc_real_t s = MAT_ELEM(M, i, j0);
93 for (j = 1; j < len; j++) s += v[j] * MAT_ELEM(M, i, j0 + j);
94 s *= tau;
95 MAT_ELEM(M, i, j0) -= s;
96 for (j = 1; j < len; j++) MAT_ELEM(M, i, j0 + j) -= s * v[j];
97 }
98}
99
100void givens_right(lmmc_mat_t *M, size_t rows, size_t p, size_t q,
102 size_t i;
103 for (i = 0; i < rows; i++) {
104 lmmc_real_t mp = MAT_ELEM(M, i, p);
105 lmmc_real_t mq = MAT_ELEM(M, i, q);
106 MAT_ELEM(M, i, p) = c * mp + s * mq;
107 MAT_ELEM(M, i, q) = -s * mp + c * mq;
108 }
109}
110
113 if (b == 0.0) { *c = (a >= 0.0) ? 1.0 : -1.0; *s = 0.0; *r = lmmc_abs(a); }
114 else if (a == 0.0) { *c = 0.0; *s = (b >= 0.0) ? 1.0 : -1.0; *r = lmmc_abs(b); }
115 else {
116 lmmc_real_t h = hypot(a, b);
117 *r = h;
118 *c = a / h;
119 *s = b / h;
120 }
121}
122
LMMC binary real type and arithmetic spelling.
double lmmc_real_t
Public and internal LMMC real type.
行优先存储的稠密矩阵。
特征值 / 奇异值分解,伪逆与条件数接口.
void givens_right(lmmc_mat_t *M, size_t rows, size_t p, size_t q, lmmc_real_t c, lmmc_real_t s)
void householder_apply_left(lmmc_mat_t *M, size_t i0, size_t len, size_t j0, size_t j1, const lmmc_real_t *v, lmmc_real_t tau)
void householder_make(lmmc_real_t *x, size_t len, lmmc_real_t *tau_out, lmmc_real_t *beta_out)
void givens_compute(lmmc_real_t a, lmmc_real_t b, lmmc_real_t *c, lmmc_real_t *s, lmmc_real_t *r)
void householder_apply_right(lmmc_mat_t *M, size_t i0, size_t i1, size_t j0, size_t len, const lmmc_real_t *v, lmmc_real_t tau)
lmmc_status_t lmmc_eigen_matrix_scale(const lmmc_mat_t *a, lmmc_real_t *scale)
特征值 / SVD 模块内部共享的缩放、Householder 与 Givens 辅助接口(仅源文件可见)。
#define MAT_ELEM(mat, i, j)
LMMC 内部使用的公共工具(仅源文件可见).
稠密矩阵直接分解接口(LU、Cholesky、QR)。
Private recoverable allocator for persistent LMMC ownership.
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_OK
@ LMMC_STATUS_NUMERICAL_FAILURE