LMMC
Lamina Mathematic core
载入中...
搜索中...
未找到
stdlib_internal.h
浏览该文件的文档.
1#ifndef LMMC_STD_STDLIB_INTERNAL_H
2#define LMMC_STD_STDLIB_INTERNAL_H
3
4/* Private shared helpers for the LMMC standard-library translation units. */
5#include <math.h>
6#include <stdint.h>
7#include <string.h>
8
9#include "memory_bridge.h"
10#include "internal.h"
11#include "lmmc/dense.h"
12#include "lmmc/eigen.h"
13#include "lmmc/stdlib.h"
14
15static inline int lmmc_std_vec_is_empty(const lmmc_vec_t* out)
16{
17 return out && out->size == 0 && out->data == NULL && out->owns_data == 0;
18}
19
20static inline int lmmc_std_mat_is_empty(const lmmc_mat_t* out)
21{
22 return out && out->rows == 0 && out->cols == 0 && out->stride == 0 &&
23 out->data == NULL && out->owns_data == 0;
24}
25
26static inline int lmmc_std_bool_vec_is_empty(const lmmc_std_bool_vec_t* out)
27{
28 return out && out->size == 0 && out->data == NULL && out->owns_data == 0;
29}
30
31static inline int lmmc_std_bool_mat_is_empty(const lmmc_std_bool_mat_t* out)
32{
33 return out && out->rows == 0 && out->cols == 0 && out->stride == 0 &&
34 out->data == NULL && out->owns_data == 0;
35}
36
37static inline lmmc_status_t lmmc_std_store_real(lmmc_real_t value, lmmc_real_t* out)
38{
39 if (!out) { return LMMC_STATUS_INVALID_ARGUMENT; }
40 *out = value;
41 return LMMC_STATUS_OK;
42}
43
44static inline lmmc_status_t lmmc_std_store_finite_real(lmmc_real_t value,
45 lmmc_real_t* out)
46{
47 if (!out) { return LMMC_STATUS_INVALID_ARGUMENT; }
48 if (!isfinite((double)value)) { return LMMC_STATUS_NUMERICAL_FAILURE; }
49 *out = value;
50 return LMMC_STATUS_OK;
51}
52
53static inline int lmmc_std_real_is_finite(lmmc_real_t value)
54{
55 return isfinite((double)value);
56}
57
58static inline int lmmc_std_real_array_is_finite(const lmmc_real_t* values,
59 size_t count)
60{
61 for (size_t i = 0; i < count; ++i) {
62 if (!lmmc_std_real_is_finite(values[i])) { return 0; }
63 }
64 return 1;
65}
66
67static inline int lmmc_std_complex_is_finite(const lmmc_complex_t* z)
68{
69 return z && lmmc_std_real_is_finite(z->real) &&
70 lmmc_std_real_is_finite(z->imag);
71}
72
73static inline uint64_t lmmc_std_hash_mix64(uint64_t value)
74{
75 value ^= value >> 30;
76 value *= UINT64_C(0xbf58476d1ce4e5b9);
77 value ^= value >> 27;
78 value *= UINT64_C(0x94d049bb133111eb);
79 value ^= value >> 31;
80 return value;
81}
82
83static inline uint64_t lmmc_std_real_hash_bits(lmmc_real_t value)
84{
85 uint64_t bits = 0;
86 if (value == (lmmc_real_t)0) {
87 value = (lmmc_real_t)0;
88 }
89 memcpy(&bits, &value, sizeof(value));
90 return lmmc_std_hash_mix64(bits);
91}
92
93static inline int lmmc_std_bool_is_valid(int value)
94{
95 return value == 0 || value == 1;
96}
97
98static inline uint64_t lmmc_std_text_hash_bytes(const char* value)
99{
100 uint64_t hash = UINT64_C(1469598103934665603);
101 const unsigned char* cursor = (const unsigned char*)value;
102 while (*cursor) {
103 hash ^= (uint64_t)(*cursor);
104 hash *= UINT64_C(1099511628211);
105 ++cursor;
106 }
107 return lmmc_std_hash_mix64(hash);
108}
109
110static inline lmmc_status_t lmmc_std_require_finite_mat(const lmmc_mat_t* a)
111{
112 if (!lmmc_mat_descriptor_is_valid(a)) { return LMMC_STATUS_INVALID_ARGUMENT; }
113 for (size_t i = 0; i < a->rows; ++i) {
114 for (size_t j = 0; j < a->cols; ++j) {
115 if (!lmmc_std_real_is_finite(a->data[i * a->stride + j])) {
117 }
118 }
119 }
120 return LMMC_STATUS_OK;
121}
122
123static inline lmmc_status_t lmmc_std_require_finite_vec(const lmmc_vec_t* v)
124{
125 if (!lmmc_vec_descriptor_is_valid(v)) {
127 }
128 return lmmc_std_real_array_is_finite(v->data, v->size) ? LMMC_STATUS_OK
130}
131
132static inline int lmmc_std_compare_eval(lmmc_real_t lhs,
134 lmmc_real_t rhs,
135 uint8_t* out)
136{
137 if (!out) { return 0; }
138 switch (op) {
139 case LMMC_STD_COMPARE_EQ: {
140 *out = (uint8_t)(lhs == rhs);
141 return 1;
142 }
143 case LMMC_STD_COMPARE_NE: {
144 *out = (uint8_t)(lhs != rhs);
145 return 1;
146 }
147 case LMMC_STD_COMPARE_LT: {
148 *out = (uint8_t)(lhs < rhs);
149 return 1;
150 }
151 case LMMC_STD_COMPARE_LE: {
152 *out = (uint8_t)(lhs <= rhs);
153 return 1;
154 }
155 case LMMC_STD_COMPARE_GT: {
156 *out = (uint8_t)(lhs > rhs);
157 return 1;
158 }
159 case LMMC_STD_COMPARE_GE: {
160 *out = (uint8_t)(lhs >= rhs);
161 return 1;
162 }
163 }
164 return 0;
165}
166
167static inline lmmc_status_t lmmc_std_bool_vec_create(size_t size,
169{
170 size_t bytes = 0;
171 if (!out || size == 0) { return LMMC_STATUS_INVALID_ARGUMENT; }
172 if (!lmmc_safe_mul_size(size, sizeof(uint8_t), &bytes)) {
174 }
175 out->data = (uint8_t*)lmmc_memory_alloc(bytes);
176 if (!out->data) { return LMMC_STATUS_ALLOCATION_FAILED; }
177 memset(out->data, 0, bytes);
178 out->size = size;
179 out->owns_data = 1;
180 return LMMC_STATUS_OK;
181}
182
183static inline lmmc_status_t lmmc_std_bool_mat_create(size_t rows,
184 size_t cols,
186{
187 size_t count = 0;
188 size_t bytes = 0;
189 if (!out || rows == 0 || cols == 0) { return LMMC_STATUS_INVALID_ARGUMENT; }
190 if (!lmmc_safe_mul_size(rows, cols, &count) ||
191 !lmmc_safe_mul_size(count, sizeof(uint8_t), &bytes)) {
193 }
194 out->data = (uint8_t*)lmmc_memory_alloc(bytes);
195 if (!out->data) { return LMMC_STATUS_ALLOCATION_FAILED; }
196 memset(out->data, 0, bytes);
197 out->rows = rows;
198 out->cols = cols;
199 out->stride = cols;
200 out->owns_data = 1;
201 return LMMC_STATUS_OK;
202}
203
204static inline lmmc_status_t lmmc_std_require_finite_eig_result(
205 const lmmc_eigen_gen_full_result_t* result)
206{
207 lmmc_status_t status;
208 if (!result) { return LMMC_STATUS_INVALID_ARGUMENT; }
209 status = lmmc_std_require_finite_vec(&result->real_parts);
210 if (status != LMMC_STATUS_OK) { return status; }
211 status = lmmc_std_require_finite_vec(&result->imag_parts);
212 if (status != LMMC_STATUS_OK) { return status; }
213 status = lmmc_std_require_finite_mat(&result->vectors_real);
214 if (status != LMMC_STATUS_OK) { return status; }
215 return lmmc_std_require_finite_mat(&result->vectors_imag);
216}
217
218static inline lmmc_status_t lmmc_std_require_finite_svd_result(
219 const lmmc_svd_result_t* result)
220{
221 lmmc_status_t status;
222 if (!result) { return LMMC_STATUS_INVALID_ARGUMENT; }
223 status = lmmc_std_require_finite_mat(&result->U);
224 if (status != LMMC_STATUS_OK) { return status; }
225 status = lmmc_std_require_finite_vec(&result->sigma);
226 if (status != LMMC_STATUS_OK) { return status; }
227 return lmmc_std_require_finite_mat(&result->Vt);
228}
229
230static inline lmmc_status_t lmmc_std_copy_mat(const lmmc_mat_t* src, lmmc_mat_t* out)
231{
232 lmmc_status_t status;
233 if (!lmmc_mat_descriptor_is_valid(src) || !out) { return LMMC_STATUS_INVALID_ARGUMENT; }
234 status = lmmc_std_require_finite_mat(src);
235 if (status != LMMC_STATUS_OK) { return status; }
236 status = lmmc_mat_create(src->rows, src->cols, out);
237 if (status != LMMC_STATUS_OK) { return status; }
238 status = lmmc_mat_copy(src, out);
239 if (status != LMMC_STATUS_OK) {
240 lmmc_mat_destroy(out);
241 }
242 return status;
243}
244
245static inline lmmc_status_t lmmc_std_copy_vec(const lmmc_vec_t* src, lmmc_vec_t* out)
246{
247 lmmc_status_t status;
248 if (!out) { return LMMC_STATUS_INVALID_ARGUMENT; }
249 status = lmmc_std_require_finite_vec(src);
250 if (status != LMMC_STATUS_OK) { return status; }
251 status = lmmc_vec_create(src->size, out);
252 if (status != LMMC_STATUS_OK) { return status; }
253 status = lmmc_vec_copy(src, out);
254 if (status != LMMC_STATUS_OK) {
255 lmmc_vec_destroy(out);
256 }
257 return status;
258}
259
260static inline int lmmc_std_real_is_integer(lmmc_real_t value)
261{
262 double as_double = (double)value;
263 return isfinite(as_double) && floor(as_double) == as_double;
264}
265
266static inline lmmc_status_t lmmc_std_pow_finite(lmmc_real_t base,
267 lmmc_real_t exponent,
268 lmmc_real_t* out)
269{
270 double value;
271 if (!out) { return LMMC_STATUS_INVALID_ARGUMENT; }
272 if (!lmmc_std_real_is_finite(base) ||
273 !lmmc_std_real_is_finite(exponent)) {
275 }
276 if (base == (lmmc_real_t)0 && exponent < (lmmc_real_t)0) {
278 }
279 if (base < (lmmc_real_t)0 && !lmmc_std_real_is_integer(exponent)) {
281 }
282 value = pow((double)base, (double)exponent);
283 if (!isfinite(value)) { return LMMC_STATUS_NUMERICAL_FAILURE; }
284 *out = (lmmc_real_t)value;
285 return LMMC_STATUS_OK;
286}
287
288/* Allocating entrypoints validate the finite source before construction. */
289static inline lmmc_status_t lmmc_std_vec_to_diag(const lmmc_vec_t* src,
290 size_t rows,
291 size_t cols,
292 lmmc_mat_t* out)
293{
294 lmmc_status_t status;
295 if (!src || !src->data || src->size == 0 || rows == 0 || cols == 0 ||
296 !out) {
298 }
299 if (src->size > rows || src->size > cols) { return LMMC_STATUS_INVALID_ARGUMENT; }
300 status = lmmc_mat_create(rows, cols, out);
301 if (status != LMMC_STATUS_OK) { return status; }
302 for (size_t i = 0; i < src->size; ++i) {
303 LMMC_REAL_SET(&out->data[i * out->stride + i], &src->data[i]);
304 }
305 return LMMC_STATUS_OK;
306}
307
308static inline lmmc_real_t lmmc_std_num_set_key(lmmc_real_t value)
309{
310 return value == (lmmc_real_t)0 ? (lmmc_real_t)0 : value;
311}
312
313#endif
lmmc_real_t real
lmmc_real_t imag
复数类型,包含实部与虚部.
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_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_vec_t sigma
定义 eigen.h:54
一般实矩阵完整特征分解结果(特征值 + 特征向量).
定义 eigen.h:42
奇异值分解结果: .
定义 eigen.h:52
LMMC 内部使用的公共工具(仅源文件可见).
void * lmmc_memory_alloc(size_t size)
Private recoverable allocator for persistent LMMC ownership.
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_OK
@ LMMC_STATUS_NUMERICAL_FAILURE
@ LMMC_STATUS_ALLOCATION_FAILED
@ LMMC_STATUS_INVALID_ARGUMENT
@ LMMC_STATUS_OUT_OF_RANGE
lmmc_std_compare_op_t
@ LMMC_STD_COMPARE_GE
@ LMMC_STD_COMPARE_EQ
@ LMMC_STD_COMPARE_LT
@ LMMC_STD_COMPARE_GT
@ LMMC_STD_COMPARE_LE
@ LMMC_STD_COMPARE_NE