LMMC
Lamina Mathematic core
载入中...
搜索中...
未找到
sparse_builder.c
浏览该文件的文档.
1
5#include <string.h>
6
7#include "memory_bridge.h"
8#include "internal.h"
9#include "sparse_internal.h"
10#include "lmmc/sparse.h"
11
13 size_t rows;
14 size_t cols;
15 size_t nnz;
16 size_t capacity;
17 size_t* r_idx;
18 size_t* c_idx;
20};
21
22static lmmc_status_t lmmc_sparse_entries_grow(
23 size_t nnz, size_t* capacity, size_t** rows, size_t** cols,
24 lmmc_real_t** values)
25{
26 size_t new_cap = 0;
27 size_t sz_idx = 0;
28 size_t sz_vals = 0;
29 size_t* nr = NULL;
30 size_t* nc = NULL;
31 lmmc_real_t* nv = NULL;
32
33 if (!lmmc_safe_mul_size(*capacity, 2, &new_cap) ||
34 !lmmc_safe_mul_size(new_cap, sizeof(size_t), &sz_idx) ||
35 !lmmc_safe_mul_size(new_cap, sizeof(lmmc_real_t), &sz_vals)) {
37 }
38
39 nr = (size_t*)lmmc_memory_alloc(sz_idx);
40 nc = (size_t*)lmmc_memory_alloc(sz_idx);
41 nv = (lmmc_real_t*)lmmc_memory_alloc(sz_vals);
42
43 if (nr == NULL || nc == NULL || nv == NULL) {
44 if (nr) {
46 }
47 if (nc) {
49 }
50 if (nv) {
52 }
54 }
55
56 for (size_t k = 0; k < new_cap; ++k) {
57 LMMC_REAL_INIT(&nv[k]);
58 }
59
60 if (nnz > 0) {
61 memcpy(nr, *rows, nnz * sizeof(size_t));
62 memcpy(nc, *cols, nnz * sizeof(size_t));
63 for (size_t k = 0; k < nnz; ++k) {
64 LMMC_REAL_SET(&nv[k], &(*values)[k]);
65 }
66 }
67
68 for (size_t k = 0; k < *capacity; ++k) {
69 LMMC_REAL_CLEAR(&(*values)[k]);
70 }
71 lmmc_memory_free(*rows);
72 lmmc_memory_free(*cols);
73 lmmc_memory_free(*values);
74
75 *rows = nr;
76 *cols = nc;
77 *values = nv;
78 *capacity = new_cap;
79 return LMMC_STATUS_OK;
80}
81
82
83lmmc_status_t lmmc_sparse_builder_create(size_t rows, size_t cols, size_t initial_capacity, lmmc_sparse_builder_t** out_builder) {
84 lmmc_sparse_builder_t* b = NULL;
85 if (out_builder == NULL || rows == 0 || cols == 0) {
87 }
88
90 if (b == NULL) {
92 }
93
94 b->rows = rows;
95 b->cols = cols;
96 b->nnz = 0;
97 b->capacity = initial_capacity > 0 ? initial_capacity : 16;
98
99 size_t sz_idx = 0;
100 size_t sz_vals = 0;
101 if (!lmmc_safe_mul_size(b->capacity, sizeof(size_t), &sz_idx) ||
102 !lmmc_safe_mul_size(b->capacity, sizeof(lmmc_real_t), &sz_vals)) {
105 }
106
107 b->r_idx = (size_t*)lmmc_memory_alloc(sz_idx);
108 b->c_idx = (size_t*)lmmc_memory_alloc(sz_idx);
109 b->vals = (lmmc_real_t*)lmmc_memory_alloc(sz_vals);
110
111 if (b->r_idx == NULL || b->c_idx == NULL || b->vals == NULL) {
114 }
115
116 for (size_t k = 0; k < b->capacity; ++k) {
117 LMMC_REAL_INIT(&b->vals[k]);
118 }
119
120 *out_builder = b;
121 return LMMC_STATUS_OK;
122}
123
125 if (b == NULL || row >= b->rows || col >= b->cols) {
127 }
128
129 if (b->nnz >= b->capacity) {
130 lmmc_status_t st = lmmc_sparse_entries_grow(
131 b->nnz, &b->capacity, &b->r_idx, &b->c_idx, &b->vals);
132 if (st != LMMC_STATUS_OK) {
133 return st;
134 }
135 }
136
137 b->r_idx[b->nnz] = row;
138 b->c_idx[b->nnz] = col;
139 LMMC_REAL_SET(&b->vals[b->nnz], &val);
140 b->nnz++;
141 return LMMC_STATUS_OK;
142}
143
145 if (b) {
146 if (b->r_idx) {
148 }
149 if (b->c_idx) {
151 }
152 if (b->vals) {
153 for (size_t k = 0; k < b->capacity; ++k) {
154 LMMC_REAL_CLEAR(&b->vals[k]);
155 }
157 }
159 }
160}
161
163 if (b == NULL || out == NULL ||
164 (format != LMMC_SPARSE_CSR && format != LMMC_SPARSE_CSC)) {
166 }
167 lmmc_sparse_coo_t coo = {0};
168 coo.rows = b->rows;
169 coo.cols = b->cols;
170 coo.nnz = b->nnz;
171 coo.capacity = b->capacity;
172 coo.row_idx = b->r_idx;
173 coo.col_idx = b->c_idx;
174 coo.values = b->vals;
175 return format == LMMC_SPARSE_CSR
176 ? lmmc_sparse_coo_to_csr(&coo, out)
177 : lmmc_sparse_coo_to_csc(&coo, out);
178}
179
180
182 size_t rows, size_t cols, size_t capacity,
183 lmmc_sparse_coo_t* out_coo
184) {
185 size_t sz_idx = 0;
186 size_t sz_vals = 0;
187 size_t actual_cap;
188
189 if (out_coo == NULL || rows == 0 || cols == 0) {
191 }
192
193 actual_cap = capacity > 0 ? capacity : 16;
194
195 if (!lmmc_safe_mul_size(actual_cap, sizeof(size_t), &sz_idx) ||
196 !lmmc_safe_mul_size(actual_cap, sizeof(lmmc_real_t), &sz_vals)) {
198 }
199
200 out_coo->row_idx = (size_t*)lmmc_memory_alloc(sz_idx);
201 out_coo->col_idx = (size_t*)lmmc_memory_alloc(sz_idx);
202 out_coo->values = (lmmc_real_t*)lmmc_memory_alloc(sz_vals);
203
204 if (out_coo->row_idx == NULL || out_coo->col_idx == NULL || out_coo->values == NULL) {
205 if (out_coo->row_idx) {
206 lmmc_memory_free(out_coo->row_idx);
207 }
208 if (out_coo->col_idx) {
209 lmmc_memory_free(out_coo->col_idx);
210 }
211 if (out_coo->values) {
212 lmmc_memory_free(out_coo->values);
213 }
214 out_coo->row_idx = NULL;
215 out_coo->col_idx = NULL;
216 out_coo->values = NULL;
218 }
219
220 for (size_t k = 0; k < actual_cap; ++k) {
221 LMMC_REAL_INIT(&out_coo->values[k]);
222 }
223
224 out_coo->rows = rows;
225 out_coo->cols = cols;
226 out_coo->nnz = 0;
227 out_coo->capacity = actual_cap;
228 return LMMC_STATUS_OK;
229}
230
233 size_t row, size_t col, lmmc_real_t value
234) {
235 if (coo == NULL) {
237 }
238 if (row >= coo->rows || col >= coo->cols) {
240 }
241
242
243 if (coo->nnz >= coo->capacity) {
244 lmmc_status_t st = lmmc_sparse_entries_grow(
245 coo->nnz, &coo->capacity, &coo->row_idx, &coo->col_idx, &coo->values);
246 if (st != LMMC_STATUS_OK) {
247 return st;
248 }
249 }
250
251 coo->row_idx[coo->nnz] = row;
252 coo->col_idx[coo->nnz] = col;
253 LMMC_REAL_SET(&coo->values[coo->nnz], &value);
254 coo->nnz++;
255 return LMMC_STATUS_OK;
256}
#define LMMC_REAL_CLEAR(x)
释放一个 lmmc_real_t 变量(POD 类型为空操作)。
#define LMMC_REAL_INIT(x)
初始化一个 lmmc_real_t 变量(POD 类型为空操作)。
double lmmc_real_t
Public and internal LMMC real type.
#define LMMC_REAL_SET(dst, src)
将一个 lmmc_real_t 赋值到另一个:*dst = *src 。
LMMC 内部使用的公共工具(仅源文件可见).
void * lmmc_memory_alloc(size_t size)
void lmmc_memory_free(void *pointer)
Private recoverable allocator for persistent LMMC ownership.
增量构造稀疏矩阵的辅助对象(不透明类型)。
稀疏矩阵模块内部共享辅助函数(仅源文件可见)。
lmmc_status_t lmmc_sparse_coo_add_entry(lmmc_sparse_coo_t *coo, size_t row, size_t col, lmmc_real_t value)
向 COO 追加一项非零元,达到容量时返回错误。
lmmc_status_t lmmc_sparse_builder_build(lmmc_sparse_builder_t *builder, lmmc_sparse_format_t format, lmmc_sparse_mat_t *out_sparse)
将构造器条目转换为指定压缩格式的稀疏矩阵。
lmmc_status_t lmmc_sparse_coo_to_csr(const lmmc_sparse_coo_t *coo, lmmc_sparse_mat_t *out_csr)
将 COO 排序为 CSR,重复坐标按插入顺序累加,保留显式零。 要求非零维度、nnz<=capacity、有效条目数组和范围内坐标。 输入保持不变;非法描述符返回 INVALID_ARGUMENT,输...
void lmmc_sparse_builder_destroy(lmmc_sparse_builder_t *builder)
销毁稀疏构造器,释放动态数组与句柄。
lmmc_status_t lmmc_sparse_builder_create(size_t rows, size_t cols, size_t initial_capacity, lmmc_sparse_builder_t **out_builder)
创建稀疏矩阵增量构造器。
lmmc_status_t lmmc_sparse_coo_create(size_t rows, size_t cols, size_t capacity, lmmc_sparse_coo_t *out_coo)
创建容量为 capacity 的空 COO 矩阵。
lmmc_status_t lmmc_sparse_builder_add(lmmc_sparse_builder_t *builder, size_t row, size_t col, lmmc_real_t value)
向构造器追加一项非零元。
lmmc_status_t lmmc_sparse_coo_to_csc(const lmmc_sparse_coo_t *coo, lmmc_sparse_mat_t *out_csc)
将 COO 转换为 CSC,校验、稳定合并与显式零语义同 COO→CSR。
lmmc_sparse_format_t
稀疏矩阵存储格式。
@ LMMC_SPARSE_CSR
@ LMMC_SPARSE_CSC
三元组 (COO) 形式的稀疏矩阵临时表示。
通用稀疏矩阵(CSR / CSC 共用同一结构)。
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_OK
@ LMMC_STATUS_ALLOCATION_FAILED
@ LMMC_STATUS_INVALID_ARGUMENT
@ LMMC_STATUS_INDEX_OUT_OF_BOUNDS