number 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ext/bounds.c +116 -0
- data/ext/compare.c +706 -0
- data/ext/complex.c +674 -0
- data/ext/decompose.c +231 -0
- data/ext/extconf.rb +7 -0
- data/ext/interval.c +394 -0
- data/ext/number.c +1651 -0
- data/ext/number.h +92 -0
- data/ext/real.c +877 -0
- data/ext/real_bounds.c +57 -0
- data/ext/round.c +46 -0
- metadata +69 -0
data/ext/decompose.c
ADDED
@@ -0,0 +1,231 @@
|
|
1
|
+
#include "number.h"
|
2
|
+
|
3
|
+
Complex* complex_im (Complex* complex)
|
4
|
+
{
|
5
|
+
return (Complex*)complex_new((Interval*)interval_dup(complex->im), (Interval*)interval_zero());
|
6
|
+
}
|
7
|
+
|
8
|
+
Complex* complex_im_l (Complex* complex)
|
9
|
+
{
|
10
|
+
return (Complex*)complex_from_real(complex->im->l);
|
11
|
+
}
|
12
|
+
|
13
|
+
Complex* complex_im_n (Complex* complex)
|
14
|
+
{
|
15
|
+
return (Complex*)complex_from_real(complex->im->n);
|
16
|
+
}
|
17
|
+
|
18
|
+
Complex* complex_im_u (Complex* complex)
|
19
|
+
{
|
20
|
+
return (Complex*)complex_from_real(complex->im->u);
|
21
|
+
}
|
22
|
+
|
23
|
+
Complex* complex_im_magnitude (Complex* complex)
|
24
|
+
{
|
25
|
+
Real* l_abs;
|
26
|
+
Real* u_abs;
|
27
|
+
Complex* result;
|
28
|
+
|
29
|
+
l_abs = (Real*)real_abs(complex->im->l);
|
30
|
+
u_abs = (Real*)real_abs(complex->im->u);
|
31
|
+
|
32
|
+
result = (Complex*)complex_from_real(real_gt_p(l_abs, u_abs) ? l_abs : u_abs);
|
33
|
+
|
34
|
+
real_free(l_abs);
|
35
|
+
real_free(u_abs);
|
36
|
+
|
37
|
+
return result;
|
38
|
+
}
|
39
|
+
|
40
|
+
Complex* complex_im_mignitude (Complex* complex)
|
41
|
+
{
|
42
|
+
Real* l_abs;
|
43
|
+
Real* u_abs;
|
44
|
+
Real* zero;
|
45
|
+
Complex* result;
|
46
|
+
|
47
|
+
l_abs = (Real*)real_abs(complex->im->l);
|
48
|
+
u_abs = (Real*)real_abs(complex->im->u);
|
49
|
+
zero = (Real*)real_zero();
|
50
|
+
|
51
|
+
result = (Complex*)complex_from_real(interval_span_zero_p(complex->im) ? zero : (real_lt_p(l_abs, u_abs) ? l_abs : u_abs));
|
52
|
+
|
53
|
+
real_free(l_abs);
|
54
|
+
real_free(u_abs);
|
55
|
+
real_free(zero);
|
56
|
+
|
57
|
+
return result;
|
58
|
+
}
|
59
|
+
|
60
|
+
Complex* complex_im_width (Complex* complex)
|
61
|
+
{
|
62
|
+
Real* width;
|
63
|
+
Complex* result;
|
64
|
+
|
65
|
+
width = (Real*)real_subtract(complex->im->u, complex->im->l);
|
66
|
+
result = (Complex*)complex_from_real(width);
|
67
|
+
|
68
|
+
real_free(width);
|
69
|
+
|
70
|
+
return result;
|
71
|
+
}
|
72
|
+
|
73
|
+
Complex* complex_re (Complex* complex)
|
74
|
+
{
|
75
|
+
return (Complex*)complex_new((Interval*)interval_dup(complex->re), (Interval*)interval_zero());
|
76
|
+
}
|
77
|
+
|
78
|
+
Complex* complex_re_l (Complex* complex)
|
79
|
+
{
|
80
|
+
return (Complex*)complex_from_real(complex->re->l);
|
81
|
+
}
|
82
|
+
|
83
|
+
Complex* complex_re_n (Complex* complex)
|
84
|
+
{
|
85
|
+
return (Complex*)complex_from_real(complex->re->n);
|
86
|
+
}
|
87
|
+
|
88
|
+
Complex* complex_re_u (Complex* complex)
|
89
|
+
{
|
90
|
+
return (Complex*)complex_from_real(complex->re->u);
|
91
|
+
}
|
92
|
+
|
93
|
+
Complex* complex_re_magnitude (Complex* complex)
|
94
|
+
{
|
95
|
+
Real* l_abs;
|
96
|
+
Real* u_abs;
|
97
|
+
Complex* result;
|
98
|
+
|
99
|
+
l_abs = (Real*)real_abs(complex->re->l);
|
100
|
+
u_abs = (Real*)real_abs(complex->re->u);
|
101
|
+
|
102
|
+
result = (Complex*)complex_from_real(real_gt_p(l_abs, u_abs) ? l_abs : u_abs);
|
103
|
+
|
104
|
+
real_free(l_abs);
|
105
|
+
real_free(u_abs);
|
106
|
+
|
107
|
+
return result;
|
108
|
+
}
|
109
|
+
|
110
|
+
Complex* complex_re_mignitude (Complex* complex)
|
111
|
+
{
|
112
|
+
Real* l_abs;
|
113
|
+
Real* u_abs;
|
114
|
+
Real* zero;
|
115
|
+
Complex* result;
|
116
|
+
|
117
|
+
l_abs = (Real*)real_abs(complex->re->l);
|
118
|
+
u_abs = (Real*)real_abs(complex->re->u);
|
119
|
+
zero = (Real*)real_zero();
|
120
|
+
|
121
|
+
result = (Complex*)complex_from_real(interval_span_zero_p(complex->re) ? zero : (real_lt_p(l_abs, u_abs) ? l_abs : u_abs));
|
122
|
+
|
123
|
+
real_free(l_abs);
|
124
|
+
real_free(u_abs);
|
125
|
+
real_free(zero);
|
126
|
+
|
127
|
+
return result;
|
128
|
+
}
|
129
|
+
|
130
|
+
Complex* complex_re_width (Complex* complex)
|
131
|
+
{
|
132
|
+
Real* width;
|
133
|
+
Complex* result;
|
134
|
+
|
135
|
+
width = (Real*)real_subtract(complex->re->u, complex->re->l);
|
136
|
+
result = (Complex*)complex_from_real(width);
|
137
|
+
|
138
|
+
real_free(width);
|
139
|
+
|
140
|
+
return result;
|
141
|
+
}
|
142
|
+
|
143
|
+
Complex* complex_ll (Complex* complex)
|
144
|
+
{
|
145
|
+
return (Complex*)complex_new((Interval*)interval_from_real(complex->re->l), (Interval*)interval_from_real(complex->im->l));
|
146
|
+
}
|
147
|
+
|
148
|
+
Complex* complex_lu (Complex* complex)
|
149
|
+
{
|
150
|
+
return (Complex*)complex_new((Interval*)interval_from_real(complex->re->l), (Interval*)interval_from_real(complex->im->u));
|
151
|
+
}
|
152
|
+
|
153
|
+
Complex* complex_n (Complex* complex)
|
154
|
+
{
|
155
|
+
return (Complex*)complex_new((Interval*)interval_from_real(complex->re->n), (Interval*)interval_from_real(complex->im->n));
|
156
|
+
}
|
157
|
+
|
158
|
+
Complex* complex_ul (Complex* complex)
|
159
|
+
{
|
160
|
+
return (Complex*)complex_new((Interval*)interval_from_real(complex->re->u), (Interval*)interval_from_real(complex->im->l));
|
161
|
+
}
|
162
|
+
|
163
|
+
Complex* complex_uu (Complex* complex)
|
164
|
+
{
|
165
|
+
return (Complex*)complex_new((Interval*)interval_from_real(complex->re->u), (Interval*)interval_from_real(complex->im->u));
|
166
|
+
}
|
167
|
+
|
168
|
+
Complex* complex_magnitude (Complex* complex)
|
169
|
+
{
|
170
|
+
Real* re_l_abs;
|
171
|
+
Real* re_u_abs;
|
172
|
+
Real* im_l_abs;
|
173
|
+
Real* im_u_abs;
|
174
|
+
Complex* result;
|
175
|
+
|
176
|
+
re_l_abs = (Real*)real_abs(complex->re->l);
|
177
|
+
re_u_abs = (Real*)real_abs(complex->re->u);
|
178
|
+
im_l_abs = (Real*)real_abs(complex->im->l);
|
179
|
+
im_u_abs = (Real*)real_abs(complex->im->u);
|
180
|
+
|
181
|
+
result = (Complex*)complex_new((Interval*)interval_from_real(real_gt_p(re_l_abs, re_u_abs) ? re_l_abs : re_u_abs), (Interval*)interval_from_real(real_gt_p(im_l_abs, im_u_abs) ? im_l_abs : im_u_abs));
|
182
|
+
|
183
|
+
real_free(re_l_abs);
|
184
|
+
real_free(re_u_abs);
|
185
|
+
real_free(im_l_abs);
|
186
|
+
real_free(im_u_abs);
|
187
|
+
|
188
|
+
return result;
|
189
|
+
}
|
190
|
+
|
191
|
+
Complex* complex_mignitude (Complex* complex)
|
192
|
+
{
|
193
|
+
Real* re_l_abs;
|
194
|
+
Real* re_u_abs;
|
195
|
+
Real* im_l_abs;
|
196
|
+
Real* im_u_abs;
|
197
|
+
Real* zero;
|
198
|
+
Complex* result;
|
199
|
+
|
200
|
+
re_l_abs = (Real*)real_abs(complex->re->l);
|
201
|
+
re_u_abs = (Real*)real_abs(complex->re->u);
|
202
|
+
im_l_abs = (Real*)real_abs(complex->im->l);
|
203
|
+
im_u_abs = (Real*)real_abs(complex->im->u);
|
204
|
+
|
205
|
+
zero = (Real*)real_zero();
|
206
|
+
result = (Complex*)complex_new((Interval*)interval_from_real(interval_span_zero_p(complex->re) ? zero : (real_lt_p(re_l_abs, re_u_abs) ? re_l_abs : re_u_abs)), (Interval*)interval_from_real(interval_span_zero_p(complex->im) ? zero : (real_lt_p(im_l_abs, im_u_abs) ? im_l_abs : im_u_abs)));
|
207
|
+
|
208
|
+
real_free(re_l_abs);
|
209
|
+
real_free(re_u_abs);
|
210
|
+
real_free(im_l_abs);
|
211
|
+
real_free(im_u_abs);
|
212
|
+
real_free(zero);
|
213
|
+
|
214
|
+
return result;
|
215
|
+
}
|
216
|
+
|
217
|
+
Complex* complex_width (Complex* complex)
|
218
|
+
{
|
219
|
+
Real* re_width;
|
220
|
+
Real* im_width;
|
221
|
+
Complex* result;
|
222
|
+
|
223
|
+
re_width = (Real*)real_subtract(complex->re->u, complex->re->l);
|
224
|
+
im_width = (Real*)real_subtract(complex->im->u, complex->im->l);
|
225
|
+
result = (Complex*)complex_new((Interval*)interval_from_real(re_width), (Interval*)interval_from_real(im_width));
|
226
|
+
|
227
|
+
real_free(re_width);
|
228
|
+
real_free(im_width);
|
229
|
+
|
230
|
+
return result;
|
231
|
+
}
|
data/ext/extconf.rb
ADDED
data/ext/interval.c
ADDED
@@ -0,0 +1,394 @@
|
|
1
|
+
#include "number.h"
|
2
|
+
|
3
|
+
/*
|
4
|
+
* Frees the memory block pointed to by interval.
|
5
|
+
*/
|
6
|
+
void interval_free (Interval* interval)
|
7
|
+
{
|
8
|
+
if (interval)
|
9
|
+
{
|
10
|
+
if (interval->n)
|
11
|
+
{
|
12
|
+
real_free(interval->n);
|
13
|
+
}
|
14
|
+
|
15
|
+
if (interval->l)
|
16
|
+
{
|
17
|
+
real_free(interval->l);
|
18
|
+
}
|
19
|
+
|
20
|
+
if (interval->u)
|
21
|
+
{
|
22
|
+
real_free(interval->u);
|
23
|
+
}
|
24
|
+
|
25
|
+
free(interval);
|
26
|
+
interval = NULL;
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
/*
|
31
|
+
* Returns the maximum size of the string representation of interval as a long.
|
32
|
+
*/
|
33
|
+
long interval_strlen (Interval* interval)
|
34
|
+
{
|
35
|
+
return real_strlen(interval->l) + real_strlen(interval->n) + real_strlen(interval->u) + 10;
|
36
|
+
}
|
37
|
+
|
38
|
+
/*
|
39
|
+
* Puts a string representation of interval into the string pointed to by buf.
|
40
|
+
*
|
41
|
+
* interval: {1:1 < 2:1 < 3:1} => str: "{1:1 < 2:1 < 3:1}"
|
42
|
+
* interval: {0:1 ≤ 0:1 ≤ 0:1} => str: "{0:1 ≤ 0:1 ≤ 0:1}"
|
43
|
+
*/
|
44
|
+
void interval_print(char* buf, Interval* interval)
|
45
|
+
{
|
46
|
+
char n_str[real_strlen(interval->n)];
|
47
|
+
char l_str[real_strlen(interval->l)];
|
48
|
+
char u_str[real_strlen(interval->u)];
|
49
|
+
|
50
|
+
if (interval_degenerate_p(interval))
|
51
|
+
{
|
52
|
+
real_print(n_str, interval->n);
|
53
|
+
sprintf(buf, "%s", n_str);
|
54
|
+
}
|
55
|
+
else
|
56
|
+
{
|
57
|
+
real_print(n_str, interval->n);
|
58
|
+
real_print(l_str, interval->l);
|
59
|
+
real_print(u_str, interval->u);
|
60
|
+
|
61
|
+
sprintf(buf, "[%s %s (%s) %s %s]", l_str, interval->L ? "≤" : "<", n_str, interval->R ? "≤" : "<", u_str);
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
/*
|
66
|
+
* Returns 1 if interval contains real, 0 otherwise.
|
67
|
+
*/
|
68
|
+
int interval_span_p (Interval* interval, Real* real)
|
69
|
+
{
|
70
|
+
return !(real_gt_p(interval->l, real) || real_lt_p(interval->u, real) || (real_eq_p(interval->l, real) && !interval->L) || (real_eq_p(interval->u, real) && !interval->R));
|
71
|
+
}
|
72
|
+
|
73
|
+
/*
|
74
|
+
* Returns 1 if interval contains zero, 0 otherwise.
|
75
|
+
*/
|
76
|
+
int interval_span_zero_p (Interval* interval)
|
77
|
+
{
|
78
|
+
int result;
|
79
|
+
Real* zero;
|
80
|
+
|
81
|
+
zero = (Real*)real_zero();
|
82
|
+
result = interval_span_p(interval, zero);
|
83
|
+
|
84
|
+
real_free(zero);
|
85
|
+
|
86
|
+
return result;
|
87
|
+
}
|
88
|
+
|
89
|
+
/*
|
90
|
+
* Returns 1 if interval contains only zero, 0 otherwise.
|
91
|
+
*/
|
92
|
+
int interval_zero_p (Interval* interval)
|
93
|
+
{
|
94
|
+
int result;
|
95
|
+
Real* zero;
|
96
|
+
|
97
|
+
zero = (Real*)real_zero();
|
98
|
+
result = real_eq_p(interval->l, zero) && real_eq_p(interval->u, zero);
|
99
|
+
|
100
|
+
real_free(zero);
|
101
|
+
|
102
|
+
return result;
|
103
|
+
}
|
104
|
+
|
105
|
+
/*
|
106
|
+
* Returns 1 if interval contains exactly one real number, 0 otherwise.
|
107
|
+
*/
|
108
|
+
int interval_degenerate_p (Interval* interval)
|
109
|
+
{
|
110
|
+
return real_eq_p(interval->l, interval->u);
|
111
|
+
}
|
112
|
+
|
113
|
+
/*
|
114
|
+
* Returns a pointer to a newly allocated Interval with the given value. The
|
115
|
+
* given reals will be referenced by the new interval and must be freed only
|
116
|
+
* when this interval is freed.
|
117
|
+
*
|
118
|
+
* l: (1:1), L: 0, n: (2:1), R: 1, u: (3:1) => interval: {1:1 < 2:1 ≤ 3:1}
|
119
|
+
*/
|
120
|
+
Interval* interval_new (Real* l, int L, Real* n, int R, Real* u)
|
121
|
+
{
|
122
|
+
Interval* interval;
|
123
|
+
interval = (Interval*)malloc(sizeof(Interval));
|
124
|
+
|
125
|
+
if (interval == NULL)
|
126
|
+
{
|
127
|
+
return NULL;
|
128
|
+
}
|
129
|
+
|
130
|
+
memset(interval, 0, sizeof(Interval));
|
131
|
+
|
132
|
+
if (NaN(l) || NaN(n) || NaN(u))
|
133
|
+
{
|
134
|
+
interval->n = (Real*)real_nan();
|
135
|
+
interval->l = (Real*)real_neg_inf();
|
136
|
+
interval->u = (Real*)real_pos_inf();
|
137
|
+
|
138
|
+
interval->L = true;
|
139
|
+
interval->R = true;
|
140
|
+
|
141
|
+
real_free(n);
|
142
|
+
real_free(l);
|
143
|
+
real_free(u);
|
144
|
+
}
|
145
|
+
else
|
146
|
+
{
|
147
|
+
interval->n = (Real*)n;
|
148
|
+
interval->l = (Real*)l;
|
149
|
+
interval->u = (Real*)u;
|
150
|
+
|
151
|
+
interval->L = real_eq_p(interval->l, interval->u) || real_eq_p(interval->n, interval->l) || L;
|
152
|
+
interval->R = real_eq_p(interval->l, interval->u) || real_eq_p(interval->n, interval->u) || R;
|
153
|
+
}
|
154
|
+
|
155
|
+
return interval;
|
156
|
+
}
|
157
|
+
|
158
|
+
/*
|
159
|
+
* Returns a pointer to a newly allocated Interval containing only the given
|
160
|
+
* real. The given real is duplicated before being stored, and therefore must
|
161
|
+
* be freed separately.
|
162
|
+
*/
|
163
|
+
Interval* interval_from_real (Real* real)
|
164
|
+
{
|
165
|
+
return interval_new((Real*)real_dup(real), true, (Real*)real_dup(real), true, (Real*)real_dup(real));
|
166
|
+
}
|
167
|
+
|
168
|
+
/*
|
169
|
+
* Returns a pointer to a newly allocated Interval containing a NaN value.
|
170
|
+
*/
|
171
|
+
Interval* interval_nan ()
|
172
|
+
{
|
173
|
+
return interval_new((Real*)real_neg_inf(), true, (Real*)real_nan(), true, (Real*)real_pos_inf());
|
174
|
+
}
|
175
|
+
|
176
|
+
/*
|
177
|
+
* Returns a pointer to a newly allocated Interval containing only +∞.
|
178
|
+
*/
|
179
|
+
Interval* interval_pos_inf ()
|
180
|
+
{
|
181
|
+
return interval_new((Real*)real_pos_inf(), true, (Real*)real_pos_inf(), true, (Real*)real_pos_inf());
|
182
|
+
}
|
183
|
+
|
184
|
+
/*
|
185
|
+
* Returns a pointer to a newly allocated Interval containing only -∞.
|
186
|
+
*/
|
187
|
+
Interval* interval_neg_inf ()
|
188
|
+
{
|
189
|
+
return interval_new((Real*)real_neg_inf(), true, (Real*)real_neg_inf(), true, (Real*)real_neg_inf());
|
190
|
+
}
|
191
|
+
|
192
|
+
/*
|
193
|
+
* Returns a pointer to a newly allocated Interval containing only 0.
|
194
|
+
*/
|
195
|
+
Interval* interval_zero ()
|
196
|
+
{
|
197
|
+
return interval_new((Real*)real_zero(), true, (Real*)real_zero(), true, (Real*)real_zero());
|
198
|
+
}
|
199
|
+
|
200
|
+
/*
|
201
|
+
* Returns a pointer to a newly allocated Interval containing only 1.
|
202
|
+
*/
|
203
|
+
Interval* interval_one ()
|
204
|
+
{
|
205
|
+
return interval_new((Real*)real_one(), true, (Real*)real_one(), true, (Real*)real_one());
|
206
|
+
}
|
207
|
+
|
208
|
+
/*
|
209
|
+
* Returns a pointer to a newly allocated Interval containing π, accurate to
|
210
|
+
* digs digits.
|
211
|
+
*/
|
212
|
+
Interval* interval_pi ()
|
213
|
+
{
|
214
|
+
return (Interval*)interval_new((Real*)real_pi(ROUND_DOWN), false, (Real*)real_pi(ROUND_NEAREST), false, (Real*)real_pi(ROUND_UP1));
|
215
|
+
}
|
216
|
+
|
217
|
+
/*
|
218
|
+
* Returns a pointer to a newly allocated Interval containing e, accurate to
|
219
|
+
* digs digits.
|
220
|
+
*/
|
221
|
+
Interval* interval_e ()
|
222
|
+
{
|
223
|
+
return (Interval*)interval_new((Real*)real_e(ROUND_DOWN), false, (Real*)real_e(ROUND_NEAREST), false, (Real*)real_e(ROUND_UP1));
|
224
|
+
}
|
225
|
+
|
226
|
+
/*
|
227
|
+
* Returns a pointer to a newly allocated Interval with the same value as the
|
228
|
+
* given interval.
|
229
|
+
*/
|
230
|
+
Interval* interval_dup (Interval* interval)
|
231
|
+
{
|
232
|
+
return interval_new((Real*)real_dup(interval->l), interval->L, (Real*)real_dup(interval->n), interval->R, (Real*)real_dup(interval->u));
|
233
|
+
}
|
234
|
+
|
235
|
+
/*
|
236
|
+
* Returns a pointer to a newly allocated Interval containing a + b.
|
237
|
+
*/
|
238
|
+
Interval* interval_add (Interval* a, Interval* b)
|
239
|
+
{
|
240
|
+
int L;
|
241
|
+
int R;
|
242
|
+
Real* n;
|
243
|
+
Real* l;
|
244
|
+
Real* u;
|
245
|
+
|
246
|
+
n = (Real*)real_add(a->n, b->n);
|
247
|
+
l = (Real*)real_add(a->l, b->l);
|
248
|
+
u = (Real*)real_add(a->u, b->u);
|
249
|
+
|
250
|
+
L = a->L && b->L;
|
251
|
+
R = a->R && b->R;
|
252
|
+
|
253
|
+
return interval_new(l, L, n, R, u);
|
254
|
+
}
|
255
|
+
|
256
|
+
/*
|
257
|
+
* Returns a pointer to a newly allocated Interval containing a - b.
|
258
|
+
*/
|
259
|
+
Interval* interval_subtract (Interval* a, Interval* b)
|
260
|
+
{
|
261
|
+
int L;
|
262
|
+
int R;
|
263
|
+
Real* n;
|
264
|
+
Real* l;
|
265
|
+
Real* u;
|
266
|
+
|
267
|
+
n = (Real*)real_subtract(a->n, b->n);
|
268
|
+
l = (Real*)real_subtract(a->l, b->u);
|
269
|
+
u = (Real*)real_subtract(a->u, b->l);
|
270
|
+
|
271
|
+
L = a->L && b->R;
|
272
|
+
R = a->R && b->L;
|
273
|
+
|
274
|
+
return interval_new(l, L, n, R, u);
|
275
|
+
}
|
276
|
+
|
277
|
+
/*
|
278
|
+
* Returns a pointer to a newly allocated Interval containing a * b.
|
279
|
+
*/
|
280
|
+
Interval* interval_multiply (Interval* a, Interval* b)
|
281
|
+
{
|
282
|
+
int L;
|
283
|
+
int R;
|
284
|
+
Real* n;
|
285
|
+
Real* l;
|
286
|
+
Real* u;
|
287
|
+
RealBounds* bounds;
|
288
|
+
Interval* interval;
|
289
|
+
|
290
|
+
bounds = (RealBounds*)real_bounds_new();
|
291
|
+
real_bounds_update(bounds, (Real*)real_multiply(a->l, b->l), a->L && b->L);
|
292
|
+
real_bounds_update(bounds, (Real*)real_multiply(a->l, b->u), a->L && b->R);
|
293
|
+
real_bounds_update(bounds, (Real*)real_multiply(a->u, b->l), a->R && b->L);
|
294
|
+
real_bounds_update(bounds, (Real*)real_multiply(a->u, b->u), a->R && b->R);
|
295
|
+
|
296
|
+
L = bounds->min_closed;
|
297
|
+
R = bounds->max_closed;
|
298
|
+
|
299
|
+
n = (Real*)real_multiply(a->n, b->n);
|
300
|
+
l = (Real*)real_dup(bounds->min);
|
301
|
+
u = (Real*)real_dup(bounds->max);
|
302
|
+
|
303
|
+
real_bounds_free(bounds);
|
304
|
+
|
305
|
+
return interval_new(l, L, n, R, u);
|
306
|
+
}
|
307
|
+
|
308
|
+
/*
|
309
|
+
* Returns a pointer to a newly allocated Interval containing a / b.
|
310
|
+
*/
|
311
|
+
Interval* interval_divide (Interval* a, Interval* b)
|
312
|
+
{
|
313
|
+
int L;
|
314
|
+
int R;
|
315
|
+
Real* n;
|
316
|
+
Real* l;
|
317
|
+
Real* u;
|
318
|
+
RealBounds* bounds;
|
319
|
+
Interval* interval;
|
320
|
+
|
321
|
+
bounds = (RealBounds*)real_bounds_new();
|
322
|
+
real_bounds_update(bounds, (Real*)real_divide(a->l, b->l, ROUND_NEAREST), a->L && b->L);
|
323
|
+
real_bounds_update(bounds, (Real*)real_divide(a->l, b->u, ROUND_NEAREST), a->L && b->R);
|
324
|
+
real_bounds_update(bounds, (Real*)real_divide(a->u, b->l, ROUND_NEAREST), a->R && b->L);
|
325
|
+
real_bounds_update(bounds, (Real*)real_divide(a->u, b->u, ROUND_NEAREST), a->R && b->R);
|
326
|
+
|
327
|
+
L = bounds->min_closed;
|
328
|
+
R = bounds->max_closed;
|
329
|
+
|
330
|
+
n = (Real*)real_divide(a->n, b->n);
|
331
|
+
l = (Real*)real_dup(bounds->min);
|
332
|
+
u = (Real*)real_dup(bounds->max);
|
333
|
+
|
334
|
+
real_bounds_free(bounds);
|
335
|
+
|
336
|
+
return interval_new(l, L, n, R, u);
|
337
|
+
}
|
338
|
+
|
339
|
+
/*
|
340
|
+
* Returns a pointer to a newly allocated Interval containing -interval.
|
341
|
+
*/
|
342
|
+
Interval* interval_negate (Interval* interval)
|
343
|
+
{
|
344
|
+
return interval_new((Real*)real_negate(interval->u), interval->R, (Real*)real_negate(interval->n), interval->L, (Real*)real_negate(interval->l));
|
345
|
+
}
|
346
|
+
|
347
|
+
/*
|
348
|
+
* Returns a pointer to a newly allocated Interval containing the elements of
|
349
|
+
* interval rounded to the nearest integer values.
|
350
|
+
*/
|
351
|
+
Interval* interval_round (Interval* interval)
|
352
|
+
{
|
353
|
+
return interval_new((Real*)real_round(interval->l), true, (Real*)real_round(interval->n), true, (Real*)real_round(interval->u));
|
354
|
+
}
|
355
|
+
|
356
|
+
/*
|
357
|
+
* Returns a pointer to a newly allocated Interval containing the elements of
|
358
|
+
* interval rounded to the next closest integer values in the direction of
|
359
|
+
* positive infinity.
|
360
|
+
*/
|
361
|
+
Interval* interval_round_ceiling (Interval* interval)
|
362
|
+
{
|
363
|
+
return interval_new((Real*)real_ceil(interval->l), true, (Real*)real_ceil(interval->n), true, (Real*)real_ceil(interval->u));
|
364
|
+
}
|
365
|
+
|
366
|
+
/*
|
367
|
+
* Returns a pointer to a newly allocated Interval containing the elements of
|
368
|
+
* interval rounded to the next closest integer values in the direction of
|
369
|
+
* negative infinity.
|
370
|
+
*/
|
371
|
+
Interval* interval_round_floor (Interval* interval)
|
372
|
+
{
|
373
|
+
return interval_new((Real*)real_floor(interval->l), true, (Real*)real_floor(interval->n), true, (Real*)real_floor(interval->u));
|
374
|
+
}
|
375
|
+
|
376
|
+
/*
|
377
|
+
* Returns a pointer to a newly allocated Interval containing the elements of
|
378
|
+
* interval rounded to the next closest integer values in the direction away
|
379
|
+
* from the origin.
|
380
|
+
*/
|
381
|
+
Interval* interval_round_infinity (Interval* interval)
|
382
|
+
{
|
383
|
+
return interval_new((Real*)real_round_infinity(interval->l), true, (Real*)real_round_infinity(interval->n), true, (Real*)real_round_infinity(interval->u));
|
384
|
+
}
|
385
|
+
|
386
|
+
/*
|
387
|
+
* Returns a pointer to a newly allocated Interval containing the elements of
|
388
|
+
* interval rounded to the next closest integer values in the direction of the
|
389
|
+
* origin.
|
390
|
+
*/
|
391
|
+
Interval* interval_round_origin (Interval* interval)
|
392
|
+
{
|
393
|
+
return interval_new((Real*)real_round_origin(interval->l), true, (Real*)real_round_origin(interval->n), true, (Real*)real_round_origin(interval->u));
|
394
|
+
}
|