14 size_t i = 0, j = 0, nz = 0;
16 if (dense == NULL || out_sparse == NULL || dense->
data == NULL) {
30 for (i = 0; i < dense->
rows; ++i) {
31 for (j = 0; j < dense->
cols; ++j) {
46 for (i = 0; i < dense->
rows; ++i) {
47 for (j = 0; j < dense->
cols; ++j) {
56 out_sparse->
row_ptr[i + 1] = nz;
84 for (i = 0; i < sparse->
rows; ++i) {
85 for (p = sparse->
row_ptr[i]; p < sparse->row_ptr[i + 1]; ++p) {
90 for (i = 0; i < sparse->
cols; ++i) {
91 for (p = sparse->
row_ptr[i]; p < sparse->row_ptr[i + 1]; ++p) {
109 st = lmmc_sparse_create(sparse->
cols, sparse->
rows, sparse->
nnz, sparse->
format, out_transposed);
117 for (p = 0; p < sparse->
nnz; ++p) {
121 for (i = 0; i < inner_size_src; ++i) {
125 if (out_transposed->
nnz == 0) {
134 memcpy(next, out_transposed->
row_ptr, inner_size_src *
sizeof(
size_t));
136 for (i = 0; i < outer_size_src; ++i) {
137 for (p = sparse->
row_ptr[i]; p < sparse->row_ptr[i + 1]; ++p) {
138 size_t inner = sparse->
col_idx[p];
139 size_t dst = next[inner]++;
140 out_transposed->
col_idx[dst] = i;
149 if (src == NULL || dst == NULL) {
165 for (
size_t k = 0; k < src->
nnz; ++k) {
177 for (
size_t p = 0; p < src->
nnz; ++p) {
180 for (
size_t i = 0; i < src->
cols; ++i) {
189 memcpy(next, dst->
row_ptr, src->
cols *
sizeof(
size_t));
191 for (
size_t i = 0; i < src->
rows; ++i) {
192 for (
size_t p = src->
row_ptr[i]; p < src->row_ptr[i + 1]; ++p) {
194 size_t dest_idx = next[col]++;
204 if (src == NULL || dst == NULL) {
220 for (
size_t k = 0; k < src->
nnz; ++k) {
232 for (
size_t p = 0; p < src->
nnz; ++p) {
235 for (
size_t i = 0; i < src->
rows; ++i) {
244 memcpy(next, dst->
row_ptr, src->
rows *
sizeof(
size_t));
246 for (
size_t i = 0; i < src->
cols; ++i) {
247 for (
size_t p = src->
row_ptr[i]; p < src->row_ptr[i + 1]; ++p) {
249 size_t dest_idx = next[row]++;
263static int lmmc_coo_cmp_row_col(
const void* a,
const void* b) {
267 return (ea->
row < eb->
row) ? -1 : 1;
270 return (ea->
col < eb->
col) ? -1 : 1;
276static int lmmc_coo_cmp_col_row(
const void* a,
const void* b) {
280 return (ea->
col < eb->
col) ? -1 : 1;
283 return (ea->
row < eb->
row) ? -1 : 1;
288static void lmmc_coo_compressed_offsets(
290 int column_major,
size_t* row_ptr)
292 size_t prev_row = entries[0].
row;
293 size_t prev_col = entries[0].
col;
294 memset(row_ptr, 0, (outer_size + 1) *
sizeof(
size_t));
295 row_ptr[(column_major ? prev_col : prev_row) + 1]++;
296 for (
size_t i = 1; i < nnz; ++i) {
297 if (entries[i].row != prev_row || entries[i].col != prev_col) {
298 row_ptr[(column_major ? entries[i].
col : entries[i].
row) + 1]++;
299 prev_row = entries[i].
row;
300 prev_col = entries[i].
col;
303 for (
size_t i = 0; i < outer_size; ++i) {
304 row_ptr[i + 1] += row_ptr[i];
308static void lmmc_coo_compressed_values(
314 size_t cur_row = entries[0].
row;
315 size_t cur_col = entries[0].
col;
317 for (
size_t i = 1; i < coo->
nnz; ++i) {
318 if (entries[i].row == cur_row && entries[i].col == cur_col) {
322 out->
col_idx[index] = column_major ? cur_row : cur_col;
325 cur_row = entries[i].
row;
326 cur_col = entries[i].
col;
330 out->
col_idx[index] = column_major ? cur_row : cur_col;
336 if (coo == NULL || coo->
rows == 0 || coo->
cols == 0 ||
341 for (
size_t i = 0; i < coo->
nnz; ++i) {
354 size_t unique_nnz = 0;
358 if (out_csr == NULL || lmmc_sparse_coo_validate(coo) !=
LMMC_STATUS_OK) {
369 if (entries == NULL) {
373 for (i = 0; i < coo->
nnz; ++i) {
384 for (i = 1; i < coo->
nnz; ++i) {
385 if (entries[i].row != entries[i - 1].row || entries[i].col != entries[i - 1].col) {
403 lmmc_coo_compressed_offsets(entries, coo->
nnz, coo->
rows, 0, out_csr->
row_ptr);
404 lmmc_coo_compressed_values(coo, entries, 0, out_csr, &sum, &tmp);
419 size_t unique_nnz = 0;
423 if (out_csc == NULL || lmmc_sparse_coo_validate(coo) !=
LMMC_STATUS_OK) {
434 if (entries == NULL) {
438 for (i = 0; i < coo->
nnz; ++i) {
449 for (i = 1; i < coo->
nnz; ++i) {
450 if (entries[i].row != entries[i - 1].row || entries[i].col != entries[i - 1].col) {
467 lmmc_coo_compressed_values(coo, entries, 1, out_csc, &sum, &tmp);
468 lmmc_coo_compressed_offsets(entries, coo->
nnz, coo->
cols, 1, out_csc->
row_ptr);
482 if (coo->
values != NULL) {
483 for (
size_t k = 0; k < coo->
capacity; ++k) {
#define LMMC_REAL_CLEAR(x)
释放一个 lmmc_real_t 变量(POD 类型为空操作)。
#define LMMC_REAL_INIT(x)
初始化一个 lmmc_real_t 变量(POD 类型为空操作)。
#define LMMC_REAL_ADD(res, a, b)
计算 *res = *a + *b 。
double lmmc_real_t
Public and internal LMMC real type.
#define LMMC_REAL_SET(dst, src)
将一个 lmmc_real_t 赋值到另一个:*dst = *src 。
#define LMMC_REAL_ABS(res, a)
计算绝对值,*res = |*a| 。
#define LMMC_REAL_CMP(a, b)
比较 *a 与 *b ,返回 -1/0/1 。
#define LMMC_REAL_SET_D(dst, dbl)
将一个 double 字面量赋值到 lmmc_real_t 。
lmmc_status_t lmmc_mat_fill(lmmc_mat_t *mat, lmmc_real_t value)
就地将矩阵所有元素设为 value。
void * lmmc_memory_alloc_array(size_t count, size_t element_size)
void lmmc_memory_free(void *pointer)
Private recoverable allocator for persistent LMMC ownership.
lmmc_status_t lmmc_sparse_create_csc(size_t rows, size_t cols, size_t nnz, lmmc_sparse_mat_t *out_sparse)
为指定 nnz 的 CSC 矩阵分配数组。
lmmc_status_t lmmc_sparse_transpose(const lmmc_sparse_mat_t *sparse, lmmc_sparse_mat_t *out_transposed)
计算稀疏矩阵转置,保持原存储格式。
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,输...
lmmc_status_t lmmc_sparse_to_csc(const lmmc_sparse_mat_t *src, lmmc_sparse_mat_t *dst)
转换为 CSC,src 已为 CSC 时执行深拷贝。
lmmc_status_t lmmc_sparse_to_csr(const lmmc_sparse_mat_t *src, lmmc_sparse_mat_t *dst)
转换为 CSR,src 已为 CSR 时执行深拷贝。
void lmmc_sparse_destroy(lmmc_sparse_mat_t *sparse)
销毁稀疏矩阵,释放其拥有的缓冲区并清零全部字段。
lmmc_status_t lmmc_sparse_create_csr(size_t rows, size_t cols, size_t nnz, lmmc_sparse_mat_t *out_sparse)
为指定 nnz 的 CSR 矩阵分配数组。
lmmc_status_t lmmc_sparse_to_dense(const lmmc_sparse_mat_t *sparse, lmmc_mat_t *out_dense)
将稀疏矩阵展开为稠密矩阵,缺失项填零。
lmmc_status_t lmmc_sparse_coo_to_csc(const lmmc_sparse_coo_t *coo, lmmc_sparse_mat_t *out_csc)
将 COO 转换为 CSC,校验、稳定合并与显式零语义同 COO→CSR。
void lmmc_sparse_coo_destroy(lmmc_sparse_coo_t *coo)
销毁 COO 矩阵并释放缓冲区。
lmmc_status_t lmmc_sparse_from_dense(const lmmc_mat_t *dense, lmmc_real_t eps, lmmc_sparse_mat_t *out_sparse)
由稠密矩阵生成 CSR,丢弃绝对值 <= eps 的元素。
lmmc_sparse_format_t format
通用稀疏矩阵(CSR / CSC 共用同一结构)。
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_DIMENSION_MISMATCH
@ LMMC_STATUS_ALLOCATION_FAILED
@ LMMC_STATUS_INVALID_ARGUMENT