LMMC
Lamina Mathematic core
载入中...
搜索中...
未找到
dense_storage.c
浏览该文件的文档.
1
5
6#include <string.h>
7#include "memory_bridge.h"
8#include "internal.h"
9#include "lmmc/config.h"
10#include "lmmc/dense.h"
11#include "lmmc/linear_algebra.h"
12
13
14lmmc_status_t lmmc_mat_create(size_t rows, size_t cols, lmmc_mat_t* out_mat) {
15 size_t n_elem = 0;
16 size_t n_bytes = 0;
17 lmmc_real_t* data = NULL;
18
19 if (out_mat == NULL || rows == 0 || cols == 0) {
21 }
22 if (!lmmc_safe_mul_size(rows, cols, &n_elem) ||
23 !lmmc_safe_mul_size(n_elem, sizeof(lmmc_real_t), &n_bytes)) {
25 }
26
27 data = (lmmc_real_t*)lmmc_memory_alloc(n_bytes);
28 if (data == NULL) {
30 }
31 memset(data, 0, n_bytes);
32
33 for (size_t i = 0; i < rows * cols; ++i) {
34 LMMC_REAL_INIT(&data[i]);
35 }
36
37 out_mat->rows = rows;
38 out_mat->cols = cols;
39 out_mat->stride = cols;
40 out_mat->data = data;
41 out_mat->owns_data = 1;
42 return LMMC_STATUS_OK;
43}
44
45lmmc_status_t lmmc_mat_wrap(size_t rows, size_t cols, size_t stride, lmmc_real_t* data, lmmc_mat_t* out_mat) {
46 lmmc_mat_t candidate;
47 if (out_mat == NULL) {
49 }
50 candidate.rows = rows;
51 candidate.cols = cols;
52 candidate.stride = stride;
53 candidate.data = data;
54 candidate.owns_data = 0;
55 if (!lmmc_mat_descriptor_is_valid(&candidate)) {
57 }
58 *out_mat = candidate;
59 return LMMC_STATUS_OK;
60}
61
63 if (mat == NULL) {
64 return;
65 }
66 if (mat->owns_data && mat->data != NULL) {
67 for (size_t i = 0; i < mat->rows * mat->cols; ++i) {
68 LMMC_REAL_CLEAR(&mat->data[i]);
69 }
71 }
72 mat->rows = 0;
73 mat->cols = 0;
74 mat->stride = 0;
75 mat->data = NULL;
76 mat->owns_data = 0;
77}
78
80 size_t i = 0;
81 size_t j = 0;
82 if (!lmmc_mat_descriptor_is_valid(mat)) {
84 }
85 for (i = 0; i < mat->rows; ++i) {
86 for (j = 0; j < mat->cols; ++j) {
87 LMMC_REAL_SET(&mat->data[i * mat->stride + j], &value);
88 }
89 }
90 return LMMC_STATUS_OK;
91}
92
94 size_t i = 0;
95 size_t j = 0;
96 if (!lmmc_mat_descriptor_is_valid(src) ||
97 !lmmc_mat_descriptor_is_valid(dst)) {
99 }
100 if (src->rows != dst->rows || src->cols != dst->cols) {
102 }
103 for (i = 0; i < src->rows; ++i) {
104 for (j = 0; j < src->cols; ++j) {
105 LMMC_REAL_SET(&dst->data[i * dst->stride + j], &src->data[i * src->stride + j]);
106 }
107 }
108 return LMMC_STATUS_OK;
109}
110
112 size_t i = 0;
113 size_t j = 0;
114 if (!lmmc_mat_descriptor_is_valid(src) ||
115 !lmmc_mat_descriptor_is_valid(dst)) {
117 }
118 if (dst->rows != src->cols || dst->cols != src->rows) {
120 }
121 {
122 lmmc_storage_envelope_t src_envelope;
123 lmmc_storage_envelope_t dst_envelope;
124 if (!lmmc_storage_envelope_checked(src->data, src->rows, src->cols,
125 src->stride, sizeof(lmmc_real_t),
126 &src_envelope) ||
127 !lmmc_storage_envelope_checked(dst->data, dst->rows, dst->cols,
128 dst->stride, sizeof(lmmc_real_t),
129 &dst_envelope)) {
131 }
132 if (lmmc_storage_envelopes_overlap(&src_envelope, &dst_envelope)) {
134 }
135 }
136 for (i = 0; i < src->rows; ++i) {
137 for (j = 0; j < src->cols; ++j) {
138 LMMC_REAL_SET(&dst->data[j * dst->stride + i], &src->data[i * src->stride + j]);
139 }
140 }
141 return LMMC_STATUS_OK;
142}
143
145 size_t n_bytes = 0;
146 lmmc_real_t* data = NULL;
147 if (out_vec == NULL || size == 0) {
149 }
150 if (!lmmc_safe_mul_size(size, sizeof(lmmc_real_t), &n_bytes)) {
152 }
153 data = (lmmc_real_t*)lmmc_memory_alloc(n_bytes);
154 if (data == NULL) {
156 }
157 memset(data, 0, n_bytes);
158
159 for (size_t i = 0; i < size; ++i) {
160 LMMC_REAL_INIT(&data[i]);
161 }
162
163 out_vec->size = size;
164 out_vec->data = data;
165 out_vec->owns_data = 1;
166 return LMMC_STATUS_OK;
167}
168
169lmmc_status_t lmmc_vec_wrap(size_t size, lmmc_real_t* data, lmmc_vec_t* out_vec) {
170 lmmc_vec_t candidate;
171 if (out_vec == NULL) {
173 }
174 candidate.size = size;
175 candidate.data = data;
176 candidate.owns_data = 0;
177 if (!lmmc_vec_descriptor_is_valid(&candidate)) {
179 }
180 *out_vec = candidate;
181 return LMMC_STATUS_OK;
182}
183
185 if (vec == NULL) {
186 return;
187 }
188 if (vec->owns_data && vec->data != NULL) {
189 for (size_t i = 0; i < vec->size; ++i) {
190 LMMC_REAL_CLEAR(&vec->data[i]);
191 }
193 }
194 vec->size = 0;
195 vec->data = NULL;
196 vec->owns_data = 0;
197}
198
200 size_t i = 0;
201 if (!lmmc_vec_descriptor_is_valid(vec)) {
203 }
204 for (i = 0; i < vec->size; ++i) {
205 LMMC_REAL_SET(&vec->data[i], &value);
206 }
207 return LMMC_STATUS_OK;
208}
209
211 if (!lmmc_vec_descriptor_is_valid(src) ||
212 !lmmc_vec_descriptor_is_valid(dst)) {
214 }
215 if (src->size != dst->size) {
217 }
218
219 for (size_t i = 0; i < src->size; ++i) {
220 LMMC_REAL_SET(&dst->data[i], &src->data[i]);
221 }
222 return LMMC_STATUS_OK;
223}
224
226 if (!lmmc_vec_descriptor_is_valid(x) ||
227 !lmmc_vec_descriptor_is_valid(y)) {
229 }
230 if (x->size != y->size) {
232 }
233
234 for (size_t i = 0; i < x->size; ++i) {
235 lmmc_swap(&x->data[i], &y->data[i]);
236 }
237 return LMMC_STATUS_OK;
238}
239
LMMC binary real type and arithmetic spelling.
#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_status_t lmmc_mat_copy(const lmmc_mat_t *src, lmmc_mat_t *dst)
逐元素复制矩阵内容:dst = src。
lmmc_status_t lmmc_mat_create(size_t rows, size_t cols, lmmc_mat_t *out_mat)
创建 rows x cols 的零矩阵。
lmmc_status_t lmmc_vec_fill(lmmc_vec_t *vec, lmmc_real_t value)
就地将向量所有元素设为 value。
lmmc_status_t lmmc_mat_wrap(size_t rows, size_t cols, size_t stride, lmmc_real_t *data, lmmc_mat_t *out_mat)
创建引用调用方连续缓冲区的矩阵视图。
lmmc_status_t lmmc_vec_swap(lmmc_vec_t *x, lmmc_vec_t *y)
就地交换两个等长向量的全部元素。
lmmc_status_t lmmc_vec_wrap(size_t size, lmmc_real_t *data, lmmc_vec_t *out_vec)
创建引用调用方连续缓冲区的向量视图。
lmmc_status_t lmmc_mat_fill(lmmc_mat_t *mat, lmmc_real_t value)
就地将矩阵所有元素设为 value。
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 的零向量。
lmmc_status_t lmmc_vec_copy(const lmmc_vec_t *src, lmmc_vec_t *dst)
逐元素复制向量内容:dst = src。
void lmmc_mat_destroy(lmmc_mat_t *mat)
销毁矩阵,释放其拥有的缓冲区并清零结构体字段。
void lmmc_vec_destroy(lmmc_vec_t *vec)
销毁向量,释放其拥有的缓冲区并清零字段。
lmmc_real_t * data
lmmc_real_t * data
行优先存储的稠密矩阵。
一维稠密向量。
LMMC 内部使用的公共工具(仅源文件可见).
稠密矩阵直接分解接口(LU、Cholesky、QR)。
void * lmmc_memory_alloc(size_t size)
void lmmc_memory_free(void *pointer)
Private recoverable allocator for persistent LMMC ownership.
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_OK
@ LMMC_STATUS_DIMENSION_MISMATCH
@ LMMC_STATUS_ALLOCATION_FAILED
@ LMMC_STATUS_INVALID_ARGUMENT