15 for (
size_t i = 0; i < sigma->
size; ++i) {
16 sigma->
data[i] *= scale;
17 if (!isfinite(sigma->
data[i])) {
44 for (
size_t i = 0; i < source->
sigma.
size; ++i) {
67 status = restore_singular_value_scale(&temporary.
sigma, scale);
69 status = transpose_factors(&temporary, result);
78 if (!lmmc_mat_descriptor_is_valid(a) || !out_result) {
89 status = restore_singular_value_scale(&result.
sigma, scale);
92 status = svd_wide(a, scale, &result);
102static int matrix_is_finite(
const lmmc_mat_t *matrix)
104 for (
size_t i = 0; i < matrix->
rows; ++i) {
105 for (
size_t j = 0; j < matrix->
cols; ++j) {
106 if (!isfinite(
MAT_ELEM(matrix, i, j))) {
118 if (!matrix_is_finite(&svd->
U) || !matrix_is_finite(&svd->
Vt)) {
121 const size_t m = svd->
U.
rows;
122 const size_t n = svd->
Vt.
rows;
127 if (!isfinite(tol)) {
130 for (
size_t k = 0; k < svd->
sigma.
size; ++k) {
132 if (!isfinite(singular) || singular < 0.0) {
135 lmmc_real_t reciprocal = (singular > tol) ? 1.0 / singular : 0.0;
136 if (!isfinite(reciprocal)) {
148 for (
size_t k = 0; k < svd->
sigma.
size; ++k) {
150 if (reciprocal == 0.0) {
154 if (!isfinite(product)) {
157 product *= reciprocal;
158 if (!isfinite(product)) {
162 if (!isfinite(sum)) {
173 for (
size_t i = 0; i < candidate->
rows; ++i) {
174 for (
size_t j = 0; j < candidate->
cols; ++j) {
188 if (!a || !out_pinv || !a->
data || !out_pinv->
data) {
197 if (!lmmc_mat_descriptor_is_valid(a) || !lmmc_mat_descriptor_is_valid(out_pinv)) {
215 status = prepare_reciprocals(&svd, tol);
223 status = reconstruct_pinv(&svd, &candidate);
225 for (
size_t i = 0; i < candidate.
rows; ++i) {
228 candidate.
cols *
sizeof(*candidate.
data));
239 if (!a || !out_cond || !a->
data) {
257 *out_cond = (s_min <= 0.0) ? INFINITY : s_max / s_min;
double lmmc_real_t
Public and internal LMMC real type.
#define LMMC_REAL_EPSILON
既有算法的经验近似阈值,非机器 epsilon。
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_transpose_to(const lmmc_mat_t *src, lmmc_mat_t *dst)
计算矩阵转置:dst = src^T。
lmmc_status_t lmmc_vec_create(size_t size, lmmc_vec_t *out_vec)
创建长度为 size 的零向量。
void lmmc_mat_destroy(lmmc_mat_t *mat)
销毁矩阵,释放其拥有的缓冲区并清零结构体字段。
void lmmc_vec_destroy(lmmc_vec_t *vec)
销毁向量,释放其拥有的缓冲区并清零字段。
lmmc_status_t lmmc_svd(const lmmc_mat_t *a, lmmc_svd_result_t *out_result)
计算奇异值分解:A = U * Σ * V^T.
lmmc_status_t lmmc_pinv(const lmmc_mat_t *a, lmmc_real_t tol, lmmc_mat_t *out_pinv)
计算 Moore-Penrose 伪逆 A^+。
lmmc_status_t lmmc_cond(const lmmc_mat_t *a, lmmc_real_t *out_cond)
计算矩阵的 2-范数条件数:κ_2(A) = sigma_max / sigma_min.
void lmmc_svd_result_destroy(lmmc_svd_result_t *result)
释放 lmmc_svd 输出结果.
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_status_t lmmc_svd_tall(const lmmc_mat_t *a, lmmc_real_t input_scale, lmmc_svd_result_t *result)
稠密矩阵直接分解接口(LU、Cholesky、QR)。
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_NUMERICAL_FAILURE
@ LMMC_STATUS_DIMENSION_MISMATCH
@ LMMC_STATUS_INVALID_ARGUMENT