18 memset(chol->
L_col_ptr, 0, (n + 1) *
sizeof(
size_t));
25 size_t initial_capacity = (nnz > 64) ? nnz : 64;
26 if (initial_capacity < n) {
45 int csc_needs_free = 0;
49 if (a == NULL || out_chol == NULL) {
75status = chol_allocate_indices(chol);
82 for (
size_t i = 0; i < n; ++i) chol->
perm_inv[chol->
perm[i]] = i;
83 status = chol_allocate_factors(chol, a->
nnz);
104 size_t orig_col = chol->
perm[j];
106 size_t col_start = csc->
row_ptr[orig_col];
107 size_t col_end = csc->
row_ptr[orig_col + 1];
108 for (
size_t p = col_start; p < col_end; p++) {
109 size_t orig_row = csc->
col_idx[p];
110 size_t perm_row = chol->
perm_inv[orig_row];
112 col_dense[perm_row] += csc->
values[p];
118 size_t column,
size_t row)
120 for (
size_t p = chol->
L_col_ptr[column]; p < chol->L_col_ptr[column + 1]; ++p) {
122 if (current == row) {
136 for (
size_t k = 0; k < j; k++) {
145 for (
size_t p = L_start; p < L_end; p++) {
148 col_dense[i] -= chol->
L_values[p] * Ljk;
167 sqrt_diag = sqrt(diag);
178 for (
size_t i = j + 1; i < n; i++) {
179 if (col_dense[i] != 0.0) {
198 int csc_needs_free = 0;
203 if (a == NULL || chol == NULL) {
209 if (a->
rows != chol->
n) {
221 if (col_dense == NULL) {
222 if (csc_needs_free) {
231for (
size_t j = 0; j < n; j++) {
233 chol_scatter_column(&csc, chol, j, col_dense);
234 chol_update_column(chol, j, col_dense);
235 status = chol_store_column(chol, j, col_dense);
246 if (csc_needs_free) {
257 for (
size_t j = 0; j < n; j++) {
261 size_t diag_idx = (size_t)-1;
263 for (
size_t p = L_start; p < L_end; p++) {
274 work[j] = work[j] / diag;
276 for (
size_t p = L_start; p < L_end; p++) {
281 work[i] -= chol->
L_values[p] * work[j];
292 for (
size_t jj = 0; jj < n; jj++) {
293 size_t j = n - 1 - jj;
297 size_t diag_idx = (size_t)-1;
299 for (
size_t p = L_start; p < L_end; p++) {
310 for (
size_t p = L_start; p < L_end; p++) {
315 work[j] -= chol->
L_values[p] * work[i];
317 work[j] = work[j] / diag;
335 if (chol == NULL || b == NULL || x == NULL) {
338 if (b->
data == NULL || x->
data == NULL) {
353 for (
size_t i = 0; i < n; i++) {
359 status = chol_backward_solve(chol, work);
367 for (
size_t k = 0; k < n; k++) {
double lmmc_real_t
Public and internal LMMC real type.
void * lmmc_memory_alloc_array(size_t count, size_t element_size)
void * lmmc_memory_alloc(size_t size)
void * lmmc_memory_alloc_array_plus(size_t count, size_t extra, size_t element_size)
void lmmc_memory_free(void *pointer)
Private recoverable allocator for persistent LMMC ownership.
lmmc_status_t lmmc_sparse_factor_capacity(size_t **idx, lmmc_real_t **vals, size_t *capacity, size_t needed)
lmmc_status_t lmmc_sparse_direct_csc(const lmmc_sparse_mat_t *a, lmmc_sparse_mat_t *csc_out, int *needs_free)
lmmc_status_t lmmc_sparse_residual_reorder(const lmmc_sparse_mat_t *csc, size_t *perm)
稀疏 Cholesky 分解上下文(不透明类型,要求 A 对称正定)。
lmmc_status_t lmmc_sparse_chol_numeric(const lmmc_sparse_mat_t *a, lmmc_sparse_chol_t *chol)
使用稠密列工作区的左看稀疏 Cholesky 数值分解。
void lmmc_sparse_chol_destroy(lmmc_sparse_chol_t *chol)
销毁稀疏 Cholesky 上下文。
lmmc_status_t lmmc_sparse_chol_solve(const lmmc_sparse_chol_t *chol, const lmmc_vec_t *b, lmmc_vec_t *x)
使用已分解的 Cholesky 因子求解 A*x = b。
lmmc_status_t lmmc_sparse_chol_symbolic(const lmmc_sparse_mat_t *a, lmmc_sparse_chol_t **out_chol)
稀疏 Cholesky 符号分析:去重简单图和贪心残余度重排序。
void lmmc_sparse_destroy(lmmc_sparse_mat_t *sparse)
销毁稀疏矩阵,释放其拥有的缓冲区并清零全部字段。
通用稀疏矩阵(CSR / CSC 共用同一结构)。
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_NOT_POSITIVE_DEFINITE
@ LMMC_STATUS_DIMENSION_MISMATCH
@ LMMC_STATUS_ALLOCATION_FAILED
@ LMMC_STATUS_INVALID_ARGUMENT