LMMC
Lamina Mathematic core
载入中...
搜索中...
未找到
statistics_combinatorics.c
浏览该文件的文档.
1#include <math.h>
2
3#include "lmmc/config.h"
4#include "lmmc/numeric.h"
5#include "lmmc/stats.h"
6
8
9static int lmmc_real_mul_overflows(lmmc_real_t value, lmmc_real_t factor) {
10 return factor != 0.0 && value > (lmmc_real_t)(DBL_MAX / factor);
11}
12
13void lmmc_stats_factorial(lmmc_real_t* out_val, uint32_t n) {
14 if (out_val == NULL) {
15 return;
16 }
17 lmmc_real_t result = 1.0;
18 for (uint32_t k = 2; k <= n; ++k) {
19 lmmc_real_t factor = (lmmc_real_t)k;
20 if (lmmc_real_mul_overflows(result, factor)) {
21 LMMC_REAL_SET_D(out_val, INFINITY);
22 return;
23 }
24 result *= factor;
25 }
26 LMMC_REAL_SET(out_val, &result);
27}
28
29void lmmc_stats_npr(lmmc_real_t* out_val, uint32_t n, uint32_t r) {
30 if (out_val == NULL) {
31 return;
32 }
33 if (r > n) {
34 LMMC_REAL_SET_D(out_val, 0.0);
35 return;
36 }
37 lmmc_real_t result = 1.0;
38 for (uint32_t k = 0; k < r; ++k) {
39 lmmc_real_t factor = (lmmc_real_t)(n - k);
40 if (lmmc_real_mul_overflows(result, factor)) {
41 LMMC_REAL_SET_D(out_val, INFINITY);
42 return;
43 }
44 result *= factor;
45 }
46 LMMC_REAL_SET(out_val, &result);
47}
48
49void lmmc_stats_ncr(lmmc_real_t* out_val, uint32_t n, uint32_t r) {
50 if (out_val == NULL) {
51 return;
52 }
53 if (r > n) {
54 LMMC_REAL_SET_D(out_val, 0.0);
55 return;
56 }
57 if (r > n - r) {
58 r = n - r;
59 }
60 lmmc_real_t mantissa = 0.5;
61 int exponent = 1;
62 for (uint32_t k = 1; k <= r; ++k) {
63 const lmmc_real_t numerator = (lmmc_real_t)(n - r + k);
64 const lmmc_real_t denominator = (lmmc_real_t)k;
65 int increment;
67 mantissa = frexp((mantissa * numerator) / denominator, &increment);
68 exponent += increment;
69 if (exponent > DBL_MAX_EXP ||
70 (exponent == DBL_MAX_EXP && !isfinite(scalbn(mantissa, exponent)))) {
71 LMMC_REAL_SET_D(out_val, INFINITY);
72 return;
73 }
74 }
75 LMMC_REAL_SET_D(out_val, scalbn(mantissa, exponent));
76}
77
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_SET_D(dst, dbl)
将一个 double 字面量赋值到 lmmc_real_t 。
数值标量、特殊函数和 FFT 公共接口。
基础统计量与组合数学接口。
void lmmc_stats_npr(lmmc_real_t *out_val, uint32_t n, uint32_t r)
计算排列数 。
void lmmc_stats_ncr(lmmc_real_t *out_val, uint32_t n, uint32_t r)
计算组合数 的近似 binary64 值。 r>n 返回 0;r=0 或 r=n 返回 1。乘除递推处理可溢出的中间乘积, 仅最终结果不可表示时返回正 inf。输出为 NULL 时直接返回。
void lmmc_stats_factorial(lmmc_real_t *out_val, uint32_t n)
计算 ,溢出时按 IEEE-754 规则返回 inf 。