10#define LMMC_INTERNAL_H
23static inline double lmmc_two_sum(
double a,
double b,
double* residual)
25 const double sum = a + b;
26 const double virtual_b = sum - a;
27 *residual = (a - (sum - virtual_b)) + (b - virtual_b);
32static inline void lmmc_compensated_add(
double value,
double* sum,
double* correction)
35 *sum = lmmc_two_sum(*sum, value, &residual);
36 *correction += residual;
47static inline void lmmc_fill_identity_unchecked(
lmmc_mat_t* matrix)
51 for (
size_t row = 0; row < matrix->
rows; ++row) {
52 for (
size_t column = 0; column < matrix->
cols; ++column) {
54 row == column ? &one : &zero);
59static inline int lmmc_is_power_of_four(
60 size_t value,
unsigned* out_digits)
62 size_t remaining = value;
67 while ((remaining & (
size_t)3) == 0) {
71 if (remaining != (
size_t)1) {
74 if (out_digits != NULL) {
86static inline int lmmc_safe_mul_size(
size_t a,
size_t b,
size_t *result)
88 if (a == 0 || b == 0) {
92 if (a > SIZE_MAX / b) {
104static inline int lmmc_safe_add_size(
size_t a,
size_t b,
size_t *result)
106 if (a > SIZE_MAX - b) {
114typedef struct lmmc_storage_envelope {
125static inline int lmmc_storage_envelope_checked(
138 if (data == NULL || out == NULL) {
141 begin = (uintptr_t)data;
144 if (rows == 0 || cols == 0) {
147 if (!lmmc_safe_mul_size(rows - 1, stride, &last_row)) {
150 if (!lmmc_safe_add_size(last_row, cols, &elements)) {
153 if (!lmmc_safe_mul_size(elements, element_size, &bytes)) {
156 if ((uintptr_t)bytes > UINTPTR_MAX - begin) {
159 out->
end = begin + (uintptr_t)bytes;
171static inline int lmmc_mat_descriptor_is_valid(
const lmmc_mat_t *matrix)
174 return matrix != NULL && matrix->
data != NULL &&
175 matrix->
rows != 0 && matrix->
cols != 0 &&
177 lmmc_storage_envelope_checked(
183static inline int lmmc_vec_descriptor_is_valid(
const lmmc_vec_t *vector)
186 return vector != NULL && vector->
data != NULL && vector->
size != 0 &&
187 lmmc_storage_envelope_checked(
193static inline int lmmc_storage_envelopes_overlap(
201static inline int lmmc_is_finite(
const lmmc_real_t *x)
206static inline int lmmc_real_range_is_finite(
209 if (values == NULL) {
212 for (
size_t index = 0; index < count; ++index) {
213 if (!lmmc_is_finite(&values[index])) {
220static inline void lmmc_interval_center_half_width(
224 if ((left < 0.0 && right > 0.0) ||
225 (left > 0.0 && right < 0.0)) {
226 *center = left * 0.5 + right * 0.5;
227 *half_width = right * 0.5 - left * 0.5;
230 *half_width = (right - left) * 0.5;
231 *center = left + *half_width;
239 lmmc_interval_center_half_width(
240 left, right, ¢er, &half_width);
251typedef struct lmmc_scaled_sumsq {
262static inline void lmmc_scaled_sumsq_add(
266 if (isnan(acc->
scale)) {
269 if (isnan(magnitude)) {
270 acc->
scale = magnitude;
274 if (magnitude == 0.0 || isinf(acc->
scale)) {
277 if (isinf(magnitude)) {
278 acc->
scale = magnitude;
282 if (acc->
scale < magnitude) {
284 acc->
sumsq = 1.0 + acc->
sumsq * ratio * ratio;
285 acc->
scale = magnitude;
288 acc->
sumsq += ratio * ratio;
307 return (a >= b) ? a : b;
LMMC binary real type and arithmetic spelling.
double lmmc_real_t
Public and internal LMMC real type.
#define LMMC_REAL_SET(dst, src)
将一个 lmmc_real_t 赋值到另一个:*dst = *src 。
#define LMMC_REAL_IS_FINITE(x)
判断 *x 是否为有限数。
void lmmc_rng_default_reset(void)
lmmc_rng_t * lmmc_rng_default_get(void)