File indexing completed on 2026-11-07 10:15:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef DOUBLE_INTERVAL_H
0013 #define DOUBLE_INTERVAL_H
0014
0015 #ifdef DOUBLE_INTERVAL_INLINES_C
0016 #define DOUBLE_INTERVAL_INLINE
0017 #else
0018 #define DOUBLE_INTERVAL_INLINE static inline
0019 #endif
0020
0021 #include <math.h>
0022 #include "double_extras.h"
0023 #include "arb_types.h"
0024
0025 #ifdef __cplusplus
0026 extern "C" {
0027 #endif
0028
0029 typedef struct
0030 {
0031 double a;
0032 double b;
0033 }
0034 di_t;
0035
0036 #define DI_CHECK(__x) \
0037 if (!(__x.a <= __x.b)) \
0038 { \
0039 flint_throw(FLINT_ERROR, "di_t endpoints %g, %g not ordered\n", __x.a, __x.b); \
0040 } \
0041
0042 DOUBLE_INTERVAL_INLINE
0043 di_t di_interval(double a, double b)
0044 {
0045 di_t res;
0046
0047 if (!(a <= b))
0048 {
0049 flint_throw(FLINT_ERROR, "di_interval endpoints %g, %g not ordered\n", a, b);
0050 }
0051
0052 res.a = a;
0053 res.b = b;
0054 return res;
0055 }
0056
0057 DOUBLE_INTERVAL_INLINE
0058 double _di_below(double x)
0059 {
0060 double t;
0061
0062 if (x <= 1e300)
0063 {
0064 t = x;
0065 if (t < 0.0)
0066 t = -t;
0067
0068 t += 1e-300;
0069 return x - t * 4.440892098500626e-16;
0070 }
0071 else
0072 {
0073 if (x != x)
0074 return -D_INF;
0075
0076 return 1e300;
0077 }
0078 }
0079
0080 DOUBLE_INTERVAL_INLINE
0081 double _di_above(double x)
0082 {
0083 double t;
0084
0085 if (x >= -1e300)
0086 {
0087 t = x;
0088 if (t < 0.0)
0089 t = -t;
0090
0091 t += 1e-300;
0092 return x + t * 4.440892098500626e-16;
0093 }
0094 else
0095 {
0096 if (x != x)
0097 return D_INF;
0098
0099 return -1e300;
0100 }
0101 }
0102
0103 DOUBLE_INTERVAL_INLINE
0104 di_t di_neg(di_t x)
0105 {
0106 di_t res;
0107 res.a = -x.b;
0108 res.b = -x.a;
0109 return res;
0110 }
0111
0112 DOUBLE_INTERVAL_INLINE
0113 di_t di_fast_add(di_t x, di_t y)
0114 {
0115 di_t res;
0116 res.a = _di_below(x.a + y.a);
0117 res.b = _di_above(x.b + y.b);
0118 return res;
0119 }
0120
0121 DOUBLE_INTERVAL_INLINE
0122 di_t di_fast_sub(di_t x, di_t y)
0123 {
0124 di_t res;
0125 res.a = _di_below(x.a - y.b);
0126 res.b = _di_above(x.b - y.a);
0127 return res;
0128 }
0129
0130 di_t di_fast_mul(di_t x, di_t y);
0131 di_t di_fast_sqr(di_t x);
0132 di_t di_fast_div(di_t x, di_t y);
0133
0134 DOUBLE_INTERVAL_INLINE
0135 di_t di_fast_add_d(di_t x, double y)
0136 {
0137 return di_fast_add(x, di_interval(y, y));
0138 }
0139
0140 DOUBLE_INTERVAL_INLINE
0141 di_t di_fast_sub_d(di_t x, double y)
0142 {
0143 return di_fast_sub(x, di_interval(y, y));
0144 }
0145
0146 DOUBLE_INTERVAL_INLINE
0147 di_t di_fast_mul_d(di_t x, double y)
0148 {
0149 return di_fast_mul(x, di_interval(y, y));
0150 }
0151
0152 DOUBLE_INTERVAL_INLINE
0153 di_t di_fast_div_d(di_t x, double y)
0154 {
0155 return di_fast_div(x, di_interval(y, y));
0156 }
0157
0158 di_t di_fast_log_nonnegative(di_t x);
0159
0160 DOUBLE_INTERVAL_INLINE
0161 di_t di_fast_mid(di_t x)
0162 {
0163 di_t a, b;
0164 if (x.a == -D_INF || x.b == D_INF)
0165 return di_interval(-D_INF, D_INF);
0166 a = di_interval(x.a, x.a);
0167 b = di_interval(x.b, x.b);
0168 return di_fast_mul_d(di_fast_add(a, b), 0.5);
0169 }
0170
0171 DOUBLE_INTERVAL_INLINE
0172 double di_fast_ubound_radius(di_t x)
0173 {
0174 return _di_above((x.b - x.a) * 0.5);
0175 }
0176
0177 DOUBLE_INTERVAL_INLINE
0178 void di_print(di_t x)
0179 {
0180 flint_printf("[%.17g, %.17g]", x.a, x.b);
0181 }
0182
0183 di_t arb_get_di(const arb_t x);
0184 void arb_set_di(arb_t res, di_t x, slong prec);
0185
0186 DOUBLE_INTERVAL_INLINE
0187 double d_randtest2(flint_rand_t state)
0188 {
0189 double x;
0190
0191 x = d_randtest(state);
0192 if (n_randint(state, 2))
0193 x = -x;
0194
0195 return ldexp(x, n_randint(state, 2400) - 1200);
0196 }
0197
0198 DOUBLE_INTERVAL_INLINE
0199 di_t di_randtest(flint_rand_t state)
0200 {
0201 di_t res;
0202
0203 res.a = d_randtest2(state);
0204 res.b = d_randtest2(state);
0205
0206 if (res.a > res.b)
0207 {
0208 double t = res.a;
0209 res.a = res.b;
0210 res.b = t;
0211 }
0212
0213 return res;
0214 }
0215
0216 #ifdef __cplusplus
0217 }
0218 #endif
0219
0220 #endif