p1788 0.1.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.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +8 -0
  3. data/AUTHORS +6 -0
  4. data/LICENSE +201 -0
  5. data/NOTICE +29 -0
  6. data/README.md +65 -0
  7. data/ext/libieeep1788_copy/README +3 -0
  8. data/ext/libieeep1788_copy/p1788/AUTHORS +16 -0
  9. data/ext/libieeep1788_copy/p1788/LICENSE +202 -0
  10. data/ext/libieeep1788_copy/p1788/NOTICE +14 -0
  11. data/ext/libieeep1788_copy/p1788/decoration/decoration.hpp +265 -0
  12. data/ext/libieeep1788_copy/p1788/exception/exception.hpp +302 -0
  13. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor.hpp +3443 -0
  14. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_bool_func_impl.hpp +608 -0
  15. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_cancel_func_impl.hpp +229 -0
  16. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_class_impl.hpp +526 -0
  17. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_elem_func_impl.hpp +4533 -0
  18. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_io_impl.hpp +1421 -0
  19. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_mul_rev_to_pair_func_impl.hpp +347 -0
  20. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_num_func_impl.hpp +655 -0
  21. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_rec_bool_func_impl.hpp +146 -0
  22. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_rec_overlap_impl.hpp +188 -0
  23. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_rev_func_impl.hpp +1674 -0
  24. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_set_op_impl.hpp +216 -0
  25. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_setup_func_impl.hpp +68 -0
  26. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_util_func_impl.hpp +135 -0
  27. data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_validation_func_impl.hpp +93 -0
  28. data/ext/libieeep1788_copy/p1788/infsup/base_interval.hpp +1529 -0
  29. data/ext/libieeep1788_copy/p1788/infsup/base_interval_bool_func_impl.hpp +481 -0
  30. data/ext/libieeep1788_copy/p1788/infsup/base_interval_cancel_func_impl.hpp +126 -0
  31. data/ext/libieeep1788_copy/p1788/infsup/base_interval_elem_func_impl.hpp +1581 -0
  32. data/ext/libieeep1788_copy/p1788/infsup/base_interval_io_impl.hpp +59 -0
  33. data/ext/libieeep1788_copy/p1788/infsup/base_interval_mul_rev_to_pair_func_impl.hpp +88 -0
  34. data/ext/libieeep1788_copy/p1788/infsup/base_interval_num_func_impl.hpp +345 -0
  35. data/ext/libieeep1788_copy/p1788/infsup/base_interval_rec_bool_func_impl.hpp +92 -0
  36. data/ext/libieeep1788_copy/p1788/infsup/base_interval_rec_overlap_impl.hpp +72 -0
  37. data/ext/libieeep1788_copy/p1788/infsup/base_interval_rev_func_impl.hpp +656 -0
  38. data/ext/libieeep1788_copy/p1788/infsup/base_interval_set_op_impl.hpp +126 -0
  39. data/ext/libieeep1788_copy/p1788/infsup/decorated_interval.hpp +464 -0
  40. data/ext/libieeep1788_copy/p1788/infsup/forward_declaration.hpp +66 -0
  41. data/ext/libieeep1788_copy/p1788/infsup/interval.hpp +275 -0
  42. data/ext/libieeep1788_copy/p1788/io/io_manip.hpp +531 -0
  43. data/ext/libieeep1788_copy/p1788/overlapping/overlapping.hpp +241 -0
  44. data/ext/libieeep1788_copy/p1788/p1788.hpp +45 -0
  45. data/ext/libieeep1788_copy/p1788/reduction/reduction.hpp +341 -0
  46. data/ext/libieeep1788_copy/p1788/util/io.hpp +63 -0
  47. data/ext/libieeep1788_copy/p1788/util/mixed_type_traits.hpp +140 -0
  48. data/ext/libieeep1788_copy/p1788/util/mpfr_util.hpp +77 -0
  49. data/ext/libieeep1788_copy/p1788/util/mpfr_var.hpp +119 -0
  50. data/ext/libieeep1788_copy/p1788/util/mpfr_var_impl.hpp +382 -0
  51. data/ext/libieeep1788_copy/p1788/version.hpp +34 -0
  52. data/ext/p1788/extconf.rb +49 -0
  53. data/ext/p1788/p1788.cc +3764 -0
  54. data/lib/p1788/version.rb +4 -0
  55. data/lib/p1788.rb +25 -0
  56. data/p1788.gemspec +72 -0
  57. metadata +99 -0
@@ -0,0 +1,3764 @@
1
+ /*
2
+ * P1788
3
+ *
4
+ * A Ruby extension wrapping the C++ libieeep1788 interval arithmetic library.
5
+ *
6
+ * Copyright 2022
7
+ *
8
+ * Thรฉotime Bollengier (theotime.bollengier@ensta-bretagne.fr)
9
+ * ENSTA Bretagne, France
10
+ *
11
+ * Licensed under the Apache License, Version 2.0 (the "License");
12
+ * you may not use this file except in compliance with the License.
13
+ * You may obtain a copy of the License at
14
+ *
15
+ * http://www.apache.org/licenses/LICENSE-2.0
16
+ *
17
+ * Unless required by applicable law or agreed to in writing, software
18
+ * distributed under the License is distributed on an "AS IS" BASIS,
19
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
+ * See the License for the specific language governing permissions and
21
+ * limitations under the License.
22
+ */
23
+
24
+ /* ๐‘ ๐‘’๐‘™๐‘“ โˆšโชฝ ๐’”๐’†๐’๐’‡ โˆ…โ„โ‚Šโ‚‹ยฑโˆž๐ฑ๐ฒ๐ณย ๐‘Ž๐‘๐‘๐‘ฅ๐‘ฆ๐‘งโ‹…๐’‚๐’ƒ๐’„๐’™๐’š๐’›|โ‰ โˆ€โˆƒโจ†โ‹€โ‹โ‹‚โ‹ƒโˆงโˆจโˆฉโˆชโ‰คโ‰ฅโŠ”โŠ‚โŠƒโŠ„โŠ…โІโЇโŠˆโЉโˆˆโˆˆโˆ‰โˆ‹โˆŒโˆ‘โ†‘โ†“โ†•โŽงโŽจโŽฉโŽชโŽซโŽฌโŽญโŽฎ */
25
+ /* TODO:
26
+ * function index with groups
27
+ * README
28
+ */
29
+
30
+ #include <ruby.h>
31
+ #include <limits>
32
+ #include <p1788/p1788.hpp>
33
+
34
+
35
+ /* Document-module: P1788
36
+ *
37
+ * The {P1788} module defines forward and reverse functions to work on intervals.
38
+ *
39
+ * Set operations
40
+ * --------------
41
+ *
42
+ * {intersection} {convex_hull}
43
+ *
44
+ * Forward-mode and reverse-mode elementary functions
45
+ * --------------------------------------------------
46
+ *
47
+ * ### Basic operations
48
+ *
49
+ * {neg} {add} {sub} {mul} {div} {recip} {sqr} {sqrt} {fma}
50
+ *
51
+ * ### Power functions
52
+ *
53
+ * {pown} {pow} {exp} {exp2} {exp10} {log} {log2} {log10}
54
+ *
55
+ * ### Trigonometric functions
56
+ *
57
+ * {sin} {cos} {tan} {asin} {acos} {atan} {atan2}
58
+ *
59
+ * ### Hyperbolic functions
60
+ *
61
+ * {sinh} {cosh} {tanh} {asinh} {acosh} {atanh}
62
+ *
63
+ * ### Integer functions
64
+ *
65
+ * {sign} {ceil} {floor} {floorceil} {trunc} {round_ties_to_even} {round_ties_to_away}
66
+ *
67
+ * ### Absmax functions
68
+ *
69
+ * {abs} {min} {max}
70
+ *
71
+ *
72
+ * Reverse-mode elementary functions
73
+ * ---------------------------------
74
+ *
75
+ * ### Reverse basic operations
76
+ *
77
+ * {neg_rev} {add_rev} {sub_rev} {mul_rev} {mul_rev_to_pair} {div_rev} {recip_rev} {sqr_rev} {sqrt_rev}
78
+ *
79
+ * ### Reverse power functions
80
+ *
81
+ * {pown_rev} {pow_rev1} {pow_rev2} {exp_rev} {exp2_rev} {exp10_rev} {log_rev} {log2_rev} {log10_rev}
82
+ *
83
+ * ### Reverse trigonometric functions
84
+ *
85
+ * {sin_rev} {cos_rev} {tan_rev} {asin_rev} {acos_rev} {atan_rev}
86
+ *
87
+ * ### Reverse yperbolic functions
88
+ *
89
+ * {sinh_rev} {cosh_rev} {tanh_rev} {asinh_rev} {acosh_rev} {atanh_rev}
90
+ *
91
+ * ### Reverse abs function
92
+ *
93
+ * {abs_rev}
94
+ *
95
+ *
96
+ * Two-output division
97
+ * -------------------
98
+ *
99
+ * {div_to_pair}
100
+ *
101
+ *
102
+ * Cancellative addition and subtraction
103
+ * ------------------------------------
104
+ *
105
+ * {cancel_plus} {cancel_minus}
106
+ */
107
+
108
+
109
+ /* Document-class: P1788::Interval
110
+ *
111
+ * The set of mathematical intervals implemented by the {Interval} class is denoted ๐•€โ„.
112
+ * It comprises those subsets [๐’™] of the real line โ„ that are closed and connected in the topological sense:
113
+ * that is, the empty set (โˆ…) together with all the nonempty intervals,
114
+ * denoted [<span style="text-decoration:underline">๐’™</span>, <span style="text-decoration:overline">๐’™</span>],
115
+ * defined by
116
+ *
117
+ * [<span style="text-decoration:underline">๐’™</span>, <span style="text-decoration:overline">๐’™</span>] = { ๐‘ฅ โˆˆ โ„ \| <span style="text-decoration:underline">๐’™</span> โ‰ค ๐‘ฅ โ‰ค <span style="text-decoration:overline">๐’™</span> },
118
+ *
119
+ * where <span style="text-decoration:underline">๐’™</span> = inf([๐’™]) โˆˆ โ„ โˆช \\{-โˆž\} and
120
+ * <span style="text-decoration:overline">๐’™</span> = sup([๐’™]) โˆˆ โ„ โˆช \\{+โˆž} are extended-real numbers satisfying
121
+ * <span style="text-decoration:underline">๐’™</span> โ‰ค <span style="text-decoration:overline">๐’™</span>,
122
+ * <span style="text-decoration:underline">๐’™</span> < +โˆž and <span style="text-decoration:overline">๐’™</span> > -โˆž.
123
+ *
124
+ * Set operation methods
125
+ * ---------------------
126
+ *
127
+ * {&}
128
+ * {Interval#|}
129
+ * {bisect}
130
+ *
131
+ * Boolean methods
132
+ * ---------------
133
+ *
134
+ * {empty?} {entire?} {all_reals?} {pos_reals?} {neg_reals?} {positive?} {strictly_positive?} {negative?}
135
+ * {strictly_negative?} {common?} {finite?} {symmetric?} {singleton?} {eql?} {==} {less?} {greater?}
136
+ * {strictly_less?} {strictly_greater?} {precedes?} {succeeds?} {strictly_precedes?} {strictly_succeeds?}
137
+ * {disjoint_from?} {intersect?} {strict_subset_of?} {subset_of?} {strictly_contain?} {contain?} {include?}
138
+ *
139
+ * Numeric methods
140
+ * ---------------
141
+ *
142
+ * {inf} {sup} {midpoint} {splitpoint} {radius} {mid_rad} {width} {magnitude} {mignitude}
143
+ *
144
+ * Forward elementary function methods
145
+ * -----------------------------------
146
+ *
147
+ * {+@} {-@} {+} {-} {*} {/} {**} {pow} {pown} {recip} {abs}
148
+ * {sqr} {sqrt} {exp} {exp2} {exp10} {log} {log2} {log10}
149
+ * {sin} {cos} {tan} {asin} {acos} {atan} {sinh} {cosh} {tanh} {asinh} {acosh} {atanh}
150
+ * {sign} {ceil} {floor} {floorceil} {truncate} {round_ties_to_even} {round_ties_to_away}
151
+ * {min} {max} {div_to_pair} {cancel_plus} {cancel_minus} {fma}
152
+ *
153
+ * Reverse elementary functions methods
154
+ * ------------------------------------
155
+ *
156
+ * {mul_rev_to_pair} {mul_rev} {sqr_rev} {abs_rev} {pown_rev} {pow_rev1} {pow_rev2}
157
+ * {sin_rev} {cos_rev} {tan_rev} {cosh_rev}
158
+ *
159
+ * Ruby object methods
160
+ * -------------------
161
+ *
162
+ * {inspect} {coerce} {===} {to_s} {to_a} {to_latex} {dup} {clone}
163
+ */
164
+
165
+ typedef union {
166
+ double d;
167
+ uint64_t u;
168
+ } double_int_t;
169
+
170
+ using InfSupDouble = p1788::infsup::interval<double, p1788::flavor::infsup::setbased::mpfr_bin_ieee754_flavor>;
171
+
172
+ static const double INF = std::numeric_limits<double>::infinity();
173
+ static const double MAXF = std::numeric_limits<double>::max();
174
+
175
+ static const double_int_t pi_inf = {.u = 0x400921fb54442d18ULL};
176
+ static const double_int_t pi_sup = {.u = 0x400921fb54442d19ULL};
177
+ static const double_int_t e_inf = {.u = 0x4005bf0a8b145769ULL};
178
+ static const double_int_t e_sup = {.u = 0x4005bf0a8b14576aULL};
179
+ static const double_int_t hpi_inf = {.u = 0x3ff921fb54442d18ULL};
180
+ static const double_int_t hpi_sup = {.u = 0x3ff921fb54442d19ULL};
181
+ static const double_int_t pi2_inf = {.u = 0x401921fb54442d18ULL};
182
+ static const double_int_t pi2_sup = {.u = 0x401921fb54442d19ULL};
183
+
184
+
185
+
186
+
187
+ static const InfSupDouble all_reals_set(-INF, INF);
188
+ static const InfSupDouble pos_reals_set( 0.0, INF);
189
+ static const InfSupDouble neg_reals_set(-INF, 0.0);
190
+ static const InfSupDouble pi_set(pi_inf.d, pi_sup.d);
191
+ static const InfSupDouble hpi_set(hpi_inf.d, hpi_sup.d);
192
+ static const InfSupDouble pi2_set(pi2_inf.d, pi2_sup.d);
193
+ static const InfSupDouble e_set(e_inf.d, e_sup.d);
194
+ static const InfSupDouble minus_one_one_set(-1.0, 1.0);
195
+ static const InfSupDouble minus_pi_pi_set(-pi_sup.d, pi_sup.d);
196
+ static const InfSupDouble minus_hpi_hpi_set(-hpi_sup.d, hpi_sup.d);
197
+ static const InfSupDouble zero_pi_set(0.0, pi_sup.d);
198
+
199
+ static VALUE m_P1788;
200
+ static VALUE c_Interval;
201
+
202
+ static ID id_to_s;
203
+
204
+
205
+
206
+ static void p1788_interval_free(void *p)
207
+ {
208
+ InfSupDouble *i = (InfSupDouble*)p;
209
+ delete i;
210
+ }
211
+
212
+
213
+ static size_t p1788_interval_size(const void* p)
214
+ {
215
+ return sizeof(InfSupDouble);
216
+ }
217
+
218
+
219
+ static const rb_data_type_t p1788_interval_type = {
220
+ .wrap_struct_name = "P1788::Interval",
221
+ .function = {
222
+ .dmark = NULL,
223
+ .dfree = p1788_interval_free,
224
+ .dsize = p1788_interval_size,
225
+ },
226
+ .parent = NULL,
227
+ .data = NULL,
228
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
229
+ };
230
+
231
+
232
+ static VALUE p1788_interval_alloc(VALUE klass)
233
+ {
234
+ InfSupDouble *inter = new InfSupDouble(-INF, INF);
235
+ return TypedData_Wrap_Struct(klass, &p1788_interval_type, inter);
236
+ }
237
+
238
+
239
+ // static inline VALUE p1788_interval_new(const InfSupDouble& isd) {
240
+ // InfSupDouble *inter = new InfSupDouble(isd);
241
+ // return TypedData_Wrap_Struct(c_Interval, &p1788_interval_type, inter);
242
+ // }
243
+
244
+
245
+ #define P1788_NEW_RB_INTERVAL(new_rb_obj, ...) \
246
+ do { \
247
+ InfSupDouble *isdp_ = new InfSupDouble(__VA_ARGS__); \
248
+ new_rb_obj = TypedData_Wrap_Struct(c_Interval, &p1788_interval_type, isdp_); \
249
+ } while (0)
250
+
251
+
252
+ static inline InfSupDouble& p1788_interval_rb2ref(VALUE obj) {
253
+ InfSupDouble *i;
254
+ TypedData_Get_Struct(obj, InfSupDouble, &p1788_interval_type, i);
255
+ return *i;
256
+ }
257
+
258
+
259
+ static InfSupDouble p1788_rbobj2infsupdouble(VALUE obj)
260
+ {
261
+ InfSupDouble inter;
262
+ double lower, upper;
263
+ VALUE beg, end;
264
+ int i, arlen;
265
+
266
+ if (rb_class_of(obj) == c_Interval)
267
+ inter = p1788_interval_rb2ref(obj);
268
+ else if (rb_obj_is_kind_of(obj, rb_cNumeric)) {
269
+ lower = NUM2DBL(obj);
270
+ inter = InfSupDouble(lower, lower);
271
+ }
272
+ else if (rb_obj_is_kind_of(obj, rb_cRange)) {
273
+ rb_range_values(obj, &beg, &end, &i);
274
+ lower = NUM2DBL(beg);
275
+ upper = NUM2DBL(end);
276
+ inter = InfSupDouble(lower, upper);
277
+ }
278
+ else if (rb_obj_is_kind_of(obj, rb_cArray)) {
279
+ arlen = rb_array_len(obj);
280
+ if (arlen == 0)
281
+ inter = InfSupDouble();
282
+ else if (arlen == 1) {
283
+ lower = NUM2DBL(rb_ary_entry(obj, 0));
284
+ inter = InfSupDouble(lower, lower);
285
+ }
286
+ else if (arlen == 2) {
287
+ lower = NUM2DBL(rb_ary_entry(obj, 0));
288
+ upper = NUM2DBL(rb_ary_entry(obj, 1));
289
+ inter = InfSupDouble(lower, upper);
290
+ }
291
+ else
292
+ rb_raise(rb_eArgError, "the array must have 0 to 2 elements, not %d", arlen);
293
+ }
294
+ else
295
+ rb_raise(rb_eTypeError, "Cannot convert a %" PRIsVALUE " to a %" PRIsVALUE,
296
+ rb_class_name(rb_class_of(obj)), rb_class_name(c_Interval));
297
+
298
+ return inter;
299
+ }
300
+
301
+
302
+ /* Create a new {Interval}
303
+ * @return [Interval]
304
+ * @overload new()
305
+ * return a new interval [-โˆž, +โˆž]
306
+ * @overload new(lower, upper)
307
+ * @param lower [Float] lower bound
308
+ * @param upper [Float] upper bound
309
+ * @overload new(range_or_array)
310
+ * @param range_or_array [Range<Float>, Array<Float>] a range of Floats or a two elements array of Floats
311
+ * @overload new(str)
312
+ * @param str [String] something like '[0.1, 1/10]' or "[0.1]" or "[1/10]"
313
+ * @overload new(other_interval)
314
+ * @param other_interval [Interval]
315
+ * @see []
316
+ */
317
+ static VALUE p1788_interval_initialize(int argc, VALUE *argv, VALUE self)
318
+ {
319
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
320
+ double lower, upper;
321
+ VALUE beg, end;
322
+ int i, arlen;
323
+
324
+ switch (argc) {
325
+ case 0:
326
+ break;
327
+ case 1:
328
+ if (rb_obj_is_kind_of(argv[0], rb_cNumeric)) {
329
+ lower = NUM2DBL(argv[0]);
330
+ inter = InfSupDouble(lower, lower);
331
+ }
332
+ else if (rb_obj_is_kind_of(argv[0], rb_cString)) {
333
+ inter = InfSupDouble(std::string(StringValueCStr(argv[0])));
334
+ }
335
+ else if (rb_obj_is_kind_of(argv[0], rb_cRange)) {
336
+ rb_range_values(argv[0], &beg, &end, &i);
337
+ lower = NUM2DBL(beg);
338
+ upper = NUM2DBL(end);
339
+ inter = InfSupDouble(lower, upper);
340
+ }
341
+ else if (rb_obj_is_kind_of(argv[0], rb_cArray)) {
342
+ arlen = rb_array_len(argv[0]);
343
+ if (arlen == 0)
344
+ inter = InfSupDouble();
345
+ else if (arlen == 1) {
346
+ lower = NUM2DBL(rb_ary_entry(argv[0], 0));
347
+ inter = InfSupDouble(lower, lower);
348
+ }
349
+ else if (arlen == 2) {
350
+ lower = NUM2DBL(rb_ary_entry(argv[0], 0));
351
+ upper = NUM2DBL(rb_ary_entry(argv[0], 1));
352
+ inter = InfSupDouble(lower, upper);
353
+ }
354
+ else
355
+ rb_raise(rb_eArgError, "the array must have 0 to 2 elements, not %d", arlen);
356
+ }
357
+ else if (rb_obj_is_kind_of(argv[0], c_Interval)) {
358
+ inter = InfSupDouble(p1788_interval_rb2ref(argv[0]));
359
+ }
360
+ else
361
+ rb_raise(rb_eArgError, "expecting Numeric, String, Range, Array or Interval, not %" PRIsVALUE, rb_class_name(rb_class_of(argv[0])));
362
+ break;
363
+ case 2:
364
+ if (rb_obj_is_kind_of(argv[0], rb_cNumeric) && rb_obj_is_kind_of(argv[1], rb_cNumeric)) {
365
+ lower = NUM2DBL(argv[0]);
366
+ upper = NUM2DBL(argv[1]);
367
+ inter = InfSupDouble(lower, upper);
368
+ }
369
+ else
370
+ rb_raise(rb_eArgError, "expecting two Numerics, or a [Numeric, Range or Array]");
371
+ break;
372
+ default:
373
+ rb_raise(rb_eArgError, "expecting 0 to 2 arguments, not %d", argc);
374
+ }
375
+
376
+ return self;
377
+ }
378
+
379
+
380
+ /* Create a new {Interval}
381
+ * @example
382
+ * P1788::Interval[] #=> #<P1788::Interval โ„>
383
+ * P1788::Interval[0.7] #=> #<P1788::Interval {0.7}>
384
+ * P1788::Interval[1, 2.3] #=> #<P1788::Interval [1, 2.3]>
385
+ * P1788::Interval[-3.4 .. 5.6] #=> #<P1788::Interval [-3.4, 5.6]>
386
+ * a = [7, 8]
387
+ * P1788::Interval[a] #=> #<P1788::Interval [7, 8]>
388
+ * P1788::Interval['[-4.9]'] #=> #<P1788::Interval [-4.9, -4.8999999999999995]>
389
+ * P1788::Interval['[1/10, Inf]'] #=> #<P1788::Interval [0.09999999999999999, +โˆž]>
390
+ * P1788::Interval[0, Float::INFINITY] #=> #<P1788::Interval โ„โ‚Š>
391
+ * P1788::Interval[Float::NAN] #=> #<P1788::Interval โˆ…>
392
+ *
393
+ * @overload []()
394
+ * return a new interval [-โˆž, +โˆž]
395
+ * @overload [](lower, upper)
396
+ * @param lower [Float] lower bound
397
+ * @param upper [Float] upper bound
398
+ * @overload [](range_or_array)
399
+ * @param range_or_array [Range<Float>, Array<Float>] a range of Floats or a two elements array of Floats
400
+ * @overload [](str)
401
+ * @param str [String] something like '[0.1, 1/10]' or "[0.1]" or "[1/10]"
402
+ */
403
+ static VALUE p1788_interval_rb_new(int argc, VALUE *argv, VALUE self)
404
+ {
405
+ return rb_class_new_instance(argc, argv, c_Interval);
406
+ }
407
+
408
+
409
+ /* Return a new {Interval} equal to `self`.
410
+ * @return [Interval]
411
+ */
412
+ static VALUE p1788_interval_dup(VALUE self)
413
+ {
414
+ return rb_class_new_instance(1, &self, c_Interval);
415
+ }
416
+
417
+
418
+ /* Return a new {Interval} equal to `self`, also copying its singleton class.
419
+ * @return [Interval]
420
+ */
421
+ static VALUE p1788_interval_clone(VALUE self)
422
+ {
423
+ VALUE c = rb_call_super(0, NULL);
424
+ p1788_interval_rb2ref(c) = p1788_interval_rb2ref(self);
425
+ return c;
426
+ }
427
+
428
+
429
+ /* Returns a two element arrays containing the bounds of `self`.
430
+ * @return [Array<Float>]
431
+ */
432
+ static VALUE p1788_interval_to_a(VALUE self)
433
+ {
434
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
435
+ if (InfSupDouble::is_empty(inter))
436
+ return rb_ary_new_capa(0);
437
+ VALUE r = rb_ary_new_capa(2);
438
+ rb_ary_store(r, 0, DBL2NUM(InfSupDouble::inf(inter)));
439
+ rb_ary_store(r, 1, DBL2NUM(InfSupDouble::sup(inter)));
440
+ return r;
441
+ }
442
+
443
+
444
+ /* Returns a unicode string representation of _self_.
445
+ * @return [String]
446
+ */
447
+ static VALUE p1788_interval_to_s(VALUE self)
448
+ {
449
+ double lb, ub;
450
+ VALUE lbc, ubc;
451
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
452
+
453
+ if (InfSupDouble::is_empty(inter))
454
+ return rb_utf8_str_new_cstr("โˆ…");
455
+ if (InfSupDouble::is_entire(inter))
456
+ return rb_utf8_str_new_cstr("โ„");
457
+
458
+ lb = InfSupDouble::inf(inter);
459
+ ub = InfSupDouble::sup(inter);
460
+
461
+ if ((lb == 0.0) && (ub == INF))
462
+ return rb_utf8_str_new_cstr("โ„โ‚Š");
463
+ if ((lb == -INF) && (ub == 0.0))
464
+ return rb_utf8_str_new_cstr("โ„โ‚‹");
465
+
466
+ if (lb == -INF)
467
+ lbc = rb_utf8_str_new_cstr("-โˆž");
468
+ else if (lb == INF)
469
+ lbc = rb_utf8_str_new_cstr("+โˆž");
470
+ else if ((double)((int)(lb)) == lb)
471
+ lbc = rb_funcallv(INT2NUM((int)lb), id_to_s, 0, NULL);
472
+ else
473
+ lbc = rb_funcallv(DBL2NUM(lb), id_to_s, 0, NULL);
474
+
475
+ if (InfSupDouble::is_singleton(inter))
476
+ return rb_sprintf("{%" PRIsVALUE "}", lbc);
477
+
478
+ if (ub == -INF)
479
+ ubc = rb_utf8_str_new_cstr("-โˆž");
480
+ else if (ub == INF)
481
+ ubc = rb_utf8_str_new_cstr("+โˆž");
482
+ else if ((double)((int)(ub)) == ub)
483
+ ubc = rb_funcallv(INT2NUM((int)ub), id_to_s, 0, NULL);
484
+ else
485
+ ubc = rb_funcallv(DBL2NUM(ub), id_to_s, 0, NULL);
486
+
487
+ return rb_sprintf("[%" PRIsVALUE ", %" PRIsVALUE "]", lbc, ubc);
488
+ }
489
+
490
+
491
+ /* @return [String]
492
+ */
493
+ static VALUE p1788_interval_inspect(VALUE self)
494
+ {
495
+ InfSupDouble &i = p1788_interval_rb2ref(self);
496
+ return rb_sprintf("#<%" PRIsVALUE " %" PRIsVALUE ">",
497
+ rb_class_name(c_Interval),
498
+ p1788_interval_to_s(self));
499
+ }
500
+
501
+
502
+ static VALUE p1788_interval_to_tex(VALUE self)
503
+ {
504
+ double lb, ub;
505
+ VALUE lbc, ubc;
506
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
507
+
508
+ if (InfSupDouble::is_empty(inter))
509
+ return rb_utf8_str_new_cstr("\\emptyset");
510
+ if (InfSupDouble::is_entire(inter))
511
+ return rb_utf8_str_new_cstr("\\mathbb{R}");
512
+
513
+ lb = InfSupDouble::inf(inter);
514
+ ub = InfSupDouble::sup(inter);
515
+
516
+ if ((lb == 0.0) && (ub == INF))
517
+ return rb_utf8_str_new_cstr("\\mathbb{R}_+");
518
+ if ((lb == -INF) && (ub == 0.0))
519
+ return rb_utf8_str_new_cstr("\\mathbb{R}_-");
520
+
521
+ if (lb == -INF)
522
+ lbc = rb_utf8_str_new_cstr("-\\infty");
523
+ else if (lb == INF)
524
+ lbc = rb_utf8_str_new_cstr("+\\infty");
525
+ else if ((double)((int)(lb)) == lb)
526
+ lbc = rb_funcallv(INT2NUM((int)lb), id_to_s, 0, NULL);
527
+ else
528
+ lbc = rb_funcallv(DBL2NUM(lb), id_to_s, 0, NULL);
529
+
530
+ if (InfSupDouble::is_singleton(inter))
531
+ return rb_sprintf("\\left\\{ %" PRIsVALUE " \\right\\}", lbc);
532
+
533
+ if (ub == -INF)
534
+ ubc = rb_utf8_str_new_cstr("-\\infty");
535
+ else if (ub == INF)
536
+ ubc = rb_utf8_str_new_cstr("+\\infty");
537
+ else if ((double)((int)(ub)) == ub)
538
+ ubc = rb_funcallv(INT2NUM((int)ub), id_to_s, 0, NULL);
539
+ else
540
+ ubc = rb_funcallv(DBL2NUM(ub), id_to_s, 0, NULL);
541
+
542
+ return rb_sprintf("\\left[ %" PRIsVALUE " , %" PRIsVALUE " \\right]", lbc, ubc);
543
+ }
544
+
545
+
546
+ /* Returns a LaTex representation as a string.
547
+ * @return [String]
548
+ * @overload to_latex(print_dollars = true)
549
+ * @param print_dollars [Boolean] if true, will surround the string with `$$` signs.
550
+ */
551
+ static VALUE p1788_interval_to_latex(int argc, VALUE *argv, VALUE self)
552
+ {
553
+ VALUE arg;
554
+ if (rb_scan_args(argc, argv, "01", &arg) > 0) {
555
+ if (arg == Qnil || arg == Qfalse)
556
+ return p1788_interval_to_tex(self);
557
+ }
558
+ return rb_sprintf("$$ %" PRIsVALUE " $$", p1788_interval_to_tex(self));
559
+ }
560
+
561
+
562
+ /* @param other [Numeric]
563
+ * @return [Array<Interval>] [other.to_interval, self]
564
+ */
565
+ static VALUE p1788_interval_coerce(VALUE self, VALUE other)
566
+ {
567
+ VALUE rbo;
568
+ P1788_NEW_RB_INTERVAL(rbo, p1788_rbobj2infsupdouble(other));
569
+ return rb_ary_new_from_args(2, rbo, self);
570
+ }
571
+
572
+
573
+ /* Boolean functions on intervals */
574
+
575
+
576
+ /* [๐’”๐’†๐’๐’‡] = โˆ… ?
577
+ * @return [Boolean]
578
+ */
579
+ static VALUE p1788_interval_empty(VALUE self)
580
+ {
581
+ return InfSupDouble::is_empty(p1788_interval_rb2ref(self)) ? Qtrue : Qfalse;
582
+ }
583
+
584
+
585
+ /* [๐’”๐’†๐’๐’‡] = โ„ ?
586
+ * @return [Boolean]
587
+ */
588
+ static VALUE p1788_interval_entire(VALUE self)
589
+ {
590
+ return InfSupDouble::is_entire(p1788_interval_rb2ref(self)) ? Qtrue : Qfalse;
591
+ }
592
+
593
+
594
+ /* [๐’”๐’†๐’๐’‡] = โ„โ‚Š ?
595
+ * @return [Boolean]
596
+ */
597
+ static VALUE p1788_interval_pos_reals(VALUE self)
598
+ {
599
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
600
+ return ((InfSupDouble::inf(inter) == 0.0) && (InfSupDouble::sup(inter) == INF)) ? Qtrue : Qfalse;
601
+ }
602
+
603
+
604
+ /* [๐’”๐’†๐’๐’‡] = โ„โ‚‹ ?
605
+ * @return [Boolean]
606
+ */
607
+ static VALUE p1788_interval_neg_reals(VALUE self)
608
+ {
609
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
610
+ return ((InfSupDouble::inf(inter) == -INF) && (InfSupDouble::sup(inter) == 0.0)) ? Qtrue : Qfalse;
611
+ }
612
+
613
+
614
+ /* [๐’”๐’†๐’๐’‡] โІ [0, +โˆž]
615
+ *
616
+ * _true_ if [๐’”๐’†๐’๐’‡] = โˆ… โˆจ <span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span> โ‰ฅ 0<br/>
617
+ * _false_ otherwise
618
+ * @return [Boolean]
619
+ */
620
+ static VALUE p1788_interval_positive(VALUE self)
621
+ {
622
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
623
+ return (InfSupDouble::is_empty(inter) || InfSupDouble::inf(inter) >= 0.0) ? Qtrue : Qfalse;
624
+ }
625
+
626
+
627
+
628
+ /* [๐’”๐’†๐’๐’‡] โŠ‚ [0, +โˆž]
629
+ *
630
+ * _true_ if [๐’”๐’†๐’๐’‡] = โˆ… โˆจ <span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span> > 0<br/>
631
+ * _false_ otherwise
632
+ * @return [Boolean]
633
+ */
634
+ static VALUE p1788_interval_strictly_positive(VALUE self)
635
+ {
636
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
637
+ return (InfSupDouble::is_empty(inter) || InfSupDouble::inf(inter) > 0.0) ? Qtrue : Qfalse;
638
+ }
639
+
640
+
641
+ /* [๐’”๐’†๐’๐’‡] โІ [-โˆž, 0]
642
+ *
643
+ * _true_ if [๐’”๐’†๐’๐’‡] = โˆ… โˆจ <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span> โ‰ค 0<br/>
644
+ * _false_ otherwise
645
+ * @return [Boolean]
646
+ */
647
+ static VALUE p1788_interval_negative(VALUE self)
648
+ {
649
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
650
+ return (InfSupDouble::is_empty(inter) || InfSupDouble::sup(inter) <= 0.0) ? Qtrue : Qfalse;
651
+ }
652
+
653
+
654
+
655
+ /* [๐’”๐’†๐’๐’‡] โŠ‚ [-โˆž, 0]
656
+ *
657
+ * _true_ if [๐’”๐’†๐’๐’‡] = โˆ… โˆจ <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span> < 0<br/>
658
+ * _false_ otherwise
659
+ * @return [Boolean]
660
+ */
661
+ static VALUE p1788_interval_strictly_negative(VALUE self)
662
+ {
663
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
664
+ return (InfSupDouble::is_empty(inter) || InfSupDouble::sup(inter) < 0.0) ? Qtrue : Qfalse;
665
+ }
666
+
667
+
668
+
669
+ /* _self_ is a bounded nonempty interval
670
+ * @return [Boolean]
671
+ */
672
+ static VALUE p1788_interval_common(VALUE self)
673
+ {
674
+ return InfSupDouble::is_common_interval(p1788_interval_rb2ref(self)) ? Qtrue : Qfalse;
675
+ }
676
+
677
+
678
+ /* _self_ is empty or a bounded interval
679
+ * @return [Boolean]
680
+ */
681
+ static VALUE p1788_interval_finite(VALUE self)
682
+ {
683
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
684
+ return (InfSupDouble::is_empty(inter) || InfSupDouble::is_common_interval(inter)) ? Qtrue : Qfalse;
685
+ }
686
+
687
+
688
+ /* The lower bound of _self_ is the opposite of the upper bound.
689
+ * An empty interval is not symmetric.
690
+ * @return [Boolean]
691
+ */
692
+ static VALUE p1788_interval_symmetric(VALUE self)
693
+ {
694
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
695
+ return (InfSupDouble::is_empty(inter) || InfSupDouble::inf(inter) != -InfSupDouble::sup(inter)) ? Qfalse : Qtrue;
696
+ }
697
+
698
+
699
+ /* Tels if _self_ contains only one value.
700
+ * @return [Boolean]
701
+ */
702
+ static VALUE p1788_interval_singleton(VALUE self)
703
+ {
704
+ return InfSupDouble::is_singleton(p1788_interval_rb2ref(self)) ? Qtrue : Qfalse;
705
+ }
706
+
707
+
708
+ /* _self_ {==} _y_ and _y_ is an {Interval}
709
+ * @return [Boolean]
710
+ */
711
+ static VALUE p1788_interval_eql(VALUE self, VALUE y)
712
+ {
713
+ if (!rb_obj_is_kind_of(y, c_Interval))
714
+ return Qfalse;
715
+ return InfSupDouble::equal(p1788_interval_rb2ref(self), p1788_interval_rb2ref(y)) ? Qtrue : Qfalse;
716
+ }
717
+
718
+
719
+ /* _self_ = _y_
720
+ *
721
+ * (โˆ€ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], โˆƒ ๐‘ฆ โˆˆ [๐’š], ๐‘ฅ = ๐‘ฆ) โˆง (โˆ€ ๐‘ฆ โˆˆ [๐’š], โˆƒ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], ๐‘ฆ = ๐‘ฅ)
722
+ *
723
+ * _true_ if ([๐’”๐’†๐’๐’‡] = โˆ… โˆง [๐’š] = โˆ…) โˆจ ([๐’”๐’†๐’๐’‡] โ‰  โˆ… โˆง [๐’š] โ‰  โˆ… โˆง <span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span> = <span style="text-decoration:underline">๐’š</span> โˆง <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span> = <span style="text-decoration:overline">๐’š</span>)<br/>
724
+ * _false_ otherwise
725
+ * @return [Boolean]
726
+ */
727
+ static VALUE p1788_interval_equal(VALUE self, VALUE y)
728
+ {
729
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
730
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
731
+ return InfSupDouble::equal(inter, iother) ? Qtrue : Qfalse;
732
+ }
733
+
734
+
735
+ static VALUE p1788_casesubsumption_func(VALUE obj)
736
+ {
737
+ VALUE r;
738
+ P1788_NEW_RB_INTERVAL(r, p1788_rbobj2infsupdouble(obj));
739
+ return r;
740
+ }
741
+
742
+
743
+ static VALUE p1788_casesubsumption_rescue(VALUE obj, VALUE except)
744
+ {
745
+ return obj;
746
+ }
747
+
748
+ /* Case subsumption operator.
749
+ *
750
+ * Used to write `case` expressions with intervals.
751
+ *
752
+ * Returns _true_ if _obj_ can be converted to a {Interval} and _obj_ is contained in _self_, _false_ otherwise.
753
+ * @return [Boolean]
754
+ */
755
+ static VALUE p1788_interval_tripleequal(VALUE self, VALUE obj)
756
+ {
757
+ VALUE other = rb_rescue(p1788_casesubsumption_func, obj, p1788_casesubsumption_rescue, Qnil);
758
+ if (other == Qnil)
759
+ return Qfalse;
760
+ InfSupDouble &a = p1788_interval_rb2ref(self);
761
+ InfSupDouble &b = p1788_interval_rb2ref(other);
762
+ return InfSupDouble::subset(b, a) ? Qtrue : Qfalse;
763
+ }
764
+
765
+
766
+ /* _self_ is weakly less than _y_
767
+ *
768
+ * (โˆ€ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], โˆƒ ๐‘ฆ โˆˆ [๐’š], ๐‘ฅ โ‰ค ๐‘ฆ) โˆง (โˆ€ ๐‘ฆ โˆˆ [๐’š], โˆƒ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], ๐‘ฅ โ‰ค ๐‘ฆ)
769
+ *
770
+ * _true_ if ([๐’”๐’†๐’๐’‡] = โˆ… โˆง [๐’š] = โˆ…) โˆจ ([๐’”๐’†๐’๐’‡] โ‰  โˆ… โˆง [๐’š] โ‰  โˆ… โˆง <span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span> โ‰ค <span style="text-decoration:underline">๐’š</span> โˆง <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span> โ‰ค <span style="text-decoration:overline">๐’š</span>)<br/>
771
+ * _false_ otherwise
772
+ * @return [Boolean]
773
+ */
774
+ static VALUE p1788_interval_less(VALUE self, VALUE y)
775
+ {
776
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
777
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
778
+ return InfSupDouble::less(inter, iother) ? Qtrue : Qfalse;
779
+ }
780
+
781
+
782
+ /* _self_ is weakly greater than _y_
783
+ *
784
+ * (โˆ€ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], โˆƒ ๐‘ฆ โˆˆ [๐’š], ๐‘ฅ โ‰ฅ ๐‘ฆ) โˆง (โˆ€ ๐‘ฆ โˆˆ [๐’š], โˆƒ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], ๐‘ฅ โ‰ฅ ๐‘ฆ)
785
+ *
786
+ * _true_ if ([๐’”๐’†๐’๐’‡] = โˆ… โˆง [๐’š] = โˆ…) โˆจ ([๐’”๐’†๐’๐’‡] โ‰  โˆ… โˆง [๐’š] โ‰  โˆ… โˆง <span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span> โ‰ฅ <span style="text-decoration:underline">๐’š</span> โˆง <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span> โ‰ฅ <span style="text-decoration:overline">๐’š</span>)<br/>
787
+ * _false_ otherwise
788
+ * @return [Boolean]
789
+ */
790
+ static VALUE p1788_interval_greater(VALUE self, VALUE y)
791
+ {
792
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
793
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
794
+ return InfSupDouble::greater(inter, iother) ? Qtrue : Qfalse;
795
+ }
796
+
797
+
798
+ /* _self_ is strictly less than _y_
799
+ *
800
+ * (โˆ€ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], โˆƒ ๐‘ฆ โˆˆ [๐’š], ๐‘ฅ < ๐‘ฆ) โˆง (โˆ€ ๐‘ฆ โˆˆ [๐’š], โˆƒ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], ๐‘ฅ < ๐‘ฆ)
801
+ *
802
+ * _true_ if ([๐’”๐’†๐’๐’‡] = โˆ… โˆง [๐’š] = โˆ…) โˆจ ([๐’”๐’†๐’๐’‡] โ‰  โˆ… โˆง [๐’š] โ‰  โˆ… โˆง <span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span> < <span style="text-decoration:underline">๐’š</span> โˆง <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span> < <span style="text-decoration:overline">๐’š</span>)<br/>
803
+ * _false_ otherwise
804
+ * @return [Boolean]
805
+ */
806
+ static VALUE p1788_interval_strictly_less(VALUE self, VALUE y)
807
+ {
808
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
809
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
810
+ return InfSupDouble::strictly_less(inter, iother) ? Qtrue : Qfalse;
811
+ }
812
+
813
+
814
+ /* _self_ is strictly greater than _y_
815
+ *
816
+ * (โˆ€ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], โˆƒ ๐‘ฆ โˆˆ [๐’š], ๐‘ฅ > ๐‘ฆ) โˆง (โˆ€ ๐‘ฆ โˆˆ [๐’š], โˆƒ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], ๐‘ฅ > ๐‘ฆ)
817
+ *
818
+ * _true_ if ([๐’”๐’†๐’๐’‡] = โˆ… โˆง [๐’š] = โˆ…) โˆจ ([๐’”๐’†๐’๐’‡] โ‰  โˆ… โˆง [๐’š] โ‰  โˆ… โˆง <span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span> > <span style="text-decoration:underline">๐’š</span> โˆง <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span> > <span style="text-decoration:overline">๐’š</span>)<br/>
819
+ * _false_ otherwise
820
+ * @return [Boolean]
821
+ */
822
+ static VALUE p1788_interval_strictly_greater(VALUE self, VALUE y)
823
+ {
824
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
825
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
826
+ return InfSupDouble::strictly_greater(inter, iother) ? Qtrue : Qfalse;
827
+ }
828
+
829
+
830
+ /* _self_ is to the left of but may touch _y_
831
+ *
832
+ * โˆ€ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], โˆ€ ๐‘ฆ โˆˆ [๐’š], ๐‘ฅ โ‰ค ๐‘ฆ
833
+ *
834
+ * _true_ if [๐’”๐’†๐’๐’‡] = โˆ… โˆจ [๐’š] = โˆ… โˆจ <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span> โ‰ค <span style="text-decoration:underline">๐’š</span><br/>
835
+ * _false_ otherwise
836
+ * @return [Boolean]
837
+ */
838
+ static VALUE p1788_interval_precedes(VALUE self, VALUE y)
839
+ {
840
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
841
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
842
+ return InfSupDouble::precedes(inter, iother) ? Qtrue : Qfalse;
843
+ }
844
+
845
+
846
+ /* _self_ is to the right of but may touch _y_
847
+ *
848
+ * โˆ€ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], โˆ€ ๐‘ฆ โˆˆ [๐’š], ๐‘ฅ โ‰ฅ ๐‘ฆ
849
+ *
850
+ * _true_ if [๐’”๐’†๐’๐’‡] = โˆ… โˆจ [๐’š] = โˆ… โˆจ <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span> โ‰ฅ <span style="text-decoration:underline">๐’š</span><br/>
851
+ * _false_ otherwise
852
+ * @return [Boolean]
853
+ */
854
+ static VALUE p1788_interval_succeeds(VALUE self, VALUE y)
855
+ {
856
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
857
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
858
+ return InfSupDouble::succeeds(inter, iother) ? Qtrue : Qfalse;
859
+ }
860
+
861
+
862
+ /* _self_ is strictly to the left of _y_
863
+ *
864
+ * โˆ€ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], โˆ€ ๐‘ฆ โˆˆ [๐’š], ๐‘ฅ < ๐‘ฆ
865
+ *
866
+ * _true_ if [๐’”๐’†๐’๐’‡] = โˆ… โˆจ [๐’š] = โˆ… โˆจ <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span> < <span style="text-decoration:underline">๐’š</span><br/>
867
+ * _false_ otherwise
868
+ * @return [Boolean]
869
+ */
870
+ static VALUE p1788_interval_strictly_precedes(VALUE self, VALUE y)
871
+ {
872
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
873
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
874
+ return InfSupDouble::strictly_precedes(inter, iother) ? Qtrue : Qfalse;
875
+ }
876
+
877
+
878
+ /* _self_ is strictly to the right of _y_
879
+ *
880
+ * โˆ€ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], โˆ€ ๐‘ฆ โˆˆ [๐’š], ๐‘ฅ > ๐‘ฆ
881
+ *
882
+ * _true_ if [๐’”๐’†๐’๐’‡] = โˆ… โˆจ [๐’š] = โˆ… โˆจ <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span> > <span style="text-decoration:underline">๐’š</span><br/>
883
+ * _false_ otherwise
884
+ * @return [Boolean]
885
+ */
886
+ static VALUE p1788_interval_strictly_succeeds(VALUE self, VALUE y)
887
+ {
888
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
889
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
890
+ return InfSupDouble::strictly_succeeds(inter, iother) ? Qtrue : Qfalse;
891
+ }
892
+
893
+
894
+ /* [๐’”๐’†๐’๐’‡] โˆฉ [๐’š] = โˆ…
895
+ *
896
+ * โˆ€ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], โˆ€ ๐‘ฆ โˆˆ [๐’š], ๐‘ฅ โ‰  ๐‘ฆ
897
+ *
898
+ * _true_ if [๐’”๐’†๐’๐’‡] = โˆ… โˆจ [๐’š] = โˆ… โˆจ <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span> < <span style="text-decoration:underline">๐’š</span> โˆจ <span style="text-decoration:overline">๐’š</span> < <span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span><br/>
899
+ * _false_ otherwise
900
+ * @see intersect
901
+ * @return [Boolean]
902
+ */
903
+ static VALUE p1788_interval_disjoint(VALUE self, VALUE y)
904
+ {
905
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
906
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
907
+ return InfSupDouble::disjoint(inter, iother) ? Qtrue : Qfalse;
908
+ }
909
+
910
+
911
+ /* [๐’”๐’†๐’๐’‡] โˆฉ [๐’š] โ‰  โˆ…
912
+ *
913
+ * โˆƒ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], โˆƒ ๐‘ฆ โˆˆ [๐’š], ๐‘ฅ = ๐‘ฆ
914
+ *
915
+ * _true_ if [๐’”๐’†๐’๐’‡] โ‰  โˆ… โˆง [๐’š] โ‰  โˆ… โˆง <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span> โ‰ฅ <span style="text-decoration:underline">๐’š</span> โˆง <span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span> โ‰ค <span style="text-decoration:overline">๐’š</span><br/>
916
+ * _false_ otherwise
917
+ * @see disjoint_from
918
+ * @return [Boolean]
919
+ */
920
+ static VALUE p1788_interval_intersect(VALUE self, VALUE y)
921
+ {
922
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
923
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
924
+ if (InfSupDouble::is_empty(inter) || InfSupDouble::is_empty(iother))
925
+ return Qfalse;
926
+ double al = InfSupDouble::inf(inter);
927
+ double au = InfSupDouble::sup(inter);
928
+ double bl = InfSupDouble::inf(iother);
929
+ double bu = InfSupDouble::sup(iother);
930
+ return (au >= bl && al <= bu) ? Qtrue : Qfalse;
931
+ }
932
+
933
+
934
+ /* _self_ is interior to _y_
935
+ *
936
+ * [๐’”๐’†๐’๐’‡] โŠ‚ [๐’š]
937
+ *
938
+ * (โˆ€ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], โˆƒ ๐‘ฆ โˆˆ [๐’š] : ๐‘ฅ > ๐‘ฆ) โˆง (โˆ€ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], โˆƒ ๐‘ฆ โˆˆ [๐’š] : ๐‘ฅ < ๐‘ฆ )
939
+ *
940
+ * _true_ if [๐’”๐’†๐’๐’‡] = โˆ… โˆจ ([๐’š] โ‰  โˆ… โˆง <span style="text-decoration:underline">๐’š</span> < <span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span> โˆง <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span> < <span style="text-decoration:overline">๐’š</span>)<br/>
941
+ * _false_ otherwise
942
+ * @see subset_of?
943
+ * @see strictly_contain?
944
+ * @return [Boolean]
945
+ */
946
+ static VALUE p1788_interval_strict_subset(VALUE self, VALUE y)
947
+ {
948
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
949
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
950
+ return InfSupDouble::interior(inter, iother) ? Qtrue : Qfalse;
951
+ }
952
+
953
+
954
+ /* _y_ is interior to _self_
955
+ *
956
+ * [๐’š] โŠ‚ [๐’”๐’†๐’๐’‡]
957
+ *
958
+ * (โˆ€ ๐‘ฆ โˆˆ [๐’š], โˆƒ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡] : ๐‘ฆ < ๐‘ฅ) โˆง (โˆ€ ๐‘ฆ โˆˆ [๐’š], โˆƒ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡] : ๐‘ฆ > ๐‘ฅ)
959
+ *
960
+ * _true_ if [๐’š] = โˆ… โˆจ ([๐’”๐’†๐’๐’‡] โ‰  โˆ… โˆง <span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span> < <span style="text-decoration:underline">๐’š</span> โˆง <span style="text-decoration:overline">๐’š</span> < <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span>)<br/>
961
+ * _false_ otherwise
962
+ * @see strict_subset_of?
963
+ * @see contain?
964
+ * @return [Boolean]
965
+ */
966
+ static VALUE p1788_interval_strictly_contain(VALUE self, VALUE y)
967
+ {
968
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
969
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
970
+ return InfSupDouble::interior(iother, inter) ? Qtrue : Qfalse;
971
+ }
972
+
973
+
974
+ /* _self_ is a subset or equal to _y_
975
+ *
976
+ * [๐’”๐’†๐’๐’‡] โІ [๐’š]
977
+ *
978
+ * โˆ€ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], โˆƒ ๐‘ฆ โˆˆ [๐’š] : ๐‘ฅ = ๐‘ฆ
979
+ *
980
+ * _true_ if [๐’”๐’†๐’๐’‡] = โˆ… โˆจ ([๐’š] โ‰  โˆ… โˆง <span style="text-decoration:underline">๐’š</span> โ‰ค <span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span> โˆง <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span> โ‰ค <span style="text-decoration:overline">๐’š</span>)<br/>
981
+ * _false_ otherwise
982
+ * @see contain?
983
+ * @see strict_subset_of?
984
+ * @return [Boolean]
985
+ */
986
+ static VALUE p1788_interval_subset(VALUE self, VALUE y)
987
+ {
988
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
989
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
990
+ return InfSupDouble::subset(inter, iother) ? Qtrue : Qfalse;
991
+ }
992
+
993
+
994
+ /* _y_ is a subset or equal to _self_
995
+ *
996
+ * [๐’š] โІ [๐’”๐’†๐’๐’‡]
997
+ *
998
+ * โˆ€ ๐‘ฆ โˆˆ [๐’š], โˆƒ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡] : ๐‘ฆ = ๐‘ฅ
999
+ *
1000
+ * _true_ if [๐’š] = โˆ… โˆจ ([๐’”๐’†๐’๐’‡] โ‰  โˆ… โˆง <span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span> โ‰ค <span style="text-decoration:underline">๐’š</span> โˆง <span style="text-decoration:overline">๐’š</span> โ‰ค <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span>)<br/>
1001
+ * _false_ otherwise
1002
+ * @see subset_of?
1003
+ * @see strictly_contain?
1004
+ * @return [Boolean]
1005
+ */
1006
+ static VALUE p1788_interval_contain(VALUE self, VALUE y)
1007
+ {
1008
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1009
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
1010
+ return InfSupDouble::subset(iother, inter) ? Qtrue : Qfalse;
1011
+ }
1012
+
1013
+
1014
+ /* _y_ is a member of _self_
1015
+ *
1016
+ * ๐‘ฆ โˆˆ [๐’”๐’†๐’๐’‡]
1017
+ *
1018
+ * _true_ if [๐’”๐’†๐’๐’‡] โ‰  โˆ… โˆง <span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span> โ‰ค ๐‘ฆ โˆง ๐‘ฆ โ‰ค <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span> โˆง ๐‘ฆ โ‰  ยฑโˆž<br/>
1019
+ * _false_ otherwise
1020
+ * @param y [Numeric]
1021
+ * @return [Boolean]
1022
+ */
1023
+ static VALUE p1788_interval_include(VALUE self, VALUE y)
1024
+ {
1025
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1026
+ double od = NUM2DBL(y);
1027
+ return InfSupDouble::is_member(od, inter) ? Qtrue : Qfalse;
1028
+ }
1029
+
1030
+ /* Numeric functions on intervals */
1031
+
1032
+
1033
+ /* Lower bound of the interval.
1034
+ * Returns _nil_ if the interval is empty.
1035
+ * @return [Float, nil]
1036
+ */
1037
+ static VALUE p1788_interval_inf(VALUE self)
1038
+ {
1039
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1040
+ if (InfSupDouble::is_empty(inter))
1041
+ return Qnil;
1042
+ return DBL2NUM(InfSupDouble::inf(inter));
1043
+ }
1044
+
1045
+
1046
+ /* Upper bound of the interval.
1047
+ * Returns _nil_ if the interval is empty.
1048
+ * @return [Float, nil]
1049
+ */
1050
+ static VALUE p1788_interval_sup(VALUE self)
1051
+ {
1052
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1053
+ if (InfSupDouble::is_empty(inter))
1054
+ return Qnil;
1055
+ return DBL2NUM(InfSupDouble::sup(inter));
1056
+ }
1057
+
1058
+
1059
+ static double p1788_interval_splitpoint_double(const InfSupDouble& inter)
1060
+ {
1061
+ if (InfSupDouble::is_empty(inter))
1062
+ return std::numeric_limits<double>::quiet_NaN();
1063
+ if (InfSupDouble::wid(inter) == INF) {
1064
+ double lb = InfSupDouble::inf(inter);
1065
+ double ub = InfSupDouble::sup(inter);
1066
+ if (lb == -INF) {
1067
+ if (ub == INF)
1068
+ return 0.0;
1069
+ return -MAXF;
1070
+ }
1071
+ return MAXF;
1072
+ }
1073
+ return InfSupDouble::mid(inter);
1074
+ }
1075
+
1076
+
1077
+ /* Split point used to bisect
1078
+ *
1079
+ * Split point is:<br/>
1080
+ * (<span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span> + <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span>)/2 if [๐’”๐’†๐’๐’‡] is nonempty and bounded,<br/>
1081
+ * `0` if [๐’”๐’†๐’๐’‡] = โ„,<br/>
1082
+ * `-Float::MAX` if <span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span> = -โˆž<br/>
1083
+ * `Float::MAX` if <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span> = +โˆž<br/>
1084
+ * `nil` if [๐’”๐’†๐’๐’‡] = โˆ…
1085
+ * @return [Float, nil]
1086
+ */
1087
+ static VALUE p1788_interval_splitpoint(VALUE self)
1088
+ {
1089
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1090
+ double sp = p1788_interval_splitpoint_double(inter);
1091
+ if (std::isnan(sp))
1092
+ return Qnil;
1093
+ return DBL2NUM(sp);
1094
+ }
1095
+
1096
+
1097
+ /* Midpoint of _self_
1098
+ *
1099
+ * Midpoint is (<span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span> + <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span>)/2 if [๐’”๐’†๐’๐’‡] โ‰  โˆ… and [๐’”๐’†๐’๐’‡] is bounded, nil otherwise
1100
+ * @return [Float, nil]
1101
+ */
1102
+ static VALUE p1788_interval_mid(VALUE self)
1103
+ {
1104
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1105
+ if (InfSupDouble::is_empty(inter) || InfSupDouble::wid(inter) == INF)
1106
+ return Qnil;
1107
+ double mid = InfSupDouble::mid(inter);
1108
+ if (std::isnan(mid))
1109
+ return Qnil;
1110
+ return DBL2NUM(mid);
1111
+ }
1112
+
1113
+
1114
+ /* Radius of _self_
1115
+ *
1116
+ * Radius is (<span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span> - <span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span>)/2 if [๐’”๐’†๐’๐’‡] โ‰  โˆ…, nil if [๐’”๐’†๐’๐’‡] = โˆ…
1117
+ * @return [Float, nil]
1118
+ */
1119
+ static VALUE p1788_interval_rad(VALUE self)
1120
+ {
1121
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1122
+ if (InfSupDouble::is_empty(inter))
1123
+ return Qnil;
1124
+ return DBL2NUM(InfSupDouble::rad(inter));
1125
+ }
1126
+
1127
+
1128
+ /* Midpoint and radius
1129
+ * @return [Array<Float,nil>] [{midpoint}, {radius}]
1130
+ */
1131
+ static VALUE p1788_interval_mid_rad(VALUE self)
1132
+ {
1133
+ std::pair< double, double > p = InfSupDouble::mid_rad(p1788_interval_rb2ref(self));
1134
+ VALUE r1 = DBL2NUM(p.first);
1135
+ VALUE r2 = DBL2NUM(p.second);
1136
+ if (std::isnan(p.first))
1137
+ r1 = Qnil;
1138
+ if (std::isnan(p.second))
1139
+ r2 = Qnil;
1140
+ return rb_ary_new_from_args(2, r1, r2);
1141
+ }
1142
+
1143
+
1144
+ /* Width of _self_
1145
+ *
1146
+ * Width is <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span> - <span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span> if [๐’”๐’†๐’๐’‡] โ‰  โˆ…, nil if [๐’”๐’†๐’๐’‡] = โˆ…
1147
+ *
1148
+ * @return [Float, nil]
1149
+ */
1150
+ static VALUE p1788_interval_wid(VALUE self)
1151
+ {
1152
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1153
+ if (InfSupDouble::is_empty(inter))
1154
+ return Qnil;
1155
+ return DBL2NUM(InfSupDouble::wid(inter));
1156
+ }
1157
+
1158
+
1159
+ /* Magnitude of _self_
1160
+ *
1161
+ * [๐’”๐’†๐’๐’‡].mignitudeย ย =ย ย sup{ \|๐‘ฅ\| ๏ฟจ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡] } if [๐’”๐’†๐’๐’‡] โ‰  โˆ…, nil if [๐’”๐’†๐’๐’‡] = โˆ…
1162
+ * @return [Float, nil]
1163
+ */
1164
+ static VALUE p1788_interval_mag(VALUE self)
1165
+ {
1166
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1167
+ if (InfSupDouble::is_empty(inter))
1168
+ return Qnil;
1169
+ return DBL2NUM(InfSupDouble::mag(inter));
1170
+ }
1171
+
1172
+
1173
+ /* Mignitude of _self_
1174
+ *
1175
+ * [๐’”๐’†๐’๐’‡].mignitudeย ย =ย ย inf{ \|๐‘ฅ\| ๏ฟจ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡] } if [๐’”๐’†๐’๐’‡] โ‰  โˆ…, nil if [๐’”๐’†๐’๐’‡] = โˆ…
1176
+ * @return [Float, nil]
1177
+ */
1178
+ static VALUE p1788_interval_mig(VALUE self)
1179
+ {
1180
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1181
+ if (InfSupDouble::is_empty(inter))
1182
+ return Qnil;
1183
+ return DBL2NUM(InfSupDouble::mig(inter));
1184
+ }
1185
+
1186
+
1187
+ /* Split _self_ into two intervals using {splitpoint}.
1188
+ * @return [Array[Interval]] An Array of two intervals
1189
+ */
1190
+ static VALUE p1788_interval_bisect(VALUE self)
1191
+ {
1192
+ VALUE r1, r2;
1193
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1194
+ double midpoint = p1788_interval_splitpoint_double(inter);
1195
+ if (std::isnan(midpoint)) {
1196
+ P1788_NEW_RB_INTERVAL(r2, InfSupDouble());
1197
+ return rb_ary_new_from_args(2, self, r2);
1198
+ }
1199
+ const double lb = InfSupDouble::inf(inter);
1200
+ const double ub = InfSupDouble::sup(inter);
1201
+ InfSupDouble i1(lb, midpoint);
1202
+ InfSupDouble i2(midpoint, ub);
1203
+ if (i1 == i2) {
1204
+ P1788_NEW_RB_INTERVAL(r2, InfSupDouble());
1205
+ return rb_ary_new_from_args(2, self, r2);
1206
+ }
1207
+ P1788_NEW_RB_INTERVAL(r1, i1);
1208
+ P1788_NEW_RB_INTERVAL(r2, i2);
1209
+ return rb_ary_new_from_args(2, r1, r2);
1210
+ }
1211
+
1212
+
1213
+ /* Set operations */
1214
+
1215
+
1216
+ /* Intersection
1217
+ *
1218
+ * [๐’”๐’†๐’๐’‡].intersection([๐’š])ย ย =ย ย [๐’”๐’†๐’๐’‡] โˆฉ [๐’š]
1219
+ */
1220
+ static VALUE p1788_interval_intersection(VALUE self, VALUE y)
1221
+ {
1222
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
1223
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1224
+ VALUE r;
1225
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::intersection(inter, iother));
1226
+ return r;
1227
+ }
1228
+
1229
+
1230
+ /* Interval hull of the union of _self_ and _y_
1231
+ *
1232
+ * [๐’”๐’†๐’๐’‡].convex_hull([๐’š])ย ย =ย ย hull( [๐’”๐’†๐’๐’‡] โˆช [๐’š] )
1233
+ */
1234
+ static VALUE p1788_interval_convex_hull(VALUE self, VALUE y)
1235
+ {
1236
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
1237
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1238
+ VALUE r;
1239
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::convex_hull(inter, iother));
1240
+ return r;
1241
+ }
1242
+
1243
+
1244
+ /* Forward elementary functions */
1245
+
1246
+
1247
+ /* @return [Interval] `self`
1248
+ */
1249
+ static VALUE p1788_interval_pos(VALUE self)
1250
+ {
1251
+ VALUE r;
1252
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::pos(p1788_interval_rb2ref(self)));
1253
+ return r;
1254
+ }
1255
+
1256
+
1257
+ /* Opposite
1258
+ *
1259
+ * [๐’”๐’†๐’๐’‡].negย ย =ย ย [-<span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span>, -<span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span>]
1260
+ */
1261
+ static VALUE p1788_interval_neg(VALUE self)
1262
+ {
1263
+ VALUE r;
1264
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::neg(p1788_interval_rb2ref(self)));
1265
+ return r;
1266
+ }
1267
+
1268
+
1269
+ /* Reciprocal
1270
+ *
1271
+ * [๐’”๐’†๐’๐’‡].recipย ย =ย ย hull{ 1/๐‘ฅ \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย โ„
1272
+ *
1273
+ * Reverse function: {recip}
1274
+ */
1275
+ static VALUE p1788_interval_recip(VALUE self)
1276
+ {
1277
+ VALUE r;
1278
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::recip(p1788_interval_rb2ref(self)));
1279
+ return r;
1280
+ }
1281
+
1282
+
1283
+ /* Square
1284
+ *
1285
+ * [๐’”๐’†๐’๐’‡].sqrย ย =ย ย hull{ ๐‘ฅยฒ \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย โ„โ‚Š
1286
+ *
1287
+ * Reverse function: {sqr_rev}
1288
+ */
1289
+ static VALUE p1788_interval_sqr(VALUE self)
1290
+ {
1291
+ VALUE r;
1292
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::sqr(p1788_interval_rb2ref(self)));
1293
+ return r;
1294
+ }
1295
+
1296
+
1297
+ /* Square root
1298
+ *
1299
+ * [๐’”๐’†๐’๐’‡].sqrtย ย =ย ย hull{ ๐‘ฅ<sup>ยฝ</sup> \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡]โˆฉโ„โ‚Š }ย ย โІย ย โ„โ‚Š
1300
+ *
1301
+ * Reverse function: {sqr}
1302
+ */
1303
+ static VALUE p1788_interval_sqrt(VALUE self)
1304
+ {
1305
+ VALUE r;
1306
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::sqrt(p1788_interval_rb2ref(self)));
1307
+ return r;
1308
+ }
1309
+
1310
+
1311
+ /* _e_ raised to the power of _self_
1312
+ *
1313
+ * [๐’”๐’†๐’๐’‡].expย ย =ย ย hull{ ๐‘’<sup>๐‘ฅ</sup> \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย โ„โ‚Š
1314
+ *
1315
+ * Reverse function: {log}
1316
+ */
1317
+ static VALUE p1788_interval_exp(VALUE self)
1318
+ {
1319
+ VALUE r;
1320
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::exp(p1788_interval_rb2ref(self)));
1321
+ return r;
1322
+ }
1323
+
1324
+
1325
+ /* 2 raised to the power of _self_
1326
+ *
1327
+ * [๐’”๐’†๐’๐’‡].exp2ย ย =ย ย hull{ 2<sup>๐‘ฅ</sup> \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย โ„โ‚Š
1328
+ *
1329
+ * Reverse function: {log2}
1330
+ */
1331
+ static VALUE p1788_interval_exp2(VALUE self)
1332
+ {
1333
+ VALUE r;
1334
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::exp2(p1788_interval_rb2ref(self)));
1335
+ return r;
1336
+ }
1337
+
1338
+
1339
+ /* 10 raised to the power of _self_
1340
+ *
1341
+ * [๐’”๐’†๐’๐’‡].exp10ย ย =ย ย hull{ 10<sup>๐‘ฅ</sup> \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย โ„โ‚Š
1342
+ *
1343
+ * Reverse function: {log10}
1344
+ */
1345
+ static VALUE p1788_interval_exp10(VALUE self)
1346
+ {
1347
+ VALUE r;
1348
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::exp10(p1788_interval_rb2ref(self)));
1349
+ return r;
1350
+ }
1351
+
1352
+
1353
+ /* Natural logarithm
1354
+ *
1355
+ * [๐’”๐’†๐’๐’‡].logย ย =ย ย hull{ ln(๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡]โˆฉโ„โ‚Š }ย ย โІย ย โ„
1356
+ *
1357
+ * Reverse function: {exp}
1358
+ */
1359
+ static VALUE p1788_interval_log(VALUE self)
1360
+ {
1361
+ VALUE r;
1362
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::log(p1788_interval_rb2ref(self)));
1363
+ return r;
1364
+ }
1365
+
1366
+
1367
+ /* Base 2 logarithm
1368
+ *
1369
+ * [๐’”๐’†๐’๐’‡].log2ย ย =ย ย hull{ ln(๐‘ฅ)/ln(2) \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡]โˆฉโ„โ‚Š }ย ย โІย ย โ„
1370
+ *
1371
+ * Reverse function: {exp2}
1372
+ */
1373
+ static VALUE p1788_interval_log2(VALUE self)
1374
+ {
1375
+ VALUE r;
1376
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::log2(p1788_interval_rb2ref(self)));
1377
+ return r;
1378
+ }
1379
+
1380
+
1381
+ /* Base 10 logarithm
1382
+ *
1383
+ * [๐’”๐’†๐’๐’‡].log10ย ย =ย ย hull{ ln(๐‘ฅ)/ln(10) \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡]โˆฉโ„โ‚Š }ย ย โІย ย โ„
1384
+ *
1385
+ * Reverse function: {exp10}
1386
+ */
1387
+ static VALUE p1788_interval_log10(VALUE self)
1388
+ {
1389
+ VALUE r;
1390
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::log10(p1788_interval_rb2ref(self)));
1391
+ return r;
1392
+ }
1393
+
1394
+
1395
+ /* Sine
1396
+ *
1397
+ * [๐’”๐’†๐’๐’‡].sinย ย =ย ย hull{ sin(๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย [-1, 1]
1398
+ *
1399
+ * Reverse function: {sin_rev}
1400
+ */
1401
+ static VALUE p1788_interval_sin(VALUE self)
1402
+ {
1403
+ VALUE r;
1404
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::sin(p1788_interval_rb2ref(self)));
1405
+ return r;
1406
+ }
1407
+
1408
+
1409
+ /* Cosine
1410
+ *
1411
+ * [๐’”๐’†๐’๐’‡].cosย ย =ย ย hull{ cos(๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย [-1, 1]
1412
+ *
1413
+ * Reverse function: {cos_rev}
1414
+ */
1415
+ static VALUE p1788_interval_cos(VALUE self)
1416
+ {
1417
+ VALUE r;
1418
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::cos(p1788_interval_rb2ref(self)));
1419
+ return r;
1420
+ }
1421
+
1422
+
1423
+ /* Tangent
1424
+ *
1425
+ * [๐’”๐’†๐’๐’‡].tanย ย =ย ย hull{ tan(๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย โ„
1426
+ *
1427
+ * Reverse function: {tan_rev}
1428
+ */
1429
+ static VALUE p1788_interval_tan(VALUE self)
1430
+ {
1431
+ VALUE r;
1432
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::tan(p1788_interval_rb2ref(self)));
1433
+ return r;
1434
+ }
1435
+
1436
+
1437
+ /* Arc sine
1438
+ *
1439
+ * [๐’”๐’†๐’๐’‡].asinย ย =ย ย hull{ asin(๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡]โˆฉ[-1, 1] }ย ย โІย ย [-๐›‘/2, ๐›‘/2]
1440
+ *
1441
+ * Reverse function: {sin}
1442
+ */
1443
+ static VALUE p1788_interval_asin(VALUE self)
1444
+ {
1445
+ VALUE r;
1446
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::asin(p1788_interval_rb2ref(self)));
1447
+ return r;
1448
+ }
1449
+
1450
+
1451
+ /* Arc cosine
1452
+ *
1453
+ * [๐’”๐’†๐’๐’‡].acosย ย =ย ย hull{ acos(๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡]โˆฉ[-1, 1] }ย ย โІย ย [0, ๐›‘]
1454
+ *
1455
+ * Reverse function: {cos}
1456
+ */
1457
+ static VALUE p1788_interval_acos(VALUE self)
1458
+ {
1459
+ VALUE r;
1460
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::acos(p1788_interval_rb2ref(self)));
1461
+ return r;
1462
+ }
1463
+
1464
+
1465
+ /* Arc tangent
1466
+ *
1467
+ * [๐’”๐’†๐’๐’‡].atanย ย =ย ย hull{ atan(๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย [-๐›‘/2, ๐›‘/2]ย 
1468
+ *
1469
+ * Reverse function: {tan}
1470
+ */
1471
+ static VALUE p1788_interval_atan(VALUE self)
1472
+ {
1473
+ VALUE r;
1474
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::atan(p1788_interval_rb2ref(self)));
1475
+ return r;
1476
+ }
1477
+
1478
+
1479
+ /* Hyperbolic sine
1480
+ *
1481
+ * [๐’”๐’†๐’๐’‡].sinhย ย =ย ย hull{ (๐‘’<sup>๐‘ฅ</sup> - ๐‘’<sup>-๐‘ฅ</sup>) / 2 \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย โ„
1482
+ *
1483
+ * Reverse function: {asinh}
1484
+ */
1485
+ static VALUE p1788_interval_sinh(VALUE self)
1486
+ {
1487
+ VALUE r;
1488
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::sinh(p1788_interval_rb2ref(self)));
1489
+ return r;
1490
+ }
1491
+
1492
+
1493
+ /* Hyperbolic cosine
1494
+ *
1495
+ * [๐’”๐’†๐’๐’‡].coshย ย =ย ย hull{ (๐‘’<sup>๐‘ฅ</sup> + ๐‘’<sup>-๐‘ฅ</sup>) / 2 \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย [1, +โˆž]
1496
+ *
1497
+ * Reverse function: {cosh_rev}
1498
+ */
1499
+ static VALUE p1788_interval_cosh(VALUE self)
1500
+ {
1501
+ VALUE r;
1502
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::cosh(p1788_interval_rb2ref(self)));
1503
+ return r;
1504
+ }
1505
+
1506
+
1507
+ /* Hyperbolic tangent
1508
+ *
1509
+ * [๐’”๐’†๐’๐’‡].tanhย ย =ย ย hull{ sinh(๐‘ฅ) / cosh(๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย [-1, 1]
1510
+ *
1511
+ * Reverse function: {atanh}
1512
+ */
1513
+ static VALUE p1788_interval_tanh(VALUE self)
1514
+ {
1515
+ VALUE r;
1516
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::tanh(p1788_interval_rb2ref(self)));
1517
+ return r;
1518
+ }
1519
+
1520
+
1521
+ /* Inverse hyperbolic sine
1522
+ *
1523
+ * [๐’”๐’†๐’๐’‡].asinhย ย =ย ย hull{ asinh(๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย โ„
1524
+ *
1525
+ * Reverse function: {sinh}
1526
+ */
1527
+ static VALUE p1788_interval_asinh(VALUE self)
1528
+ {
1529
+ VALUE r;
1530
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::asinh(p1788_interval_rb2ref(self)));
1531
+ return r;
1532
+ }
1533
+
1534
+
1535
+ /* Inverse hyperbolic cosine
1536
+ *
1537
+ * [๐’”๐’†๐’๐’‡].acoshย ย =ย ย hull{ acosh(๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡]โˆฉ[1,+โˆž] }ย ย โІย ย โ„โ‚Š
1538
+ *
1539
+ * Reverse function: {cosh}
1540
+ */
1541
+ static VALUE p1788_interval_acosh(VALUE self)
1542
+ {
1543
+ VALUE r;
1544
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::acosh(p1788_interval_rb2ref(self)));
1545
+ return r;
1546
+ }
1547
+
1548
+
1549
+ /* Inverse hyperbolic tangent
1550
+ *
1551
+ * [๐’”๐’†๐’๐’‡].atanhย ย =ย ย hull{ atanh(๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡]โˆฉ[-1,1] }ย ย โІย ย โ„
1552
+ *
1553
+ * Reverse function: {tanh}
1554
+ */
1555
+ static VALUE p1788_interval_atanh(VALUE self)
1556
+ {
1557
+ VALUE r;
1558
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::atanh(p1788_interval_rb2ref(self)));
1559
+ return r;
1560
+ }
1561
+
1562
+
1563
+ /* Sign of _self_
1564
+ *
1565
+ * [๐’”๐’†๐’๐’‡].signย ย โІย ย [-1, 1]ย ย (\\{-1} if <span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span> < 0, \\{1} if <span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span> > 0, \\{0} if [๐’”๐’†๐’๐’‡] = \\{0})
1566
+ */
1567
+ static VALUE p1788_interval_sign(VALUE self)
1568
+ {
1569
+ VALUE r;
1570
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::sign(p1788_interval_rb2ref(self)));
1571
+ return r;
1572
+ }
1573
+
1574
+
1575
+ /* Round towards +โˆž
1576
+ *
1577
+ * [๐’”๐’†๐’๐’‡].ceilย ย =ย ย [ceil(<span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span>), ceil(<span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span>)]
1578
+ */
1579
+ static VALUE p1788_interval_ceil(VALUE self)
1580
+ {
1581
+ VALUE r;
1582
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::ceil(p1788_interval_rb2ref(self)));
1583
+ return r;
1584
+ }
1585
+
1586
+
1587
+ /* Round towards -โˆž
1588
+ *
1589
+ * [๐’”๐’†๐’๐’‡].floorย ย =ย ย [floor(<span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span>), floor(<span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span>)]
1590
+ */
1591
+ static VALUE p1788_interval_floor(VALUE self)
1592
+ {
1593
+ VALUE r;
1594
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::floor(p1788_interval_rb2ref(self)));
1595
+ return r;
1596
+ }
1597
+
1598
+
1599
+ /* Inflate _self_ towards nearest integer bounds
1600
+ *
1601
+ * [๐’”๐’†๐’๐’‡].floorceilย ย =ย ย [floor(<span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span>), ceil(<span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span>)]
1602
+ */
1603
+ static VALUE p1788_interval_floorceil(VALUE self)
1604
+ {
1605
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1606
+ VALUE r;
1607
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble(std::floor(InfSupDouble::inf(inter)), std::ceil(InfSupDouble::sup(inter))));
1608
+ return r;
1609
+ }
1610
+
1611
+
1612
+ /* Round towards 0
1613
+ *
1614
+ * [๐’”๐’†๐’๐’‡].truncย ย =ย ย [trunc(<span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span>), trunc(<span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span>)]
1615
+ */
1616
+ static VALUE p1788_interval_trunc(VALUE self)
1617
+ {
1618
+ VALUE r;
1619
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::trunc(p1788_interval_rb2ref(self)));
1620
+ return r;
1621
+ }
1622
+
1623
+
1624
+ /* Round, ties to even
1625
+ *
1626
+ * Round bounds of _self_ to their nearest integer values, rounding halfway cases to nearest even.
1627
+ *
1628
+ * [๐’”๐’†๐’๐’‡].round_ties_to_evenย ย =ย ย [round_ties_to_even(<span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span>), round_ties_to_even(<span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span>)]
1629
+ */
1630
+ static VALUE p1788_interval_round_ties_to_even(VALUE self)
1631
+ {
1632
+ VALUE r;
1633
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::round_ties_to_even(p1788_interval_rb2ref(self)));
1634
+ return r;
1635
+ }
1636
+
1637
+
1638
+ /* Round, ties to away from zero
1639
+ *
1640
+ * Round bounds of _self_ to their nearest integer values, rounding halfway cases away from zero.
1641
+ *
1642
+ * [๐’”๐’†๐’๐’‡].round_ties_to_awayย ย =ย ย [round_ties_to_away(<span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span>), round_ties_to_away(<span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span>)]
1643
+ */
1644
+ static VALUE p1788_interval_round_ties_to_away(VALUE self)
1645
+ {
1646
+ VALUE r;
1647
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::round_ties_to_away(p1788_interval_rb2ref(self)));
1648
+ return r;
1649
+ }
1650
+
1651
+
1652
+ /* Absolute value
1653
+ *
1654
+ * [๐’”๐’†๐’๐’‡].absย ย =ย ย hull{ \|๐‘ฅ\| ๏ฟจ ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย โ„โ‚Š
1655
+ *
1656
+ * Reverse function: {abs_rev}
1657
+ */
1658
+ static VALUE p1788_interval_abs(VALUE self)
1659
+ {
1660
+ VALUE r;
1661
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::abs(p1788_interval_rb2ref(self)));
1662
+ return r;
1663
+ }
1664
+
1665
+
1666
+ /* Arithmetic addition
1667
+ *
1668
+ * [๐’”๐’†๐’๐’‡] + [๐’š]ย ย =ย ย hull{ ๐‘ฅ + ๐‘ฆ \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], ๐‘ฆ โˆˆ [๐’š] }ย ย โІย ย โ„
1669
+ *
1670
+ * Reverse function: {-}
1671
+ */
1672
+ static VALUE p1788_interval_add(VALUE self, VALUE y)
1673
+ {
1674
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
1675
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1676
+ VALUE r;
1677
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::add(inter, iother));
1678
+ return r;
1679
+ }
1680
+
1681
+
1682
+ /* Arithmetic subtraction
1683
+ *
1684
+ * [๐’”๐’†๐’๐’‡] - [๐’š]ย ย =ย ย hull{ ๐‘ฅ - ๐‘ฆ \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], ๐‘ฆ โˆˆ [๐’š] }ย ย โІย ย โ„
1685
+ *
1686
+ * Reverse function: {+}
1687
+ */
1688
+ static VALUE p1788_interval_sub(VALUE self, VALUE y)
1689
+ {
1690
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
1691
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1692
+ VALUE r;
1693
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::sub(inter, iother));
1694
+ return r;
1695
+ }
1696
+
1697
+
1698
+ /* Arithmetic multiplication
1699
+ *
1700
+ * [๐’”๐’†๐’๐’‡]*[๐’š]ย ย =ย ย hull{ ๐‘ฅโ‹…๐‘ฆ \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], ๐‘ฆ โˆˆ [๐’š] }ย ย โІย ย โ„
1701
+ *
1702
+ * Reverse function: {mul_rev}
1703
+ */
1704
+ static VALUE p1788_interval_mul(VALUE self, VALUE y)
1705
+ {
1706
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
1707
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1708
+ VALUE r;
1709
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::mul(inter, iother));
1710
+ return r;
1711
+ }
1712
+
1713
+
1714
+ /* Arithmetic division
1715
+ *
1716
+ * [๐’”๐’†๐’๐’‡] / [๐’š]ย ย =ย ย hull{ ๐‘ฅ/๐‘ฆ \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], ๐‘ฆ โˆˆ [๐’š] }ย ย โІย ย โ„
1717
+ *
1718
+ * Reverse function: {*}
1719
+ */
1720
+ static VALUE p1788_interval_div(VALUE self, VALUE y)
1721
+ {
1722
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
1723
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1724
+ VALUE r;
1725
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::div(inter, iother));
1726
+ return r;
1727
+ }
1728
+
1729
+
1730
+ /* Two-output division
1731
+ *
1732
+ * Returns a pair of intervals, ๐’”๐’†๐’๐’‡ / (๐’š โˆฉ โ„โ‚‹) and ๐’”๐’†๐’๐’‡ / (๐’š โˆฉ โ„โ‚Š)
1733
+ * @return [Array<Interval>] [โˆ…, โˆ…] if ๐’”๐’†๐’๐’‡/๐’š is empty, [[๐’”๐’†๐’๐’‡/๐’š], โˆ…] if ๐’”๐’†๐’๐’‡/๐’š has one component, [[๐’”๐’†๐’๐’‡/๐’š]โ‚, [๐’”๐’†๐’๐’‡/๐’š]โ‚‚] if ๐’”๐’†๐’๐’‡/๐’š has two components
1734
+ */
1735
+ static VALUE p1788_interval_div_to_pair(VALUE self, VALUE y)
1736
+ {
1737
+ VALUE r1, r2;
1738
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
1739
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1740
+ std::pair< InfSupDouble, InfSupDouble > p = InfSupDouble::mul_rev_to_pair(iother, inter);
1741
+ P1788_NEW_RB_INTERVAL(r1, p.first);
1742
+ P1788_NEW_RB_INTERVAL(r2, p.second);
1743
+ return rb_ary_new_from_args(2, r1, r2);
1744
+ }
1745
+
1746
+
1747
+ /* Power operator
1748
+ *
1749
+ * If _exponent_ is an integer, calls {pown}, else call {pow}.
1750
+ * @param exponent [Interval, Integer]
1751
+ */
1752
+ static VALUE p1788_interval_powop(VALUE self, VALUE exponent)
1753
+ {
1754
+ VALUE r;
1755
+ int p;
1756
+ double d;
1757
+ if (rb_obj_is_kind_of(exponent, rb_cInteger)) {
1758
+ p = NUM2INT(exponent);
1759
+ if (p == 2)
1760
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::sqr(p1788_interval_rb2ref(self)));
1761
+ else
1762
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::pown(p1788_interval_rb2ref(self), p));
1763
+ }
1764
+ else if (rb_obj_is_kind_of(exponent, rb_cNumeric)) {
1765
+ d = NUM2DBL(exponent);
1766
+ p = NUM2INT(exponent);
1767
+ if (d == (double)p) {
1768
+ if (p == 2)
1769
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::sqr(p1788_interval_rb2ref(self)));
1770
+ else
1771
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::pown(p1788_interval_rb2ref(self), p));
1772
+ }
1773
+ else
1774
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::pow(p1788_interval_rb2ref(self), InfSupDouble(d, d)));
1775
+ }
1776
+ else {
1777
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::pow(p1788_interval_rb2ref(self), p1788_rbobj2infsupdouble(exponent)));
1778
+ }
1779
+ return r;
1780
+ }
1781
+
1782
+
1783
+ /* Power function
1784
+ *
1785
+ * [๐’”๐’†๐’๐’‡].pow([๐’š])ย ย =ย ย hull{ ๐‘ฅ<sup>๐‘ฆ</sup> \| (๐‘ฅ, ๐‘ฆ) โˆˆ \\{๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡], ๐‘ฆ โˆˆ [๐’š] \| ๐‘ฅ>0\} โˆช \\{๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡]โˆฉ\{0\}, ๐‘ฆ โˆˆ [๐’š] \| ๐‘ฆ>0\} }ย ย โІย ย โ„โ‚Š
1786
+ *
1787
+ * Reverse functions: {pow_rev1} and {pow_rev2}
1788
+ */
1789
+ static VALUE p1788_interval_pow(VALUE self, VALUE y)
1790
+ {
1791
+ VALUE r;
1792
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::pow(p1788_interval_rb2ref(self), p1788_rbobj2infsupdouble(y)));
1793
+ return r;
1794
+ }
1795
+
1796
+
1797
+ /* Power with integer exponent
1798
+ *
1799
+ * [๐’”๐’†๐’๐’‡].pow(n)ย ย =ย ย hull{ ๐‘ฅโฟ \| ๐‘ฅ โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย โ„ if n odd, โ„โ‚Š if n even, \\{1\} if n = 0
1800
+ *
1801
+ * Reverse function {pown_rev}
1802
+ * @param n [Integer] integer exponent
1803
+ */
1804
+ static VALUE p1788_interval_pown(VALUE self, VALUE n)
1805
+ {
1806
+ VALUE r;
1807
+ int p;
1808
+ if (!RB_TYPE_P(n, T_FIXNUM))
1809
+ rb_raise(rb_eTypeError, "expecting an integer (Fixnum) as exponent, not a %" PRIsVALUE, rb_class_name(rb_class_of(n)));
1810
+ p = NUM2INT(n);
1811
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::pown(p1788_interval_rb2ref(self), p));
1812
+ return r;
1813
+ }
1814
+
1815
+
1816
+ /* Minimum of two intervals
1817
+ *
1818
+ * [๐’”๐’†๐’๐’‡].min([๐’ƒ])ย ย =ย ย [min(<span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span>, <span style="text-decoration:underline">๐’ƒ</span>), min(<span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span>, <span style="text-decoration:overline">๐’ƒ</span>)]
1819
+ */
1820
+ static VALUE p1788_interval_min(VALUE self, VALUE y)
1821
+ {
1822
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
1823
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1824
+ VALUE r;
1825
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::min(inter, iother));
1826
+ return r;
1827
+ }
1828
+
1829
+
1830
+ /* Maximum of two intervals
1831
+ *
1832
+ * [๐’”๐’†๐’๐’‡].max([๐’ƒ])ย ย =ย ย [max(<span style="text-decoration:underline">๐’”๐’†๐’๐’‡</span>, <span style="text-decoration:underline">๐’ƒ</span>), max(<span style="text-decoration:overline">๐’”๐’†๐’๐’‡</span>, <span style="text-decoration:overline">๐’ƒ</span>)]
1833
+ */
1834
+ static VALUE p1788_interval_max(VALUE self, VALUE b)
1835
+ {
1836
+ InfSupDouble iother = p1788_rbobj2infsupdouble(b);
1837
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1838
+ VALUE r;
1839
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::max(inter, iother));
1840
+ return r;
1841
+ }
1842
+
1843
+
1844
+ /* Cancellative subtraction
1845
+ *
1846
+ * Cancellative subtraction solves the following problem: Recover interval [๐’›] from intervals [๐’”๐’†๐’๐’‡] and [๐’š], given that [๐’”๐’†๐’๐’‡] = [๐’š] + [๐’›].
1847
+ *
1848
+ * For any two bounded intervals [๐’”๐’†๐’๐’‡] and [๐’š], [๐’”๐’†๐’๐’‡].cancel_minus([๐’š]) is the tightest interval [๐’›] such that [๐’š] + [๐’›] โЇ [๐’”๐’†๐’๐’‡].
1849
+ */
1850
+ static VALUE p1788_interval_cancel_minus(VALUE self, VALUE y)
1851
+ {
1852
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
1853
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1854
+ VALUE r;
1855
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::cancel_minus(inter, iother));
1856
+ return r;
1857
+ }
1858
+
1859
+
1860
+ /* Cancellative addition
1861
+ *
1862
+ * self.cancel_plux([๐’š]) = self.cancel_minus(-[๐’š])
1863
+ * @see cancel_minus
1864
+ */
1865
+ static VALUE p1788_interval_cancel_plus(VALUE self, VALUE y)
1866
+ {
1867
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
1868
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1869
+ VALUE r;
1870
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::cancel_plus(inter, iother));
1871
+ return r;
1872
+ }
1873
+
1874
+
1875
+ /* Fused multiply add
1876
+ *
1877
+ *fma([๐’™], [๐’š])ย ย =ย ย hull{ ๐‘ฅโ‹…๐‘ฆ + ๐‘ง \| ๐‘ฅ โˆˆ [๐’™], ๐‘ฆ โˆˆ [๐’š], ๐‘ง โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย โ„
1878
+ */
1879
+ static VALUE p1788_interval_fma(VALUE self, VALUE x, VALUE y)
1880
+ {
1881
+ InfSupDouble ix = p1788_rbobj2infsupdouble(x);
1882
+ InfSupDouble iy = p1788_rbobj2infsupdouble(y);
1883
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1884
+ VALUE r;
1885
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::fma(ix, iy, inter));
1886
+ return r;
1887
+ }
1888
+
1889
+
1890
+ /* Reverse elementary functions */
1891
+
1892
+
1893
+ /* The reverse interval extension ฯ†Rev
1894
+ * for a unary function ฯ† is an interval fulfill the following
1895
+ * requirement:
1896
+ * ฯ†Rev([c], [x]) โЇ {x โˆˆ [x] | ฯ†(x) is defined and in [c]}
1897
+ * For a binary function ฯ† there are naturally two reverse
1898
+ * interval extensions ฯ†Rev1 and ฯ†Rev2, for details, see
1899
+ * M. Nehmeier, โ€œMotion 11 - Basic Reverse Arithmetic Operations,โ€
1900
+ * IEEE Interval Standard Working Group - P1788, January 2010
1901
+ * ฯ†Rev1([b], [c], [x]) โЇ {x โˆˆ [x] | โˆƒ b โˆˆ [b], x ฯ† b is defined and in [c]}
1902
+ * ฯ†Rev2([a], [c], [x]) โЇ {x โˆˆ [x] | โˆƒ a โˆˆ [a], a ฯ† x is defined and in [c]}
1903
+ * if ฯ† is commutative, then ฯ†Rev1 and ฯ†Rev2 agree and may be implemented simply as ฯ†Rev
1904
+ */
1905
+
1906
+
1907
+ /* Two-output division
1908
+ *
1909
+ * [๐’”๐’†๐’๐’‡]/[๐’ƒ] = { ๐‘ฅ โˆˆ โ„ \| โˆƒ ๐‘ โˆˆ [๐’ƒ] : ๐‘ฅโ‹…๐‘ โˆˆ [๐’”๐’†๐’๐’‡] }
1910
+ * @return [Array<Interval>] a two elements array of intervals: [โˆ…, โˆ…] if ๐’”๐’†๐’๐’‡/๐’ƒ is empty, [[๐’”๐’†๐’๐’‡/๐’ƒ], โˆ…] if ๐’”๐’†๐’๐’‡/๐’ƒ has one component, [[๐’”๐’†๐’๐’‡/๐’ƒ]โ‚, [๐’”๐’†๐’๐’‡/๐’ƒ]โ‚‚] if ๐’”๐’†๐’๐’‡/๐’ƒ has two components
1911
+ */
1912
+ static VALUE p1788_interval_mul_rev_to_pair(VALUE self, VALUE y)
1913
+ {
1914
+ VALUE r1, r2;
1915
+ InfSupDouble iother = p1788_rbobj2infsupdouble(y);
1916
+ InfSupDouble &inter = p1788_interval_rb2ref(self);
1917
+ std::pair< InfSupDouble, InfSupDouble > p = InfSupDouble::mul_rev_to_pair(inter, iother);
1918
+ P1788_NEW_RB_INTERVAL(r1, p.first);
1919
+ P1788_NEW_RB_INTERVAL(r2, p.second);
1920
+ return rb_ary_new_from_args(2, r1, r2);
1921
+ }
1922
+
1923
+
1924
+ /* Reverse multiplication
1925
+ *
1926
+ * mul_rev([๐’ƒ], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| โˆƒ ๐‘ โˆˆ [๐’ƒ] : ๐‘ฅโ‹…๐‘ โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย โ„
1927
+ *
1928
+ * Reverse function {mul}
1929
+ * @overload mul_rev(b, x = ALL_REALS)
1930
+ */
1931
+ static VALUE p1788_interval_mul_rev(int argc, VALUE *argv, VALUE self)
1932
+ {
1933
+ VALUE b, x, r;
1934
+ rb_scan_args(argc, argv, "11", &b, &x);
1935
+ if (x == Qnil) {
1936
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::mul_rev(p1788_rbobj2infsupdouble(b), p1788_interval_rb2ref(self)));
1937
+ }
1938
+ else {
1939
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::mul_rev(p1788_rbobj2infsupdouble(b), p1788_interval_rb2ref(self), p1788_rbobj2infsupdouble(x)));
1940
+ }
1941
+ return r;
1942
+ }
1943
+
1944
+
1945
+ /* Reverse square
1946
+ *
1947
+ * sqr_rev([๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| ๐‘ฅยฒ โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย โ„
1948
+ *
1949
+ * Reverse function: {sqr}
1950
+ * @overload sqr_rev(x = ALL_REALS)
1951
+ */
1952
+ static VALUE p1788_interval_sqr_rev(int argc, VALUE *argv, VALUE self)
1953
+ {
1954
+ VALUE x, r;
1955
+ rb_scan_args(argc, argv, "01", &x);
1956
+ if (x == Qnil) {
1957
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::sqr_rev(p1788_interval_rb2ref(self)));
1958
+ }
1959
+ else {
1960
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::sqr_rev(p1788_interval_rb2ref(self), p1788_rbobj2infsupdouble(x)));
1961
+ }
1962
+ return r;
1963
+ }
1964
+
1965
+
1966
+ /* Reverse absolute value.
1967
+ *
1968
+ * abs_rev([๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] ๏ฟจ \|๐‘ฅ\| โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย โ„
1969
+ *
1970
+ * Reverse function: {abs}
1971
+ * @overload abs_rev(x = ALL_REALS)
1972
+ */
1973
+ static VALUE p1788_interval_abs_rev(int argc, VALUE *argv, VALUE self)
1974
+ {
1975
+ VALUE x, r;
1976
+ rb_scan_args(argc, argv, "01", &x);
1977
+ if (x == Qnil) {
1978
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::abs_rev(p1788_interval_rb2ref(self)));
1979
+ }
1980
+ else {
1981
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::abs_rev(p1788_interval_rb2ref(self), p1788_rbobj2infsupdouble(x)));
1982
+ }
1983
+ return r;
1984
+ }
1985
+
1986
+
1987
+ /* Reverse power with integer exponent
1988
+ *
1989
+ * pown_rev(๐‘›, [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| ๐‘ฅโฟ โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย โ„
1990
+ *
1991
+ * Reverse function: {pown}
1992
+ * @overload pown_rev(n, x = ALL_REALS)
1993
+ * @param n [Integer] integer exponent
1994
+ * @param x [Interval]
1995
+ */
1996
+ static VALUE p1788_interval_pown_rev(int argc, VALUE *argv, VALUE self)
1997
+ {
1998
+ VALUE x, r, n;
1999
+ int p;
2000
+ rb_scan_args(argc, argv, "11", &n, &x);
2001
+ p = NUM2INT(n);
2002
+ if (x == Qnil) {
2003
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::pown_rev(p1788_interval_rb2ref(self), p));
2004
+ }
2005
+ else {
2006
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::pown_rev(p1788_interval_rb2ref(self), p1788_rbobj2infsupdouble(x), p));
2007
+ }
2008
+ return r;
2009
+ }
2010
+
2011
+
2012
+ /* Reverse power function (base)
2013
+ *
2014
+ * pow_rev1([๐’ƒ], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| โˆƒ ๐‘ โˆˆ [๐’ƒ] : ๐‘ฅ<sup>๐‘</sup> โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย โ„โ‚Š
2015
+ *
2016
+ * Reverse function: {pow}
2017
+ * @overload pow_rev1(b, x = ALL_REALS)
2018
+ */
2019
+ static VALUE p1788_interval_pow_rev1(int argc, VALUE *argv, VALUE self)
2020
+ {
2021
+ VALUE rbb, rbx, rbr;
2022
+ rb_scan_args(argc, argv, "11", &rbb, &rbx);
2023
+ InfSupDouble b = p1788_rbobj2infsupdouble(rbb);
2024
+ InfSupDouble x = (rbx == Qnil) ? InfSupDouble(-INF, INF) : p1788_rbobj2infsupdouble(rbx);
2025
+ InfSupDouble &c = p1788_interval_rb2ref(self);
2026
+
2027
+ InfSupDouble lnx = InfSupDouble::log(x);
2028
+ InfSupDouble m = InfSupDouble::intersection(InfSupDouble::log(c), InfSupDouble::mul(b, lnx));
2029
+ InfSupDouble l = InfSupDouble::mul_rev(b, m, lnx);
2030
+ InfSupDouble r = InfSupDouble::intersection(InfSupDouble::exp(l), x);
2031
+
2032
+ P1788_NEW_RB_INTERVAL(rbr, r);
2033
+ return rbr;
2034
+ }
2035
+
2036
+
2037
+ /* Reverse power function (exponent)
2038
+ *
2039
+ * pow_rev2([๐’‚], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| โˆƒ ๐‘Ž โˆˆ [๐’‚] : ๐‘Ž<sup>๐‘ฅ</sup> โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย โ„
2040
+ *
2041
+ * Reverse function: {pow}
2042
+ * @overload pow_rev2(a, x = ALL_REALS)
2043
+ */
2044
+ static VALUE p1788_interval_pow_rev2(int argc, VALUE *argv, VALUE self)
2045
+ {
2046
+ VALUE rba, rbx, rbr;
2047
+ rb_scan_args(argc, argv, "11", &rba, &rbx);
2048
+ InfSupDouble a = p1788_rbobj2infsupdouble(rba);
2049
+ InfSupDouble x = (rbx == Qnil) ? InfSupDouble(-INF, INF) : p1788_rbobj2infsupdouble(rbx);
2050
+ InfSupDouble &c = p1788_interval_rb2ref(self);
2051
+
2052
+ InfSupDouble lna = InfSupDouble::log(a);
2053
+ InfSupDouble m = InfSupDouble::intersection(InfSupDouble::log(c), InfSupDouble::mul(x, lna));
2054
+ InfSupDouble r = InfSupDouble::mul_rev(lna, m, x);
2055
+
2056
+ P1788_NEW_RB_INTERVAL(rbr, r);
2057
+ return rbr;
2058
+ }
2059
+
2060
+
2061
+ /* Reverse sine
2062
+ *
2063
+ * sin_rev([๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| sin(๐‘ฅ) โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย โ„
2064
+ *
2065
+ * Reverse function: {sin}
2066
+ * @overload sin_rev(x = ALL_REALS)
2067
+ */
2068
+ static VALUE p1788_interval_sin_rev(int argc, VALUE *argv, VALUE self)
2069
+ {
2070
+ VALUE x, r;
2071
+ rb_scan_args(argc, argv, "01", &x);
2072
+ if (x == Qnil) {
2073
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::sin_rev(p1788_interval_rb2ref(self)));
2074
+ }
2075
+ else {
2076
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::sin_rev(p1788_interval_rb2ref(self), p1788_rbobj2infsupdouble(x)));
2077
+ }
2078
+ return r;
2079
+ }
2080
+
2081
+
2082
+ /* Reverse cosine
2083
+ *
2084
+ * cos_rev([๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| cos(๐‘ฅ) โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย โ„
2085
+ *
2086
+ * Reverse function: {cos}
2087
+ * @overload cos_rev(x = ALL_REALS)
2088
+ */
2089
+ static VALUE p1788_interval_cos_rev(int argc, VALUE *argv, VALUE self)
2090
+ {
2091
+ VALUE x, r;
2092
+ rb_scan_args(argc, argv, "01", &x);
2093
+ if (x == Qnil) {
2094
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::cos_rev(p1788_interval_rb2ref(self)));
2095
+ }
2096
+ else {
2097
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::cos_rev(p1788_interval_rb2ref(self), p1788_rbobj2infsupdouble(x)));
2098
+ }
2099
+ return r;
2100
+ }
2101
+
2102
+
2103
+ /* Reverse tangent
2104
+ *
2105
+ * tan_rev([๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| tan(๐‘ฅ) โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย โ„
2106
+ *
2107
+ * Reverse function: {tan}
2108
+ * @overload tan_rev(x = ALL_REALS)
2109
+ */
2110
+ static VALUE p1788_interval_tan_rev(int argc, VALUE *argv, VALUE self)
2111
+ {
2112
+ VALUE x, r;
2113
+ rb_scan_args(argc, argv, "01", &x);
2114
+ if (x == Qnil) {
2115
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::tan_rev(p1788_interval_rb2ref(self)));
2116
+ }
2117
+ else {
2118
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::tan_rev(p1788_interval_rb2ref(self), p1788_rbobj2infsupdouble(x)));
2119
+ }
2120
+ return r;
2121
+ }
2122
+
2123
+
2124
+ /* Reverse hyperbolic cosine
2125
+ *
2126
+ * cosh_rev([๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| cosh(๐‘ฅ) โˆˆ [๐’”๐’†๐’๐’‡] }ย ย โІย ย โ„
2127
+ *
2128
+ * Reverse function: {cosh}
2129
+ * @overload cosh_rev(x = ALL_REALS)
2130
+ */
2131
+ static VALUE p1788_interval_cosh_rev(int argc, VALUE *argv, VALUE self)
2132
+ {
2133
+ VALUE x, r;
2134
+ rb_scan_args(argc, argv, "01", &x);
2135
+ if (x == Qnil) {
2136
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::cosh_rev(p1788_interval_rb2ref(self)));
2137
+ }
2138
+ else {
2139
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::cosh_rev(p1788_interval_rb2ref(self), p1788_rbobj2infsupdouble(x)));
2140
+ }
2141
+ return r;
2142
+ }
2143
+
2144
+
2145
+ /* Math module functions */
2146
+
2147
+
2148
+ /* Reciprocal of _x_
2149
+ *
2150
+ * recip([๐’™])ย ย =ย ย hull{ 1/๐‘ฅ \| ๐‘ฅ โˆˆ [๐’™] }ย ย โІย ย โ„
2151
+ *
2152
+ * Reverse function: {recip_rev}
2153
+ */
2154
+ static VALUE p1788_recip(VALUE self, VALUE x)
2155
+ {
2156
+ VALUE r;
2157
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::recip(p1788_rbobj2infsupdouble(x)));
2158
+ return r;
2159
+ }
2160
+
2161
+
2162
+ /* Reverse reciprocal
2163
+ *
2164
+ * recip_rev([๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| 1/๐‘ฅ โˆˆ [๐’„] }ย ย โІย ย โ„
2165
+ *
2166
+ * Reverse function: {recip}
2167
+ * @overload recip_rev(c, x = ALL_REALS)
2168
+ */
2169
+ static VALUE p1788_recip_rev(int argc, VALUE *argv, VALUE self)
2170
+ {
2171
+ VALUE x, c, r;
2172
+ rb_scan_args(argc, argv, "11", &c, &x);
2173
+ if (x == Qnil) {
2174
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::mul_rev(p1788_rbobj2infsupdouble(c), InfSupDouble(1.0, 1.0)));
2175
+ }
2176
+ else {
2177
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::mul_rev(p1788_rbobj2infsupdouble(c), InfSupDouble(1.0, 1.0), p1788_rbobj2infsupdouble(x)));
2178
+ }
2179
+ return r;
2180
+ }
2181
+
2182
+
2183
+ /* Square of _x_
2184
+ *
2185
+ * sqr([๐’™])ย ย =ย ย hull{ ๐‘ฅยฒ \| ๐‘ฅ โˆˆ [๐’™] }ย ย โІย ย โ„โ‚Š
2186
+ *
2187
+ * Reverse function: {sqr_rev}
2188
+ */
2189
+ static VALUE p1788_sqr(VALUE self, VALUE x)
2190
+ {
2191
+ VALUE r;
2192
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::sqr(p1788_rbobj2infsupdouble(x)));
2193
+ return r;
2194
+ }
2195
+
2196
+
2197
+ /* Square root of _x_
2198
+ *
2199
+ * sqrt([๐’™])ย ย =ย ย hull{ ๐‘ฅ<sup>ยฝ</sup> \| ๐‘ฅ โˆˆ [๐’™]โˆฉโ„โ‚Š }ย ย โІย ย โ„โ‚Š
2200
+ *
2201
+ * Reverse function: {sqrt_rev}
2202
+ */
2203
+ static VALUE p1788_sqrt(VALUE self, VALUE x)
2204
+ {
2205
+ VALUE r;
2206
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::sqrt(p1788_rbobj2infsupdouble(x)));
2207
+ return r;
2208
+ }
2209
+
2210
+
2211
+ /* Reverse square root
2212
+ *
2213
+ * sqrt_rev([๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| ๐‘ฅ<sup>ยฝ</sup> โˆˆ [๐’„] }ย ย =ย ย { ๐‘ยฒ \|ย ๐‘ โˆˆ [๐’„]โˆฉโ„โ‚Š } โˆฉ [๐’™]ย ย โІย ย โ„โ‚Š
2214
+ *
2215
+ * Reverse function: {sqrt}
2216
+ * @overload sqrt_rev(c, x = ALL_REALS)
2217
+ */
2218
+ static VALUE p1788_sqrt_rev(int argc, VALUE *argv, VALUE self)
2219
+ {
2220
+ VALUE rbc, rbx, rbr;
2221
+ rb_scan_args(argc, argv, "11", &rbc, &rbx);
2222
+ InfSupDouble c = p1788_rbobj2infsupdouble(rbc);
2223
+ InfSupDouble r = InfSupDouble::sqr(InfSupDouble::intersection(c, pos_reals_set));
2224
+ if (rbx != Qnil)
2225
+ r = InfSupDouble::intersection(r, p1788_rbobj2infsupdouble(rbx));
2226
+ P1788_NEW_RB_INTERVAL(rbr, r);
2227
+ return rbr;
2228
+ }
2229
+
2230
+
2231
+ /* _e_ raised to the power of _x_
2232
+ *
2233
+ * exp([๐’™])ย ย =ย ย hull{ ๐‘’<sup>๐‘ฅ</sup> \| ๐‘ฅ โˆˆ [๐’™] }ย ย โІย ย โ„โ‚Š
2234
+ *
2235
+ * Reverse function: {exp_rev}
2236
+ */
2237
+ static VALUE p1788_exp(VALUE self, VALUE x)
2238
+ {
2239
+ VALUE r;
2240
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::exp(p1788_rbobj2infsupdouble(x)));
2241
+ return r;
2242
+ }
2243
+
2244
+
2245
+ /* Reverse exponential
2246
+ *
2247
+ * exp_rev([๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| ๐‘’<sup>๐‘ฅ</sup> โˆˆ [๐’„] }ย ย =ย ย { log(๐‘) \|ย ๐‘ โˆˆ [๐’„]โˆฉโ„โ‚Š } โˆฉ [๐’™]ย ย โІย ย โ„
2248
+ *
2249
+ * Reverse function: {exp}
2250
+ * @overload exp_rev(c, x = ALL_REALS)
2251
+ */
2252
+ static VALUE p1788_exp_rev(int argc, VALUE *argv, VALUE self)
2253
+ {
2254
+ VALUE rbc, rbx, rbr;
2255
+ rb_scan_args(argc, argv, "11", &rbc, &rbx);
2256
+ InfSupDouble r = InfSupDouble::log(p1788_rbobj2infsupdouble(rbc));
2257
+ if (rbx != Qnil)
2258
+ r = InfSupDouble::intersection(r, p1788_rbobj2infsupdouble(rbx));
2259
+ P1788_NEW_RB_INTERVAL(rbr, r);
2260
+ return rbr;
2261
+ }
2262
+
2263
+
2264
+ /* 2 raised to the power of _x_
2265
+ *
2266
+ * exp2([๐’™])ย ย =ย ย hull{ 2<sup>๐‘ฅ</sup> \| ๐‘ฅ โˆˆ [๐’™] }ย ย โІย ย โ„โ‚Š
2267
+ *
2268
+ * Reverse function: {exp2_rev}
2269
+ */
2270
+ static VALUE p1788_exp2(VALUE self, VALUE x)
2271
+ {
2272
+ VALUE r;
2273
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::exp2(p1788_rbobj2infsupdouble(x)));
2274
+ return r;
2275
+ }
2276
+
2277
+
2278
+ /* Reverse base 2 exponential
2279
+ *
2280
+ * exp2_rev([๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| 2<sup>๐‘ฅ</sup> โˆˆ [๐’„] }ย ย =ย ย { log2(๐‘) \|ย ๐‘ โˆˆ [๐’„]โˆฉโ„โ‚Š } โˆฉ [๐’™]ย ย โІย ย โ„
2281
+ *
2282
+ * Reverse function: {exp2}
2283
+ * @overload exp2_rev(c, x = ALL_REALS)
2284
+ */
2285
+ static VALUE p1788_exp2_rev(int argc, VALUE *argv, VALUE self)
2286
+ {
2287
+ VALUE rbc, rbx, rbr;
2288
+ rb_scan_args(argc, argv, "11", &rbc, &rbx);
2289
+ InfSupDouble r = InfSupDouble::log2(p1788_rbobj2infsupdouble(rbc));
2290
+ if (rbx != Qnil)
2291
+ r = InfSupDouble::intersection(r, p1788_rbobj2infsupdouble(rbx));
2292
+ P1788_NEW_RB_INTERVAL(rbr, r);
2293
+ return rbr;
2294
+ }
2295
+
2296
+
2297
+ /* 10 raised to the power of _x_
2298
+ *
2299
+ * exp10([๐’™])ย ย =ย ย hull{ 10<sup>๐‘ฅ</sup> \| ๐‘ฅ โˆˆ [๐’™] }ย ย โІย ย โ„โ‚Š
2300
+ *
2301
+ * Reverse function: {exp10_rev}
2302
+ */
2303
+ static VALUE p1788_exp10(VALUE self, VALUE x)
2304
+ {
2305
+ VALUE r;
2306
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::exp10(p1788_rbobj2infsupdouble(x)));
2307
+ return r;
2308
+ }
2309
+
2310
+
2311
+ /* Reverse base 10 exponential
2312
+ *
2313
+ * exp10_rev([๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| 10<sup>๐‘ฅ</sup> โˆˆ [๐’„] }ย ย =ย ย { log10(๐‘) \|ย ๐‘ โˆˆ [๐’„]โˆฉโ„โ‚Š } โˆฉ [๐’™]ย ย โІย ย โ„
2314
+ *
2315
+ * Reverse function: {exp10}
2316
+ * @overload exp2_rev(c, x = ALL_REALS)
2317
+ */
2318
+ static VALUE p1788_exp10_rev(int argc, VALUE *argv, VALUE self)
2319
+ {
2320
+ VALUE rbc, rbx, rbr;
2321
+ rb_scan_args(argc, argv, "11", &rbc, &rbx);
2322
+ InfSupDouble r = InfSupDouble::log10(p1788_rbobj2infsupdouble(rbc));
2323
+ if (rbx != Qnil)
2324
+ r = InfSupDouble::intersection(r, p1788_rbobj2infsupdouble(rbx));
2325
+ P1788_NEW_RB_INTERVAL(rbr, r);
2326
+ return rbr;
2327
+ }
2328
+
2329
+
2330
+ /* Natural logarithm of _x_.
2331
+ *
2332
+ * log([๐’™])ย ย =ย ย hull{ ln(๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’™]โˆฉโ„โ‚Š }ย ย โІย ย โ„
2333
+ *
2334
+ * Reverse function: {log_rev}
2335
+ */
2336
+ static VALUE p1788_log(VALUE self, VALUE x)
2337
+ {
2338
+ VALUE r;
2339
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::log(p1788_rbobj2infsupdouble(x)));
2340
+ return r;
2341
+ }
2342
+
2343
+
2344
+ /* Reverse natural logarithm
2345
+ *
2346
+ * log_rev([๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| log(๐‘ฅ) โˆˆ [๐’„] }ย ย =ย ย { ๐‘’<sup>๐‘</sup> \|ย ๐‘ โˆˆ [๐’„] } โˆฉ [๐’™]ย ย โІย ย โ„โ‚Š
2347
+ *
2348
+ * Reverse function: {log}
2349
+ * @overload log_rev(c, x = ALL_REALS)
2350
+ */
2351
+ static VALUE p1788_log_rev(int argc, VALUE *argv, VALUE self)
2352
+ {
2353
+ VALUE rbc, rbx, rbr;
2354
+ rb_scan_args(argc, argv, "11", &rbc, &rbx);
2355
+ InfSupDouble r = InfSupDouble::exp(p1788_rbobj2infsupdouble(rbc));
2356
+ if (rbx != Qnil)
2357
+ r = InfSupDouble::intersection(r, p1788_rbobj2infsupdouble(rbx));
2358
+ P1788_NEW_RB_INTERVAL(rbr, r);
2359
+ return rbr;
2360
+ }
2361
+
2362
+
2363
+ /* Base 2 logarithm of _x_
2364
+ *
2365
+ * log2([๐’™])ย ย =ย ย hull{ ln(๐‘ฅ)/ln(2) \| ๐‘ฅ โˆˆ [๐’™]โˆฉโ„โ‚Š }ย ย โІย ย โ„
2366
+ *
2367
+ * Reverse function: {log2_rev}
2368
+ */
2369
+ static VALUE p1788_log2(VALUE self, VALUE x)
2370
+ {
2371
+ VALUE r;
2372
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::log2(p1788_rbobj2infsupdouble(x)));
2373
+ return r;
2374
+ }
2375
+
2376
+
2377
+ /* Reverse base 2 logarithm
2378
+ *
2379
+ * log2_rev([๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| log2(๐‘ฅ) โˆˆ [๐’„] }ย ย =ย ย { 2<sup>๐‘</sup> \|ย ๐‘ โˆˆ [๐’„] } โˆฉ [๐’™]ย ย โІย ย โ„โ‚Š
2380
+ *
2381
+ * Reverse function: {log2}
2382
+ * @overload log2_rev(c, x = ALL_REALS)
2383
+ */
2384
+ static VALUE p1788_log2_rev(int argc, VALUE *argv, VALUE self)
2385
+ {
2386
+ VALUE rbc, rbx, rbr;
2387
+ rb_scan_args(argc, argv, "11", &rbc, &rbx);
2388
+ InfSupDouble r = InfSupDouble::exp2(p1788_rbobj2infsupdouble(rbc));
2389
+ if (rbx != Qnil)
2390
+ r = InfSupDouble::intersection(r, p1788_rbobj2infsupdouble(rbx));
2391
+ P1788_NEW_RB_INTERVAL(rbr, r);
2392
+ return rbr;
2393
+ }
2394
+
2395
+
2396
+ /* Base 10 logarithm of _x_
2397
+ *
2398
+ * log10([๐’™])ย ย =ย ย hull{ ln(๐‘ฅ)/ln(10) \| ๐‘ฅ โˆˆ [๐’™]โˆฉโ„โ‚Š }ย ย โІย ย โ„
2399
+ *
2400
+ * Reverse function: {log10_rev}
2401
+ */
2402
+ static VALUE p1788_log10(VALUE self, VALUE x)
2403
+ {
2404
+ VALUE r;
2405
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::log10(p1788_rbobj2infsupdouble(x)));
2406
+ return r;
2407
+ }
2408
+
2409
+
2410
+ /* Reverse base 10 logarithm
2411
+ *
2412
+ * log10_rev([๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| log10(๐‘ฅ) โˆˆ [๐’„] }ย ย =ย ย { 10<sup>๐‘</sup> \|ย ๐‘ โˆˆ [๐’„] } โˆฉ [๐’™]ย ย โІย ย โ„โ‚Š
2413
+ *
2414
+ * Reverse function: {log10}
2415
+ * @overload log10_rev(c, x = ALL_REALS)
2416
+ */
2417
+ static VALUE p1788_log10_rev(int argc, VALUE *argv, VALUE self)
2418
+ {
2419
+ VALUE rbc, rbx, rbr;
2420
+ rb_scan_args(argc, argv, "11", &rbc, &rbx);
2421
+ InfSupDouble r = InfSupDouble::exp10(p1788_rbobj2infsupdouble(rbc));
2422
+ if (rbx != Qnil)
2423
+ r = InfSupDouble::intersection(r, p1788_rbobj2infsupdouble(rbx));
2424
+ P1788_NEW_RB_INTERVAL(rbr, r);
2425
+ return rbr;
2426
+ }
2427
+
2428
+
2429
+ /* Sine of _x_ in radians.
2430
+ *
2431
+ * sin([๐’™])ย ย =ย ย hull{ sin(๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’™] }ย ย โІย ย [-1, 1]
2432
+ *
2433
+ * Reverse function: {sin_rev}
2434
+ */
2435
+ static VALUE p1788_sin(VALUE self, VALUE x)
2436
+ {
2437
+ VALUE r;
2438
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::sin(p1788_rbobj2infsupdouble(x)));
2439
+ return r;
2440
+ }
2441
+
2442
+
2443
+ /* Cosine of _x_ in radians.
2444
+ *
2445
+ * cos([๐’™])ย ย =ย ย hull{ cos(๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’™] }ย ย โІย ย [-1, 1]
2446
+ *
2447
+ * Reverse function: {cos_rev}
2448
+ */
2449
+ static VALUE p1788_cos(VALUE self, VALUE x)
2450
+ {
2451
+ VALUE r;
2452
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::cos(p1788_rbobj2infsupdouble(x)));
2453
+ return r;
2454
+ }
2455
+
2456
+
2457
+ /* Tangent of _x_ in radians.
2458
+ *
2459
+ * tan([๐’™])ย ย =ย ย hull{ tan(๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’™] }ย ย โІย ย โ„
2460
+ *
2461
+ * Reverse function: {tan_rev}
2462
+ */
2463
+ static VALUE p1788_tan(VALUE self, VALUE x)
2464
+ {
2465
+ VALUE r;
2466
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::tan(p1788_rbobj2infsupdouble(x)));
2467
+ return r;
2468
+ }
2469
+
2470
+
2471
+ /* Arc sine of _x_, in radians.
2472
+ *
2473
+ * asin([๐’™])ย ย =ย ย hull{ asin(๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’™]โˆฉ[-1, 1] }ย ย โІย ย [-๐›‘/2, ๐›‘/2]
2474
+ *
2475
+ * Reverse function: {asin_rev}
2476
+ */
2477
+ static VALUE p1788_asin(VALUE self, VALUE x)
2478
+ {
2479
+ VALUE r;
2480
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::asin(p1788_rbobj2infsupdouble(x)));
2481
+ return r;
2482
+ }
2483
+
2484
+
2485
+ /* Reverse arc sine
2486
+ *
2487
+ * asin_rev([๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| asin(๐‘ฅ) โˆˆ [๐’„] }ย ย =ย ย { sin(๐‘) \|ย ๐‘ โˆˆ [๐’„]โˆฉ[-๐›‘/2, ๐›‘/2] } โˆฉ [๐’™]ย ย โІย ย [-1, 1]
2488
+ *
2489
+ * Reverse function: {asin}
2490
+ * @overload asin_rev(c, x = ALL_REALS)
2491
+ */
2492
+ static VALUE p1788_asin_rev(int argc, VALUE *argv, VALUE self)
2493
+ {
2494
+ VALUE rbc, rbx, rbr;
2495
+ rb_scan_args(argc, argv, "11", &rbc, &rbx);
2496
+ InfSupDouble r = InfSupDouble::sin(InfSupDouble::intersection(p1788_rbobj2infsupdouble(rbc), minus_hpi_hpi_set));
2497
+ if (rbx != Qnil)
2498
+ r = InfSupDouble::intersection(r, p1788_rbobj2infsupdouble(rbx));
2499
+ P1788_NEW_RB_INTERVAL(rbr, r);
2500
+ return rbr;
2501
+ }
2502
+
2503
+
2504
+ /* Arc cosine of _x_, in radians.
2505
+ *
2506
+ * acos([๐’™])ย ย =ย ย hull{ acos(๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’™]โˆฉ[-1, 1] }ย ย โІย ย [0, ๐›‘]
2507
+ *
2508
+ * Reverse function: {acos_rev}
2509
+ */
2510
+ static VALUE p1788_acos(VALUE self, VALUE x)
2511
+ {
2512
+ VALUE r;
2513
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::acos(p1788_rbobj2infsupdouble(x)));
2514
+ return r;
2515
+ }
2516
+
2517
+
2518
+ /* Reverse arc cosine
2519
+ *
2520
+ * acos_rev([๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| acos(๐‘ฅ) โˆˆ [๐’„] }ย ย =ย ย { cos(๐‘) \|ย ๐‘ โˆˆ [๐’„]โˆฉ[0, ๐›‘] } โˆฉ [๐’™]ย ย โІย ย [-1, 1]
2521
+ *
2522
+ * Reverse function: {cos}
2523
+ * @overload acos_rev(c, x = ALL_REALS)
2524
+ */
2525
+ static VALUE p1788_acos_rev(int argc, VALUE *argv, VALUE self)
2526
+ {
2527
+ VALUE rbc, rbx, rbr;
2528
+ rb_scan_args(argc, argv, "11", &rbc, &rbx);
2529
+ InfSupDouble r = InfSupDouble::cos(InfSupDouble::intersection(p1788_rbobj2infsupdouble(rbc), zero_pi_set));
2530
+ if (rbx != Qnil)
2531
+ r = InfSupDouble::intersection(r, p1788_rbobj2infsupdouble(rbx));
2532
+ P1788_NEW_RB_INTERVAL(rbr, r);
2533
+ return rbr;
2534
+ }
2535
+
2536
+
2537
+ /* Arc tangent of _x_.
2538
+ *
2539
+ * atan([๐’™])ย ย =ย ย hull{ atan(๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’™] }ย ย โІย ย [-๐›‘/2, ๐›‘/2]ย 
2540
+ *
2541
+ * Reverse function: {atan_rev}
2542
+ */
2543
+ static VALUE p1788_atan(VALUE self, VALUE x)
2544
+ {
2545
+ VALUE r;
2546
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::atan(p1788_rbobj2infsupdouble(x)));
2547
+ return r;
2548
+ }
2549
+
2550
+
2551
+ /* Reverse arc tangent
2552
+ *
2553
+ * atan_rev([๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| atan(๐‘ฅ) โˆˆ [๐’„] }ย ย =ย ย { tan(๐‘) \|ย ๐‘ โˆˆ [๐’„]โˆฉ[-๐›‘/2, ๐›‘/2] } โˆฉ [๐’™]ย ย โІย ย โ„
2554
+ *
2555
+ * Reverse function: {tan}
2556
+ * @overload atan_rev(c, x = ALL_REALS)
2557
+ */
2558
+ static VALUE p1788_atan_rev(int argc, VALUE *argv, VALUE self)
2559
+ {
2560
+ VALUE rbc, rbx, rbr;
2561
+ rb_scan_args(argc, argv, "11", &rbc, &rbx);
2562
+ InfSupDouble r = InfSupDouble::tan(InfSupDouble::intersection(p1788_rbobj2infsupdouble(rbc), minus_hpi_hpi_set));
2563
+ if (rbx != Qnil)
2564
+ r = InfSupDouble::intersection(r, p1788_rbobj2infsupdouble(rbx));
2565
+ P1788_NEW_RB_INTERVAL(rbr, r);
2566
+ return rbr;
2567
+ }
2568
+
2569
+
2570
+ /* Principal value of the arc tangent of _y_/_x_
2571
+ *
2572
+ * atan2([๐’š], [๐’™])ย ย =ย ย hull{ atan2(๐‘ฆ, ๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’™], ๐‘ฆ โˆˆ [๐’š] }ย ย โІย ย [-๐›‘, ๐›‘]ย 
2573
+ *
2574
+ * Reverse function: atan2_rev (not implemented yet)
2575
+ */
2576
+ static VALUE p1788_atan2(VALUE self, VALUE y, VALUE x)
2577
+ {
2578
+ VALUE r;
2579
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::atan2(p1788_interval_rb2ref(y), p1788_interval_rb2ref(x)));
2580
+ return r;
2581
+ }
2582
+
2583
+
2584
+ /* Hyperbolic sine of _x_.
2585
+ *
2586
+ * sinh([๐’™])ย ย =ย ย hull{ (๐‘’<sup>๐‘ฅ</sup> - ๐‘’<sup>-๐‘ฅ</sup>) / 2 \| ๐‘ฅ โˆˆ [๐’™] }ย ย โІย ย โ„
2587
+ *
2588
+ * Reverse function: {sinh_rev}
2589
+ */
2590
+ static VALUE p1788_sinh(VALUE self, VALUE x)
2591
+ {
2592
+ VALUE r;
2593
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::sinh(p1788_rbobj2infsupdouble(x)));
2594
+ return r;
2595
+ }
2596
+
2597
+
2598
+ /* Reverse hyperbolic sine
2599
+ *
2600
+ * sinh_rev([๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| sinh(๐‘ฅ) โˆˆ [๐’„] }ย ย =ย ย { asinh(๐‘) \|ย ๐‘ โˆˆ [๐’„] } โˆฉ [๐’™]ย ย โІย ย โ„
2601
+ *
2602
+ * Reverse function: {sinh}
2603
+ * @overload sinh_rev(c, x = ALL_REALS)
2604
+ */
2605
+ static VALUE p1788_sinh_rev(int argc, VALUE *argv, VALUE self)
2606
+ {
2607
+ VALUE rbc, rbx, rbr;
2608
+ rb_scan_args(argc, argv, "11", &rbc, &rbx);
2609
+ InfSupDouble r = InfSupDouble::asinh(p1788_rbobj2infsupdouble(rbc));
2610
+ if (rbx != Qnil)
2611
+ r = InfSupDouble::intersection(r, p1788_rbobj2infsupdouble(rbx));
2612
+ P1788_NEW_RB_INTERVAL(rbr, r);
2613
+ return rbr;
2614
+ }
2615
+
2616
+
2617
+ /* Hyperbolic cosine of _x_.
2618
+ *
2619
+ * cosh([๐’™])ย ย =ย ย hull{ (๐‘’<sup>๐‘ฅ</sup> + ๐‘’<sup>-๐‘ฅ</sup>) / 2 \| ๐‘ฅ โˆˆ [๐’™] }ย ย โІย ย [1, +โˆž]
2620
+ *
2621
+ * Reverse function: {cosh_rev}
2622
+ */
2623
+ static VALUE p1788_cosh(VALUE self, VALUE x)
2624
+ {
2625
+ VALUE r;
2626
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::cosh(p1788_rbobj2infsupdouble(x)));
2627
+ return r;
2628
+ }
2629
+
2630
+
2631
+ /* Hyperbolic tangent of _x_.
2632
+ *
2633
+ * tanh([๐’™])ย ย =ย ย hull{ sinh(๐‘ฅ) / cosh(๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’™] }ย ย โІย ย [-1, 1]
2634
+ *
2635
+ * Reverse function: {tanh_rev}
2636
+ */
2637
+ static VALUE p1788_tanh(VALUE self, VALUE x)
2638
+ {
2639
+ VALUE r;
2640
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::tanh(p1788_rbobj2infsupdouble(x)));
2641
+ return r;
2642
+ }
2643
+
2644
+
2645
+ /* Reverse hyperbolic tangent
2646
+ *
2647
+ * tanh_rev([๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| tanh(๐‘ฅ) โˆˆ [๐’„] }ย ย =ย ย { atanh(๐‘) \|ย ๐‘ โˆˆ [๐’„]โˆฉ[-1, 1] } โˆฉ [๐’™]ย ย โІย ย โ„
2648
+ *
2649
+ * Reverse function: {tanh}
2650
+ * @overload tanh_rev(c, x = ALL_REALS)
2651
+ */
2652
+ static VALUE p1788_tanh_rev(int argc, VALUE *argv, VALUE self)
2653
+ {
2654
+ VALUE rbc, rbx, rbr;
2655
+ rb_scan_args(argc, argv, "11", &rbc, &rbx);
2656
+ InfSupDouble r = InfSupDouble::atanh(p1788_rbobj2infsupdouble(rbc));
2657
+ if (rbx != Qnil)
2658
+ r = InfSupDouble::intersection(r, p1788_rbobj2infsupdouble(rbx));
2659
+ P1788_NEW_RB_INTERVAL(rbr, r);
2660
+ return rbr;
2661
+ }
2662
+
2663
+
2664
+ /* Inverse hyperbolic sine of _x_.
2665
+ *
2666
+ * asinh([๐’™])ย ย =ย ย hull{ asinh(๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’™] }ย ย โІย ย โ„
2667
+ *
2668
+ * Reverse function: {asinh_rev}
2669
+ */
2670
+ static VALUE p1788_asinh(VALUE self, VALUE x)
2671
+ {
2672
+ VALUE r;
2673
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::asinh(p1788_rbobj2infsupdouble(x)));
2674
+ return r;
2675
+ }
2676
+
2677
+
2678
+ /* Reverse inverse hyperbolic sine
2679
+ *
2680
+ * asinh_rev([๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| asinh(๐‘ฅ) โˆˆ [๐’„] }ย ย =ย ย { sinh(๐‘) \|ย ๐‘ โˆˆ [๐’„] } โˆฉ [๐’™]ย ย โІย ย โ„
2681
+ *
2682
+ * Reverse function: {asinh}
2683
+ * @overload tanh_rev(c, x = ALL_REALS)
2684
+ */
2685
+ static VALUE p1788_asinh_rev(int argc, VALUE *argv, VALUE self)
2686
+ {
2687
+ VALUE rbc, rbx, rbr;
2688
+ rb_scan_args(argc, argv, "11", &rbc, &rbx);
2689
+ InfSupDouble r = InfSupDouble::sinh(p1788_rbobj2infsupdouble(rbc));
2690
+ if (rbx != Qnil)
2691
+ r = InfSupDouble::intersection(r, p1788_rbobj2infsupdouble(rbx));
2692
+ P1788_NEW_RB_INTERVAL(rbr, r);
2693
+ return rbr;
2694
+ }
2695
+
2696
+
2697
+ /* Inverse hyperbolic cosine of _x_.
2698
+ *
2699
+ * acosh([๐’™])ย ย =ย ย hull{ acosh(๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’™]โˆฉ[1,+โˆž] }ย ย โІย ย โ„โ‚Š
2700
+ *
2701
+ * Reverse function: {acosh_rev}
2702
+ */
2703
+ static VALUE p1788_acosh(VALUE self, VALUE x)
2704
+ {
2705
+ VALUE r;
2706
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::acosh(p1788_rbobj2infsupdouble(x)));
2707
+ return r;
2708
+ }
2709
+
2710
+
2711
+ /* Reverse inverse hyperbolic cosine
2712
+ *
2713
+ * acosh_rev([๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| acosh(๐‘ฅ) โˆˆ [๐’„] }ย ย =ย ย { cosh(๐‘) \|ย ๐‘ โˆˆ [๐’„] โˆฉ โ„โ‚Š } โˆฉ [๐’™]ย ย โІย ย [1, +โˆž]
2714
+ *
2715
+ * Reverse function: {acosh}
2716
+ * @overload tanh_rev(c, x = ALL_REALS)
2717
+ */
2718
+ static VALUE p1788_acosh_rev(int argc, VALUE *argv, VALUE self)
2719
+ {
2720
+ VALUE rbc, rbx, rbr;
2721
+ rb_scan_args(argc, argv, "11", &rbc, &rbx);
2722
+ InfSupDouble r = InfSupDouble::cosh(InfSupDouble::intersection(p1788_rbobj2infsupdouble(rbc), pos_reals_set));
2723
+ if (rbx != Qnil)
2724
+ r = InfSupDouble::intersection(r, p1788_rbobj2infsupdouble(rbx));
2725
+ P1788_NEW_RB_INTERVAL(rbr, r);
2726
+ return rbr;
2727
+ }
2728
+
2729
+
2730
+ /* Inverse hyperbolic tangent of _x_.
2731
+ *
2732
+ * atanh([๐’™])ย ย =ย ย hull{ atanh(๐‘ฅ) \| ๐‘ฅ โˆˆ [๐’™]โˆฉ[-1,1] }ย ย โІย ย โ„
2733
+ *
2734
+ * Reverse function: {atanh_rev}
2735
+ */
2736
+ static VALUE p1788_atanh(VALUE self, VALUE x)
2737
+ {
2738
+ VALUE r;
2739
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::atanh(p1788_rbobj2infsupdouble(x)));
2740
+ return r;
2741
+ }
2742
+
2743
+
2744
+ /* Reverse inverse hyperbolic tangent
2745
+ *
2746
+ * atanh_rev([๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| atanh(๐‘ฅ) โˆˆ [๐’„] }ย ย =ย ย { tanh(๐‘) \|ย ๐‘ โˆˆ [๐’„] } โˆฉ [๐’™]ย ย โІย ย [-1, -1]
2747
+ *
2748
+ * Reverse function: {atanh}
2749
+ * @overload tanh_rev(c, x = ALL_REALS)
2750
+ */
2751
+ static VALUE p1788_atanh_rev(int argc, VALUE *argv, VALUE self)
2752
+ {
2753
+ VALUE rbc, rbx, rbr;
2754
+ rb_scan_args(argc, argv, "11", &rbc, &rbx);
2755
+ InfSupDouble r = InfSupDouble::tanh(p1788_rbobj2infsupdouble(rbc));
2756
+ if (rbx != Qnil)
2757
+ r = InfSupDouble::intersection(r, p1788_rbobj2infsupdouble(rbx));
2758
+ P1788_NEW_RB_INTERVAL(rbr, r);
2759
+ return rbr;
2760
+ }
2761
+
2762
+
2763
+ /* Sign of _x_
2764
+ *
2765
+ * sign([๐’™])ย ย โІย ย [-1, 1]ย ย (\\{-1} if <span style="text-decoration:overline">๐’™</span> < 0, \\{1} if <span style="text-decoration:underline">๐’™</span> > 0, \\{0} if [๐’™] = \\{0})
2766
+ */
2767
+ static VALUE p1788_sign(VALUE self, VALUE x)
2768
+ {
2769
+ VALUE r;
2770
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::sign(p1788_rbobj2infsupdouble(x)));
2771
+ return r;
2772
+ }
2773
+
2774
+
2775
+ /* Round _x_ towards +โˆž
2776
+ *
2777
+ * ceil([๐’™])ย ย =ย ย [ceil(<span style="text-decoration:underline">๐’™</span>), ceil(<span style="text-decoration:overline">๐’™</span>)]
2778
+ */
2779
+ static VALUE p1788_ceil(VALUE self, VALUE x)
2780
+ {
2781
+ VALUE r;
2782
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::ceil(p1788_rbobj2infsupdouble(x)));
2783
+ return r;
2784
+ }
2785
+
2786
+
2787
+ /* Round _x_ towards -โˆž
2788
+ *
2789
+ * floor([๐’™])ย ย =ย ย [floor(<span style="text-decoration:underline">๐’™</span>), floor(<span style="text-decoration:overline">๐’™</span>)]
2790
+ */
2791
+ static VALUE p1788_floor(VALUE self, VALUE x)
2792
+ {
2793
+ VALUE r;
2794
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::floor(p1788_rbobj2infsupdouble(x)));
2795
+ return r;
2796
+ }
2797
+
2798
+
2799
+ /* Inflate _x_ towards nearest integer bounds
2800
+ *
2801
+ * floorceil([๐’™])ย ย =ย ย [floor(<span style="text-decoration:underline">๐’™</span>), ceil(<span style="text-decoration:overline">๐’™</span>)]
2802
+ */
2803
+ static VALUE p1788_floorceil(VALUE self, VALUE x)
2804
+ {
2805
+ InfSupDouble inter = p1788_rbobj2infsupdouble(x);
2806
+ VALUE r;
2807
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble(std::floor(InfSupDouble::inf(inter)), std::ceil(InfSupDouble::sup(inter))));
2808
+ return r;
2809
+ }
2810
+
2811
+
2812
+ /* Inflate _x_ towards nearest integer bounds
2813
+ *
2814
+ * floorceil(๐’™)ย ย =ย ย [floor(<span style="text-decoration:underline">๐’™</span>), ceil(<span style="text-decoration:overline">๐’™</span>)]
2815
+ */
2816
+ static VALUE p1788_interval_floorceil(VALUE self, VALUE x)
2817
+ {
2818
+ InfSupDouble inter = p1788_rbobj2infsupdouble(x);
2819
+ VALUE r;
2820
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble(std::floor(InfSupDouble::inf(inter)), std::ceil(InfSupDouble::sup(inter))));
2821
+ return r;
2822
+ }
2823
+
2824
+
2825
+ /* Round _x_ towards 0
2826
+ *
2827
+ * trunc([๐’™])ย ย =ย ย [trunc(<span style="text-decoration:underline">๐’™</span>), trunc(<span style="text-decoration:overline">๐’™</span>)]
2828
+ */
2829
+ static VALUE p1788_trunc(VALUE self, VALUE x)
2830
+ {
2831
+ VALUE r;
2832
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::trunc(p1788_rbobj2infsupdouble(x)));
2833
+ return r;
2834
+ }
2835
+
2836
+
2837
+ /* Round _x_, ties to even
2838
+ *
2839
+ * Round bounds to their nearest integer values, rounding halfway cases to nearest even.
2840
+ *
2841
+ * round_ties_to_even([๐’™])ย ย =ย ย [round_ties_to_even(<span style="text-decoration:underline">๐’™</span>), round_ties_to_even(<span style="text-decoration:overline">๐’™</span>)]
2842
+ */
2843
+ static VALUE p1788_round_ties_to_even(VALUE self, VALUE x)
2844
+ {
2845
+ VALUE r;
2846
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::round_ties_to_even(p1788_rbobj2infsupdouble(x)));
2847
+ return r;
2848
+ }
2849
+
2850
+
2851
+ /* Round _x_, ties to away from zero
2852
+ *
2853
+ * Round bounds to their nearest integer values, rounding halfway cases away from zero.
2854
+ *
2855
+ * round_ties_to_away([๐’™])ย ย =ย ย [round_ties_to_away(<span style="text-decoration:underline">๐’™</span>), round_ties_to_away(<span style="text-decoration:overline">๐’™</span>)]
2856
+ */
2857
+ static VALUE p1788_round_ties_to_away(VALUE self, VALUE x)
2858
+ {
2859
+ VALUE r;
2860
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::round_ties_to_away(p1788_rbobj2infsupdouble(x)));
2861
+ return r;
2862
+ }
2863
+
2864
+
2865
+ /* Absolute value of _x_
2866
+ *
2867
+ * abs([๐’™])ย ย =ย ย hull{ \|๐‘ฅ\| ๏ฟจ ๐‘ฅ โˆˆ [๐’™] }ย ย โІย ย โ„โ‚Š
2868
+ *
2869
+ * Reverse function: {abs_rev}
2870
+ */
2871
+ static VALUE p1788_abs(VALUE self, VALUE x)
2872
+ {
2873
+ VALUE r;
2874
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::abs(p1788_rbobj2infsupdouble(x)));
2875
+ return r;
2876
+ }
2877
+
2878
+
2879
+ /* _+x_
2880
+ * @return [Interval] `self`
2881
+ */
2882
+ static VALUE p1788_pos(VALUE self, VALUE x)
2883
+ {
2884
+ VALUE r;
2885
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::pos(p1788_rbobj2infsupdouble(x)));
2886
+ return r;
2887
+ }
2888
+
2889
+
2890
+ /* Arithmetic opposite
2891
+ *
2892
+ * neg([๐’™])ย ย =ย ย { -๐‘ฅ ๏ฟจ ๐‘ฅ โˆˆ [๐’™] }ย ย =ย ย [-<span style="text-decoration:overline">๐’™</span>, -<span style="text-decoration:underline">๐’™</span>]
2893
+ *
2894
+ * Reverse function: {neg_rev}
2895
+ */
2896
+ static VALUE p1788_neg(VALUE self, VALUE x)
2897
+ {
2898
+ VALUE r;
2899
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::neg(p1788_rbobj2infsupdouble(x)));
2900
+ return r;
2901
+ }
2902
+
2903
+
2904
+ /* Reverse opposite
2905
+ *
2906
+ * neg_rev([๐’„], [๐’™])ย ย =ย ย { ๐‘ฅ โˆˆ [๐’™] \| -๐‘ฅ โˆˆ [๐’„] }ย ย =ย ย { -๐‘ \|ย ๐‘ โˆˆ [๐’„] } โˆฉ [๐’™]
2907
+ *
2908
+ * Reverse function: {neg}
2909
+ * @overload neg_rev(c, x = ALL_REALS)
2910
+ */
2911
+ static VALUE p1788_neg_rev(int argc, VALUE *argv, VALUE self)
2912
+ {
2913
+ VALUE rbc, rbx, rbr;
2914
+ rb_scan_args(argc, argv, "11", &rbc, &rbx);
2915
+ InfSupDouble r = InfSupDouble::neg(p1788_rbobj2infsupdouble(rbc));
2916
+ if (rbx != Qnil)
2917
+ r = InfSupDouble::intersection(r, p1788_rbobj2infsupdouble(rbx));
2918
+ P1788_NEW_RB_INTERVAL(rbr, r);
2919
+ return rbr;
2920
+ }
2921
+
2922
+
2923
+ /* Arithmetic addition
2924
+ *
2925
+ * add([๐’™], [๐’š])ย ย =ย ย hull{ ๐‘ฅ + ๐‘ฆ \| ๐‘ฅ โˆˆ [๐’™], ๐‘ฆ โˆˆ [๐’š] }ย ย โІย ย โ„
2926
+ *
2927
+ * Reverse function: {add_rev}
2928
+ */
2929
+ static VALUE p1788_add(VALUE self, VALUE x, VALUE y)
2930
+ {
2931
+ VALUE r;
2932
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::add(p1788_rbobj2infsupdouble(x), p1788_rbobj2infsupdouble(y)));
2933
+ return r;
2934
+ }
2935
+
2936
+
2937
+ /* Reverse addition
2938
+ *
2939
+ * add_rev([๐’ƒ], [๐’„], [๐’™])ย ย =ย ย { ๐‘ฅ โˆˆ [๐’™] \| โˆƒ ๐‘ โˆˆ [๐’ƒ] : ๐‘ฅ + ๐‘ โˆˆ [๐’„] }ย ย =ย ย { ๐‘ - ๐‘ \| ๐‘ โˆˆ [๐’ƒ], ๐‘ โˆˆ [๐’„] } โˆฉ [๐’™]
2940
+ *
2941
+ * Reverse function {add}
2942
+ * @overload add_rev(b, c, x = ALL_REALS)
2943
+ */
2944
+ static VALUE p1788_add_rev(int argc, VALUE *argv, VALUE self)
2945
+ {
2946
+ VALUE rbb, rbc, rbx, rbr;
2947
+ rb_scan_args(argc, argv, "21", &rbb, &rbc, &rbx);
2948
+ InfSupDouble r = InfSupDouble::sub(p1788_rbobj2infsupdouble(rbc), p1788_rbobj2infsupdouble(rbb));
2949
+ if (rbx != Qnil)
2950
+ r = InfSupDouble::intersection(r, p1788_rbobj2infsupdouble(rbx));
2951
+ P1788_NEW_RB_INTERVAL(rbr, r);
2952
+ return rbr;
2953
+ }
2954
+
2955
+
2956
+ /* Arithmetic subtraction
2957
+ *
2958
+ * sub([๐’™], [๐’š])ย ย =ย ย hull{ ๐‘ฅ - ๐‘ฆ \| ๐‘ฅ โˆˆ [๐’™], ๐‘ฆ โˆˆ [๐’š] }ย ย โІย ย โ„
2959
+ *
2960
+ * Reverse function: {sub_rev}
2961
+ */
2962
+ static VALUE p1788_sub(VALUE self, VALUE x, VALUE y)
2963
+ {
2964
+ VALUE r;
2965
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::sub(p1788_rbobj2infsupdouble(x), p1788_rbobj2infsupdouble(y)));
2966
+ return r;
2967
+ }
2968
+
2969
+
2970
+ /* Reverse subtraction
2971
+ *
2972
+ * sub_rev([๐’ƒ], [๐’„], [๐’™])ย ย =ย ย { ๐‘ฅ โˆˆ [๐’™] \| โˆƒ ๐‘ โˆˆ [๐’ƒ] : ๐‘ฅ - ๐‘ โˆˆ [๐’„] }ย ย =ย ย { ๐‘ + ๐‘ \| ๐‘ โˆˆ [๐’ƒ], ๐‘ โˆˆ [๐’„] } โˆฉ [๐’™]
2973
+ *
2974
+ * Reverse function {sub}
2975
+ * @overload sub_rev(b, c, x = ALL_REALS)
2976
+ */
2977
+ static VALUE p1788_sub_rev(int argc, VALUE *argv, VALUE self)
2978
+ {
2979
+ VALUE rbb, rbc, rbx, rbr;
2980
+ rb_scan_args(argc, argv, "21", &rbb, &rbc, &rbx);
2981
+ InfSupDouble r = InfSupDouble::add(p1788_rbobj2infsupdouble(rbc), p1788_rbobj2infsupdouble(rbb));
2982
+ if (rbx != Qnil)
2983
+ r = InfSupDouble::intersection(r, p1788_rbobj2infsupdouble(rbx));
2984
+ P1788_NEW_RB_INTERVAL(rbr, r);
2985
+ return rbr;
2986
+ }
2987
+
2988
+
2989
+ /* Arithmetic multiplication
2990
+ *
2991
+ * mul([๐’™], [๐’š])ย ย =ย ย hull{ ๐‘ฅโ‹…๐‘ฆ \| ๐‘ฅ โˆˆ [๐’™], ๐‘ฆ โˆˆ [๐’š] }ย ย โІย ย โ„
2992
+ *
2993
+ * Reverse function: {mul_rev}
2994
+ */
2995
+ static VALUE p1788_mul(VALUE self, VALUE x, VALUE y)
2996
+ {
2997
+ VALUE r;
2998
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::mul(p1788_rbobj2infsupdouble(x), p1788_rbobj2infsupdouble(y)));
2999
+ return r;
3000
+ }
3001
+
3002
+
3003
+ /* Arithmetic division
3004
+ *
3005
+ * div([๐’™], [๐’š])ย ย =ย ย hull{ ๐‘ฅ/๐‘ฆ \| ๐‘ฅ โˆˆ [๐’™], ๐‘ฆ โˆˆ [๐’š] }ย ย โІย ย โ„
3006
+ *
3007
+ * Reverse function: {div_rev}
3008
+ */
3009
+ static VALUE p1788_div(VALUE self, VALUE x, VALUE y)
3010
+ {
3011
+ VALUE r;
3012
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::div(p1788_rbobj2infsupdouble(x), p1788_rbobj2infsupdouble(y)));
3013
+ return r;
3014
+ }
3015
+
3016
+
3017
+ /* Reverse division
3018
+ *
3019
+ * div_rev([๐’ƒ], [๐’„], [๐’™])ย ย =ย ย { ๐‘ฅ โˆˆ [๐’™] \| โˆƒ ๐‘ โˆˆ [๐’ƒ] : ๐‘ฅ/๐‘ โˆˆ [๐’„] }ย ย =ย ย { ๐‘โ‹…๐‘ \| ๐‘ โˆˆ [๐’ƒ], ๐‘ โˆˆ [๐’„] } โˆฉ [๐’™]
3020
+ *
3021
+ * Reverse function {div}
3022
+ * @overload div_rev(b, c, x = ALL_REALS)
3023
+ */
3024
+ static VALUE p1788_div_rev(int argc, VALUE *argv, VALUE self)
3025
+ {
3026
+ VALUE rbb, rbc, rbx, rbr;
3027
+ rb_scan_args(argc, argv, "21", &rbb, &rbc, &rbx);
3028
+ InfSupDouble r = InfSupDouble::mul(p1788_rbobj2infsupdouble(rbc), p1788_rbobj2infsupdouble(rbb));
3029
+ if (rbx != Qnil)
3030
+ r = InfSupDouble::intersection(r, p1788_rbobj2infsupdouble(rbx));
3031
+ P1788_NEW_RB_INTERVAL(rbr, r);
3032
+ return rbr;
3033
+ }
3034
+
3035
+
3036
+ /* Two-output division
3037
+ *
3038
+ * Returns a pair of intervals, ๐’™ / (๐’š โˆฉ โ„โ‚‹) and ๐’™ / (๐’š โˆฉ โ„โ‚Š)
3039
+ * @param x [Interval] dividend
3040
+ * @param y [Interval] divisor
3041
+ * @return [Array<Interval>] [โˆ…, โˆ…] if ๐’™/๐’š is empty, [[๐’™/๐’š], โˆ…] if ๐’™/๐’š has one component, [[๐’™/๐’š]โ‚, [๐’™/๐’š]โ‚‚] if ๐’™/๐’š has two components
3042
+ */
3043
+ static VALUE p1788_div_to_pair(VALUE self, VALUE x, VALUE y)
3044
+ {
3045
+ VALUE r1, r2;
3046
+ std::pair< InfSupDouble, InfSupDouble > p = InfSupDouble::mul_rev_to_pair(p1788_rbobj2infsupdouble(y), p1788_rbobj2infsupdouble(x));
3047
+ P1788_NEW_RB_INTERVAL(r1, p.first);
3048
+ P1788_NEW_RB_INTERVAL(r2, p.second);
3049
+ return rb_ary_new_from_args(2, r1, r2);
3050
+ }
3051
+
3052
+
3053
+ /* Power function
3054
+ *
3055
+ * pow([๐’™], [๐’š])ย ย =ย ย hull{ ๐‘ฅ<sup>๐‘ฆ</sup> \| (๐‘ฅ, ๐‘ฆ) โˆˆ \\{๐‘ฅ โˆˆ [๐’™], ๐‘ฆ โˆˆ [๐’š] \| ๐‘ฅ>0\} โˆช \\{๐‘ฅ=0, ๐‘ฆ โˆˆ [๐’š] \| ๐‘ฆ>0\} }ย ย โІย ย โ„โ‚Š
3056
+ *
3057
+ * Reverse functions: {pow_rev1} and {pow_rev2}
3058
+ */
3059
+ static VALUE p1788_pow(VALUE self, VALUE x, VALUE y)
3060
+ {
3061
+ VALUE r;
3062
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::pow(p1788_rbobj2infsupdouble(x), p1788_rbobj2infsupdouble(y)));
3063
+ return r;
3064
+ }
3065
+
3066
+
3067
+ /* Power with integer exponent
3068
+ *
3069
+ * pow([๐’ƒ], n)ย ย =ย ย hull{ ๐‘โฟ \| ๐‘ โˆˆ [๐’ƒ] }ย ย โІย ย โ„ if n odd, โ„โ‚Š if n even, \\{1\} if n = 0
3070
+ *
3071
+ * Reverse function {pown_rev}
3072
+ * @param b [Interval] base
3073
+ * @param n [Integer] integer exponent
3074
+ */
3075
+ static VALUE p1788_pown(VALUE self, VALUE b, VALUE n)
3076
+ {
3077
+ VALUE r;
3078
+ int p;
3079
+ if (!RB_TYPE_P(n, T_FIXNUM))
3080
+ rb_raise(rb_eTypeError, "expecting an integer (Fixnum) as exponent, not a %" PRIsVALUE, rb_class_name(rb_class_of(n)));
3081
+ p = NUM2INT(n);
3082
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::pown(p1788_rbobj2infsupdouble(b), p));
3083
+ return r;
3084
+ }
3085
+
3086
+
3087
+ /* Minimum of two or more intervals
3088
+ *
3089
+ * min([๐’‚], [๐’ƒ])ย ย =ย ย [min(<span style="text-decoration:underline">๐’‚</span>, <span style="text-decoration:underline">๐’ƒ</span>), min(<span style="text-decoration:overline">๐’‚</span>, <span style="text-decoration:overline">๐’ƒ</span>)]
3090
+ * @overload min(a, b, ...)
3091
+ */
3092
+ static VALUE p1788_min(int argc, VALUE *argv, VALUE self)
3093
+ {
3094
+ if (argc < 2)
3095
+ rb_raise(rb_eArgError, "expecting at leas 2 arguments, not %d", argc);
3096
+ InfSupDouble m = InfSupDouble::min(p1788_rbobj2infsupdouble(argv[0]), p1788_rbobj2infsupdouble(argv[1]));
3097
+ for (int i = 2; i < argc; i++)
3098
+ m = InfSupDouble::min(m, p1788_rbobj2infsupdouble(argv[i]));
3099
+ VALUE r;
3100
+ P1788_NEW_RB_INTERVAL(r, m);
3101
+ return r;
3102
+ }
3103
+
3104
+
3105
+ /* Maximum of two or more intervals
3106
+ *
3107
+ * max([๐’‚], [๐’ƒ])ย ย =ย ย [max(<span style="text-decoration:underline">๐’‚</span>, <span style="text-decoration:underline">๐’ƒ</span>), max(<span style="text-decoration:overline">๐’‚</span>, <span style="text-decoration:overline">๐’ƒ</span>)]
3108
+ * @overload max(a, b, ...)
3109
+ */
3110
+ static VALUE p1788_max(int argc, VALUE *argv, VALUE self)
3111
+ {
3112
+ if (argc < 2)
3113
+ rb_raise(rb_eArgError, "expecting at leas 2 arguments, not %d", argc);
3114
+ InfSupDouble m = InfSupDouble::max(p1788_rbobj2infsupdouble(argv[0]), p1788_rbobj2infsupdouble(argv[1]));
3115
+ for (int i = 2; i < argc; i++)
3116
+ m = InfSupDouble::max(m, p1788_rbobj2infsupdouble(argv[i]));
3117
+ VALUE r;
3118
+ P1788_NEW_RB_INTERVAL(r, m);
3119
+ return r;
3120
+ }
3121
+
3122
+
3123
+ /* Cancellative subtraction
3124
+ *
3125
+ * Cancellative subtraction solves the following problem: Recover interval [๐’›] from intervals [๐’™] and [๐’š], given that [๐’™] = [๐’š] + [๐’›].
3126
+ *
3127
+ * For any two bounded intervals [๐’™] and [๐’š], cancel_minus([๐’™], [๐’š]) is the tightest interval [๐’›] such that [๐’š] + [๐’›] โЇ [๐’™].
3128
+ */
3129
+ static VALUE p1788_cancel_minus(VALUE self, VALUE x, VALUE y)
3130
+ {
3131
+ VALUE r;
3132
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::cancel_minus(p1788_rbobj2infsupdouble(x), p1788_rbobj2infsupdouble(y)));
3133
+ return r;
3134
+ }
3135
+
3136
+
3137
+ /* Cancellative addition
3138
+ *
3139
+ * cancel_plux([๐’™], [๐’š]) = cancel_minus([๐’™], -[๐’š])
3140
+ * @see cancel_minus
3141
+ */
3142
+ static VALUE p1788_cancel_plus(VALUE self, VALUE x, VALUE y)
3143
+ {
3144
+ VALUE r;
3145
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::cancel_plus(p1788_rbobj2infsupdouble(x), p1788_rbobj2infsupdouble(y)));
3146
+ return r;
3147
+ }
3148
+
3149
+
3150
+ /* Fused multiply add
3151
+ *
3152
+ *fma([๐’™], [๐’š], [๐’›])ย ย =ย ย hull{ ๐‘ฅโ‹…๐‘ฆ + ๐‘ง \| ๐‘ฅ โˆˆ [๐’™], ๐‘ฆ โˆˆ [๐’š], ๐‘ง โˆˆ [๐’›] }ย ย โІย ย โ„
3153
+ */
3154
+ static VALUE p1788_fma(VALUE self, VALUE x, VALUE y, VALUE z)
3155
+ {
3156
+ VALUE r;
3157
+ P1788_NEW_RB_INTERVAL(
3158
+ r,
3159
+ InfSupDouble::fma(
3160
+ p1788_rbobj2infsupdouble(x),
3161
+ p1788_rbobj2infsupdouble(y),
3162
+ p1788_rbobj2infsupdouble(z)
3163
+ )
3164
+ );
3165
+ return r;
3166
+ }
3167
+
3168
+
3169
+ /* Two-output division
3170
+ *
3171
+ * [๐’„]/[๐’ƒ] = { ๐‘ฅ โˆˆ โ„ \| โˆƒ ๐‘ โˆˆ [๐’ƒ] : ๐‘ฅโ‹…๐‘ โˆˆ [๐’„] }
3172
+ * @return [Array<Interval>] a two elements array of intervals: [โˆ…, โˆ…] if ๐’„/๐’ƒ is empty, [[๐’„/๐’ƒ], โˆ…] if ๐’„/๐’ƒ has one component, [[๐’„/๐’ƒ]โ‚, [๐’„/๐’ƒ]โ‚‚] if ๐’„/๐’ƒ has two components
3173
+ */
3174
+ static VALUE p1788_mul_rev_to_pair(VALUE self, VALUE b, VALUE c)
3175
+ {
3176
+ VALUE r1, r2;
3177
+ std::pair< InfSupDouble, InfSupDouble > p = InfSupDouble::mul_rev_to_pair(p1788_rbobj2infsupdouble(b), p1788_rbobj2infsupdouble(c));
3178
+ P1788_NEW_RB_INTERVAL(r1, p.first);
3179
+ P1788_NEW_RB_INTERVAL(r2, p.second);
3180
+ return rb_ary_new_from_args(2, r1, r2);
3181
+ }
3182
+
3183
+
3184
+ /* Reverse multiplication
3185
+ *
3186
+ * mul_rev([๐’ƒ], [๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| โˆƒ ๐‘ โˆˆ [๐’ƒ] : ๐‘ฅโ‹…๐‘ โˆˆ [๐’„] }ย ย โІย ย โ„
3187
+ *
3188
+ * Reverse function {mul}
3189
+ * @overload mul_rev(b, c, x = ALL_REALS)
3190
+ */
3191
+ static VALUE p1788_mul_rev(int argc, VALUE *argv, VALUE self)
3192
+ {
3193
+ VALUE b, c, x, r;
3194
+ rb_scan_args(argc, argv, "21", &b, &c, &x);
3195
+ if (x == Qnil) {
3196
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::mul_rev(p1788_rbobj2infsupdouble(b), p1788_rbobj2infsupdouble(c)));
3197
+ }
3198
+ else {
3199
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::mul_rev(p1788_rbobj2infsupdouble(b), p1788_rbobj2infsupdouble(c), p1788_rbobj2infsupdouble(x)));
3200
+ }
3201
+ return r;
3202
+ }
3203
+
3204
+
3205
+ /* Reverse square
3206
+ *
3207
+ * sqr_rev([๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| ๐‘ฅยฒ โˆˆ [๐’„] }ย ย โІย ย โ„
3208
+ *
3209
+ * Reverse function: {sqr}
3210
+ * @overload sqr_rev(c, x = ALL_REALS)
3211
+ */
3212
+ static VALUE p1788_sqr_rev(int argc, VALUE *argv, VALUE self)
3213
+ {
3214
+ VALUE x, c, r;
3215
+ rb_scan_args(argc, argv, "11", &c, &x);
3216
+ if (x == Qnil) {
3217
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::sqr_rev(p1788_rbobj2infsupdouble(c)));
3218
+ }
3219
+ else {
3220
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::sqr_rev(p1788_rbobj2infsupdouble(c), p1788_rbobj2infsupdouble(x)));
3221
+ }
3222
+ return r;
3223
+ }
3224
+
3225
+
3226
+ /* Reverse absolute value.
3227
+ *
3228
+ * abs_rev([๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] ๏ฟจ \|๐‘ฅ\| โˆˆ [๐’„] }ย ย โІย ย โ„
3229
+ *
3230
+ * Reverse function: {abs}
3231
+ * @overload abs_rev(c, x = ALL_REALS)
3232
+ */
3233
+ static VALUE p1788_abs_rev(int argc, VALUE *argv, VALUE self)
3234
+ {
3235
+ VALUE x, c, r;
3236
+ rb_scan_args(argc, argv, "11", &c, &x);
3237
+ if (x == Qnil) {
3238
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::abs_rev(p1788_rbobj2infsupdouble(c)));
3239
+ }
3240
+ else {
3241
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::abs_rev(p1788_rbobj2infsupdouble(c), p1788_rbobj2infsupdouble(x)));
3242
+ }
3243
+ return r;
3244
+ }
3245
+
3246
+
3247
+ /* Reverse power with integer exponent
3248
+ *
3249
+ * pown_rev(๐‘›, [๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| ๐‘ฅโฟ โˆˆ [๐’„] }ย ย โІย ย โ„
3250
+ *
3251
+ * Reverse function: {pown}
3252
+ * @overload pown_rev(n, c, x = ALL_REALS)
3253
+ * @param n [Integer] integer exponent
3254
+ * @param c [Interval]
3255
+ * @param x [Interval]
3256
+ */
3257
+ static VALUE p1788_pown_rev(int argc, VALUE *argv, VALUE self)
3258
+ {
3259
+ VALUE x, c, r, n;
3260
+ int p;
3261
+ rb_scan_args(argc, argv, "21", &n, &c, &x);
3262
+ if (!RB_TYPE_P(n, T_FIXNUM))
3263
+ rb_raise(rb_eTypeError, "expecting an integer (Fixnum) as exponent, not a %" PRIsVALUE, rb_class_name(rb_class_of(n)));
3264
+ p = NUM2INT(n);
3265
+ if (x == Qnil) {
3266
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::pown_rev(p1788_rbobj2infsupdouble(c), p));
3267
+ }
3268
+ else {
3269
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::pown_rev(p1788_rbobj2infsupdouble(c), p1788_rbobj2infsupdouble(x), p));
3270
+ }
3271
+ return r;
3272
+ }
3273
+
3274
+
3275
+ /* Reverse power function (base)
3276
+ *
3277
+ * pow_rev1([๐’ƒ], [๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| โˆƒ ๐‘ โˆˆ [๐’ƒ] : ๐‘ฅ<sup>๐‘</sup> โˆˆ [๐’„] }ย ย โІย ย โ„โ‚Š
3278
+ *
3279
+ * Reverse function: {pow}
3280
+ * @overload pow_rev1(b, c, x = ALL_REALS)
3281
+ */
3282
+ static VALUE p1788_pow_rev1(int argc, VALUE *argv, VALUE self)
3283
+ {
3284
+ VALUE rbb, rbc, rbx, rbr;
3285
+ rb_scan_args(argc, argv, "21", &rbb, &rbc, &rbx);
3286
+ InfSupDouble b = p1788_rbobj2infsupdouble(rbb);
3287
+ InfSupDouble c = p1788_rbobj2infsupdouble(rbc);
3288
+ InfSupDouble x = (rbx == Qnil) ? InfSupDouble(-INF, INF) : p1788_rbobj2infsupdouble(rbx);
3289
+
3290
+ InfSupDouble lnx = InfSupDouble::log(x);
3291
+ InfSupDouble m = InfSupDouble::intersection(InfSupDouble::log(c), InfSupDouble::mul(b, lnx));
3292
+ InfSupDouble l = InfSupDouble::mul_rev(b, m, lnx);
3293
+ InfSupDouble r = InfSupDouble::intersection(InfSupDouble::exp(l), x);
3294
+
3295
+ P1788_NEW_RB_INTERVAL(rbr, r);
3296
+ return rbr;
3297
+ }
3298
+
3299
+
3300
+ /* Reverse power function (exponent)
3301
+ *
3302
+ * pow_rev2([๐’‚], [๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| โˆƒ ๐‘Ž โˆˆ [๐’‚] : ๐‘Ž<sup>๐‘ฅ</sup> โˆˆ [๐’„] }ย ย โІย ย โ„
3303
+ *
3304
+ * Reverse function: {pow}
3305
+ * @overload pow_rev2(a, c, x = ALL_REALS)
3306
+ */
3307
+ static VALUE p1788_pow_rev2(int argc, VALUE *argv, VALUE self)
3308
+ {
3309
+ VALUE rba, rbc, rbx, rbr;
3310
+ rb_scan_args(argc, argv, "21", &rba, &rbc, &rbx);
3311
+ InfSupDouble a = p1788_rbobj2infsupdouble(rba);
3312
+ InfSupDouble c = p1788_rbobj2infsupdouble(rbc);
3313
+ InfSupDouble x = (rbx == Qnil) ? InfSupDouble(-INF, INF) : p1788_rbobj2infsupdouble(rbx);
3314
+
3315
+ InfSupDouble lna = InfSupDouble::log(a);
3316
+ InfSupDouble m = InfSupDouble::intersection(InfSupDouble::log(c), InfSupDouble::mul(x, lna));
3317
+ InfSupDouble r = InfSupDouble::mul_rev(lna, m, x);
3318
+
3319
+ P1788_NEW_RB_INTERVAL(rbr, r);
3320
+ return rbr;
3321
+ }
3322
+
3323
+
3324
+ /* Reverse sine
3325
+ *
3326
+ * sin_rev([๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| sin(๐‘ฅ) โˆˆ [๐’„] }ย ย โІย ย โ„
3327
+ *
3328
+ * Reverse function: {sin}
3329
+ * @overload sin_rev(c, x = ALL_REALS)
3330
+ */
3331
+ static VALUE p1788_sin_rev(int argc, VALUE *argv, VALUE self)
3332
+ {
3333
+ VALUE x, c, r;
3334
+ rb_scan_args(argc, argv, "11", &c, &x);
3335
+ if (x == Qnil) {
3336
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::sin_rev(p1788_rbobj2infsupdouble(c)));
3337
+ }
3338
+ else {
3339
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::sin_rev(p1788_rbobj2infsupdouble(c), p1788_rbobj2infsupdouble(x)));
3340
+ }
3341
+ return r;
3342
+ }
3343
+
3344
+
3345
+ /* Reverse cosine
3346
+ *
3347
+ * cos_rev([๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| cos(๐‘ฅ) โˆˆ [๐’„] }ย ย โІย ย โ„
3348
+ *
3349
+ * Reverse function: {cos}
3350
+ * @overload cos_rev(c, x = ALL_REALS)
3351
+ */
3352
+ static VALUE p1788_cos_rev(int argc, VALUE *argv, VALUE self)
3353
+ {
3354
+ VALUE x, c, r;
3355
+ rb_scan_args(argc, argv, "11", &c, &x);
3356
+ if (x == Qnil) {
3357
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::cos_rev(p1788_rbobj2infsupdouble(c)));
3358
+ }
3359
+ else {
3360
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::cos_rev(p1788_rbobj2infsupdouble(c), p1788_rbobj2infsupdouble(x)));
3361
+ }
3362
+ return r;
3363
+ }
3364
+
3365
+
3366
+ /* Reverse tangent
3367
+ *
3368
+ * tan_rev([๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| tan(๐‘ฅ) โˆˆ [๐’„] }ย ย โІย ย โ„
3369
+ *
3370
+ * Reverse function: {tan}
3371
+ * @overload tan_rev(c, x = ALL_REALS)
3372
+ */
3373
+ static VALUE p1788_tan_rev(int argc, VALUE *argv, VALUE self)
3374
+ {
3375
+ VALUE x, c, r;
3376
+ rb_scan_args(argc, argv, "11", &c, &x);
3377
+ if (x == Qnil) {
3378
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::tan_rev(p1788_rbobj2infsupdouble(c)));
3379
+ }
3380
+ else {
3381
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::tan_rev(p1788_rbobj2infsupdouble(c), p1788_rbobj2infsupdouble(x)));
3382
+ }
3383
+ return r;
3384
+ }
3385
+
3386
+
3387
+ /* Reverse hyperbolic cosine
3388
+ *
3389
+ * cosh_rev([๐’„], [๐’™])ย ย =ย ย hull{ ๐‘ฅ โˆˆ [๐’™] \| cosh(๐‘ฅ) โˆˆ [๐’„] }ย ย โІย ย โ„
3390
+ *
3391
+ * Reverse function: {cosh}
3392
+ * @overload cosh_rev(c, x = ALL_REALS)
3393
+ */
3394
+ static VALUE p1788_cosh_rev(int argc, VALUE *argv, VALUE self)
3395
+ {
3396
+ VALUE x, c, r;
3397
+ rb_scan_args(argc, argv, "11", &c, &x);
3398
+ if (x == Qnil) {
3399
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::cosh_rev(p1788_rbobj2infsupdouble(c)));
3400
+ }
3401
+ else {
3402
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::cosh_rev(p1788_rbobj2infsupdouble(c), p1788_rbobj2infsupdouble(x)));
3403
+ }
3404
+ return r;
3405
+ }
3406
+
3407
+
3408
+ /* Intersection
3409
+ *
3410
+ * intersection([๐’™], [๐’š])ย ย =ย ย [๐’™] โˆฉ [๐’š]
3411
+ */
3412
+ static VALUE p1788_intersection(VALUE self, VALUE x, VALUE y)
3413
+ {
3414
+ VALUE r;
3415
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::intersection(p1788_rbobj2infsupdouble(x), p1788_rbobj2infsupdouble(y)));
3416
+ return r;
3417
+ }
3418
+
3419
+
3420
+ /* Interval hull of the union of _x_ and _y_
3421
+ *
3422
+ * convex_hull([๐’™], [๐’š])ย ย =ย ย hull( [๐’™] โˆช [๐’š] )
3423
+ */
3424
+ static VALUE p1788_convex_hull(VALUE self, VALUE x, VALUE y)
3425
+ {
3426
+ VALUE r;
3427
+ P1788_NEW_RB_INTERVAL(r, InfSupDouble::convex_hull(p1788_rbobj2infsupdouble(x), p1788_rbobj2infsupdouble(y)));
3428
+ return r;
3429
+ }
3430
+
3431
+
3432
+ static void print_inspect_obj(VALUE obj)
3433
+ {
3434
+ VALUE str = rb_funcallv(obj, rb_intern("inspect"), 0, NULL);
3435
+ printf("%s\n", StringValueCStr(str));
3436
+ }
3437
+
3438
+
3439
+ static VALUE my_test_proc_func(VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg)
3440
+ {
3441
+ printf("----------------------------------------------------\n");
3442
+ printf("yielded_arg = "); print_inspect_obj(yielded_arg);
3443
+ printf("callback_arg = "); print_inspect_obj(callback_arg);
3444
+ printf("argc = %d\n", argc);
3445
+ for (int i = 0; i < argc; i++) {
3446
+ printf("argv[%d] = ", i);
3447
+ print_inspect_obj(argv[i]);
3448
+ }
3449
+ printf("blockarg = "); print_inspect_obj(blockarg);
3450
+ printf("----------------------------------------------------\n");
3451
+ return INT2NUM(sizeof(InfSupDouble));
3452
+ }
3453
+
3454
+
3455
+ /* @return [Proc]
3456
+ */
3457
+ static VALUE p1788_test(int argc, VALUE *argv, VALUE self)
3458
+ {
3459
+ VALUE rb_proc_new_arg = rb_sprintf("rb_proc_new_arg");
3460
+ return rb_proc_new(my_test_proc_func, rb_proc_new_arg);
3461
+ // return rb_block_call(rb_mKernel, rb_intern("lambda"), 0, NULL, my_test_proc_func, rb_proc_new_arg);
3462
+ }
3463
+
3464
+
3465
+ /* This function is the content of Init_p1788() moved out of the 'extern "C" {}'
3466
+ * to allow yard to parse it.
3467
+ */
3468
+ static inline void Init_p1788_func()
3469
+ {
3470
+ id_to_s = rb_intern("to_s");
3471
+
3472
+ m_P1788 = rb_define_module("P1788");
3473
+ c_Interval = rb_define_class_under(m_P1788, "Interval", rb_cObject);
3474
+ rb_define_alloc_func(c_Interval, p1788_interval_alloc);
3475
+ rb_undef_method(rb_class_of(c_Interval), "allocate");
3476
+
3477
+ rb_define_method(c_Interval, "initialize", p1788_interval_initialize, -1);
3478
+ rb_define_method(c_Interval, "inspect", p1788_interval_inspect, 0);
3479
+ rb_define_method(c_Interval, "dup", p1788_interval_dup, 0);
3480
+ rb_define_method(c_Interval, "clone", p1788_interval_clone, 0);
3481
+ rb_define_method(c_Interval, "to_a", p1788_interval_to_a, 0);
3482
+ rb_define_method(c_Interval, "to_s", p1788_interval_to_s, 0);
3483
+ rb_define_method(c_Interval, "to_latex", p1788_interval_to_latex, -1);
3484
+ rb_define_method(c_Interval, "coerce", p1788_interval_coerce, 1);
3485
+ rb_define_method(c_Interval, "===", p1788_interval_tripleequal, 1);
3486
+
3487
+ /* Boolean functions on intervals */
3488
+ rb_define_method(c_Interval, "empty?", p1788_interval_empty, 0);
3489
+ rb_define_method(c_Interval, "entire?", p1788_interval_entire, 0);
3490
+ rb_define_alias(c_Interval, "all_reals?", "entire?");
3491
+ rb_define_method(c_Interval, "pos_reals?", p1788_interval_pos_reals, 0);
3492
+ rb_define_method(c_Interval, "neg_reals?", p1788_interval_neg_reals, 0);
3493
+ rb_define_method(c_Interval, "positive?", p1788_interval_positive, 0);
3494
+ rb_define_method(c_Interval, "strictly_positive?", p1788_interval_strictly_positive, 0);
3495
+ rb_define_method(c_Interval, "negative?", p1788_interval_negative, 0);
3496
+ rb_define_method(c_Interval, "strictly_negative?", p1788_interval_strictly_negative, 0);
3497
+ rb_define_method(c_Interval, "common?", p1788_interval_common, 0);
3498
+ rb_define_method(c_Interval, "finite?", p1788_interval_finite, 0);
3499
+ rb_define_method(c_Interval, "symmetric?", p1788_interval_symmetric, 0);
3500
+ rb_define_method(c_Interval, "singleton?", p1788_interval_singleton, 0);
3501
+ rb_define_method(c_Interval, "eql?", p1788_interval_eql, 1);
3502
+ rb_define_method(c_Interval, "==", p1788_interval_equal, 1);
3503
+ rb_define_method(c_Interval, "less?", p1788_interval_less, 1);
3504
+ rb_define_method(c_Interval, "greater?", p1788_interval_greater, 1);
3505
+ rb_define_method(c_Interval, "strictly_less?", p1788_interval_strictly_less, 1);
3506
+ rb_define_method(c_Interval, "strictly_greater?", p1788_interval_strictly_greater, 1);
3507
+ rb_define_method(c_Interval, "precedes?", p1788_interval_precedes, 1);
3508
+ rb_define_method(c_Interval, "succeeds?", p1788_interval_succeeds, 1);
3509
+ rb_define_method(c_Interval, "strictly_precedes?", p1788_interval_strictly_precedes, 1);
3510
+ rb_define_method(c_Interval, "strictly_succeeds?", p1788_interval_strictly_succeeds, 1);
3511
+ rb_define_method(c_Interval, "disjoint_from?", p1788_interval_disjoint, 1);
3512
+ rb_define_method(c_Interval, "intersect?", p1788_interval_intersect, 1);
3513
+ rb_define_method(c_Interval, "strict_subset_of?", p1788_interval_strict_subset, 1);
3514
+ rb_define_method(c_Interval, "subset_of?", p1788_interval_subset, 1);
3515
+ rb_define_method(c_Interval, "strictly_contain?", p1788_interval_strictly_contain, 1);
3516
+ rb_define_method(c_Interval, "contain?", p1788_interval_contain, 1);
3517
+ rb_define_method(c_Interval, "include?", p1788_interval_include, 1);
3518
+
3519
+ /* Numeric functions on intervals */
3520
+ rb_define_method(c_Interval, "inf", p1788_interval_inf, 0);
3521
+ rb_define_alias(c_Interval, "lower_bound", "inf");
3522
+ rb_define_method(c_Interval, "sup", p1788_interval_sup, 0);
3523
+ rb_define_alias(c_Interval, "upper_bound", "sup");
3524
+ rb_define_method(c_Interval, "midpoint", p1788_interval_mid, 0);
3525
+ rb_define_method(c_Interval, "splitpoint", p1788_interval_splitpoint, 0);
3526
+ rb_define_method(c_Interval, "radius", p1788_interval_rad, 0);
3527
+ rb_define_method(c_Interval, "mid_rad", p1788_interval_mid_rad, 0);
3528
+ rb_define_method(c_Interval, "width", p1788_interval_wid, 0);
3529
+ rb_define_method(c_Interval, "magnitude", p1788_interval_mag, 0);
3530
+ rb_define_method(c_Interval, "mignitude", p1788_interval_mig, 0);
3531
+
3532
+ /* Set operations */
3533
+ rb_define_method(c_Interval, "intersection", p1788_interval_intersection, 1);
3534
+ rb_define_alias(c_Interval, "&", "intersection");
3535
+ rb_define_method(c_Interval, "convex_hull", p1788_interval_convex_hull, 1);
3536
+ rb_define_alias(c_Interval, "|", "convex_hull");
3537
+ rb_define_method(c_Interval, "bisect", p1788_interval_bisect, 0);
3538
+ rb_define_alias(c_Interval, "split", "bisect");
3539
+
3540
+ /* Forward elementary functions */
3541
+ rb_define_method(c_Interval, "recip", p1788_interval_recip, 0);
3542
+ rb_define_method(c_Interval, "sqr", p1788_interval_sqr, 0);
3543
+ rb_define_method(c_Interval, "sqrt", p1788_interval_sqrt, 0);
3544
+ rb_define_method(c_Interval, "exp", p1788_interval_exp, 0);
3545
+ rb_define_method(c_Interval, "exp2", p1788_interval_exp2, 0);
3546
+ rb_define_method(c_Interval, "exp10", p1788_interval_exp10, 0);
3547
+ rb_define_method(c_Interval, "log", p1788_interval_log, 0);
3548
+ rb_define_method(c_Interval, "log2", p1788_interval_log2, 0);
3549
+ rb_define_method(c_Interval, "log10", p1788_interval_log10, 0);
3550
+ rb_define_method(c_Interval, "sin", p1788_interval_sin, 0);
3551
+ rb_define_method(c_Interval, "cos", p1788_interval_cos, 0);
3552
+ rb_define_method(c_Interval, "tan", p1788_interval_tan, 0);
3553
+ rb_define_method(c_Interval, "asin", p1788_interval_asin, 0);
3554
+ rb_define_method(c_Interval, "acos", p1788_interval_acos, 0);
3555
+ rb_define_method(c_Interval, "atan", p1788_interval_atan, 0);
3556
+ rb_define_method(c_Interval, "sinh", p1788_interval_sinh, 0);
3557
+ rb_define_method(c_Interval, "cosh", p1788_interval_cosh, 0);
3558
+ rb_define_method(c_Interval, "tanh", p1788_interval_tanh, 0);
3559
+ rb_define_method(c_Interval, "asinh", p1788_interval_asinh, 0);
3560
+ rb_define_method(c_Interval, "acosh", p1788_interval_acosh, 0);
3561
+ rb_define_method(c_Interval, "atanh", p1788_interval_atanh, 0);
3562
+ rb_define_method(c_Interval, "sign", p1788_interval_sign, 0);
3563
+ rb_define_method(c_Interval, "ceil", p1788_interval_ceil, 0);
3564
+ rb_define_method(c_Interval, "floor", p1788_interval_floor, 0);
3565
+ rb_define_method(c_Interval, "floorceil", p1788_interval_floorceil, 0);
3566
+ rb_define_method(c_Interval, "truncate", p1788_interval_trunc, 0);
3567
+ rb_define_method(c_Interval, "round_ties_to_even", p1788_interval_round_ties_to_even, 0);
3568
+ rb_define_method(c_Interval, "round_ties_to_away", p1788_interval_round_ties_to_away, 0);
3569
+ rb_define_method(c_Interval, "abs", p1788_interval_abs, 0);
3570
+ rb_define_method(c_Interval, "+@", p1788_interval_pos, 0);
3571
+ rb_define_method(c_Interval, "-@", p1788_interval_neg, 0);
3572
+ rb_define_method(c_Interval, "+", p1788_interval_add, 1);
3573
+ rb_define_method(c_Interval, "-", p1788_interval_sub, 1);
3574
+ rb_define_method(c_Interval, "*", p1788_interval_mul, 1);
3575
+ rb_define_method(c_Interval, "/", p1788_interval_div, 1);
3576
+ rb_define_method(c_Interval, "div_to_pair", p1788_interval_div_to_pair, 1);
3577
+ rb_define_method(c_Interval, "**", p1788_interval_powop, 1);
3578
+ rb_define_method(c_Interval, "pow", p1788_interval_pow, 1);
3579
+ rb_define_method(c_Interval, "pown", p1788_interval_pown, 1);
3580
+ rb_define_method(c_Interval, "min", p1788_interval_min, 1);
3581
+ rb_define_method(c_Interval, "max", p1788_interval_max, 1);
3582
+ rb_define_method(c_Interval, "cancel_plus", p1788_interval_cancel_plus, 1);
3583
+ rb_define_method(c_Interval, "cancel_minus", p1788_interval_cancel_minus, 1);
3584
+ rb_define_method(c_Interval, "fma", p1788_interval_fma, 2);
3585
+
3586
+ /* reverse elementary functions */
3587
+ rb_define_method(c_Interval, "mul_rev_to_pair", p1788_interval_mul_rev_to_pair, 1);
3588
+ rb_define_method(c_Interval, "mul_rev", p1788_interval_mul_rev, -1);
3589
+ rb_define_method(c_Interval, "sqr_rev", p1788_interval_sqr_rev, -1);
3590
+ rb_define_method(c_Interval, "abs_rev", p1788_interval_abs_rev, -1);
3591
+ rb_define_method(c_Interval, "pown_rev", p1788_interval_pown_rev, -1);
3592
+ rb_define_method(c_Interval, "pow_rev1", p1788_interval_pow_rev1, -1);
3593
+ rb_define_method(c_Interval, "pow_rev2", p1788_interval_pow_rev2, -1);
3594
+ rb_define_method(c_Interval, "sin_rev", p1788_interval_sin_rev, -1);
3595
+ rb_define_method(c_Interval, "cos_rev", p1788_interval_cos_rev, -1);
3596
+ rb_define_method(c_Interval, "tan_rev", p1788_interval_tan_rev, -1);
3597
+ rb_define_method(c_Interval, "cosh_rev", p1788_interval_cosh_rev, -1);
3598
+
3599
+ rb_define_module_function(c_Interval, "[]", p1788_interval_rb_new, -1);
3600
+
3601
+ /* Constants */
3602
+
3603
+ VALUE empty_set;
3604
+ P1788_NEW_RB_INTERVAL(empty_set, InfSupDouble());
3605
+ /* โˆ…
3606
+ */
3607
+ rb_define_const(c_Interval, "EMPTY_SET", empty_set);
3608
+
3609
+ VALUE all_reals;
3610
+ P1788_NEW_RB_INTERVAL(all_reals, all_reals_set);
3611
+ /* [-โˆž, โˆž]
3612
+ */
3613
+ rb_define_const(c_Interval, "ALL_REALS", all_reals);
3614
+
3615
+ VALUE pos_reals;
3616
+ P1788_NEW_RB_INTERVAL(pos_reals, pos_reals_set);
3617
+ /* [0, โˆž]
3618
+ */
3619
+ rb_define_const(c_Interval, "POS_REALS", pos_reals);
3620
+
3621
+ VALUE neg_reals;
3622
+ P1788_NEW_RB_INTERVAL(neg_reals, neg_reals_set);
3623
+ /* [-โˆž, 0]
3624
+ */
3625
+ rb_define_const(c_Interval, "NEG_REALS", neg_reals);
3626
+
3627
+ VALUE pi;
3628
+ P1788_NEW_RB_INTERVAL(pi, pi_set);
3629
+ /* [โ†“๐›‘โ†“, โ†‘๐›‘โ†‘]
3630
+ */
3631
+ rb_define_const(c_Interval, "PI", pi);
3632
+
3633
+ VALUE hpi;
3634
+ P1788_NEW_RB_INTERVAL(hpi, hpi_set);
3635
+ /* [โ†“๐›‘/2โ†“, โ†‘๐›‘/2โ†‘]
3636
+ */
3637
+ rb_define_const(c_Interval, "HALF_PI", hpi);
3638
+
3639
+ VALUE pi2;
3640
+ P1788_NEW_RB_INTERVAL(pi2, pi2_set);
3641
+ /* [โ†“2๐›‘โ†“, โ†‘2๐›‘โ†‘]
3642
+ */
3643
+ rb_define_const(c_Interval, "TWO_PI", pi2);
3644
+
3645
+ VALUE minus_pi_pi;
3646
+ P1788_NEW_RB_INTERVAL(minus_pi_pi, minus_pi_pi_set);
3647
+ /* [โ†“-๐›‘โ†“, โ†‘๐›‘โ†‘]
3648
+ */
3649
+ rb_define_const(c_Interval, "MINUS_PI_PI", minus_pi_pi);
3650
+
3651
+ VALUE minus_hpi_hpi;
3652
+ P1788_NEW_RB_INTERVAL(minus_hpi_hpi, minus_hpi_hpi_set);
3653
+ /* [โ†“-๐›‘/2โ†“, โ†‘๐›‘/2โ†‘]
3654
+ */
3655
+ rb_define_const(c_Interval, "MINUS_HPI_HPI", minus_hpi_hpi);
3656
+
3657
+ VALUE minus_one_one;
3658
+ P1788_NEW_RB_INTERVAL(minus_one_one, minus_one_one_set);
3659
+ /* [-1, 1]
3660
+ */
3661
+ rb_define_const(c_Interval, "MINUS_ONE_ONE", minus_one_one);
3662
+
3663
+ VALUE e;
3664
+ P1788_NEW_RB_INTERVAL(e, e_set);
3665
+ /* [โ†“๐‘’โ†“, โ†‘๐‘’โ†‘]
3666
+ */
3667
+ rb_define_const(c_Interval, "E", e);
3668
+
3669
+ VALUE libieeep1788_version = rb_sprintf(P1788_VERSION_STRING);
3670
+ /* Version of libieeep1788
3671
+ * @return [String]
3672
+ */
3673
+ rb_define_const(m_P1788, "LIBIEEEP1788_VERSION", libieeep1788_version);
3674
+
3675
+ /* Math module functions */
3676
+ rb_define_module_function(m_P1788, "recip", p1788_recip, 1);
3677
+ rb_define_module_function(m_P1788, "sqr", p1788_sqr, 1);
3678
+ rb_define_module_function(m_P1788, "sqrt", p1788_sqrt, 1);
3679
+ rb_define_module_function(m_P1788, "exp", p1788_exp, 1);
3680
+ rb_define_module_function(m_P1788, "exp2", p1788_exp2, 1);
3681
+ rb_define_module_function(m_P1788, "exp10", p1788_exp10, 1);
3682
+ rb_define_module_function(m_P1788, "log", p1788_log, 1);
3683
+ rb_define_module_function(m_P1788, "log2", p1788_log2, 1);
3684
+ rb_define_module_function(m_P1788, "log10", p1788_log10, 1);
3685
+ rb_define_module_function(m_P1788, "sin", p1788_sin, 1);
3686
+ rb_define_module_function(m_P1788, "cos", p1788_cos, 1);
3687
+ rb_define_module_function(m_P1788, "tan", p1788_tan, 1);
3688
+ rb_define_module_function(m_P1788, "asin", p1788_asin, 1);
3689
+ rb_define_module_function(m_P1788, "acos", p1788_acos, 1);
3690
+ rb_define_module_function(m_P1788, "atan", p1788_atan, 1);
3691
+ rb_define_module_function(m_P1788, "atan2", p1788_atan2, 2);
3692
+ rb_define_module_function(m_P1788, "sinh", p1788_sinh, 1);
3693
+ rb_define_module_function(m_P1788, "cosh", p1788_cosh, 1);
3694
+ rb_define_module_function(m_P1788, "tanh", p1788_tanh, 1);
3695
+ rb_define_module_function(m_P1788, "asinh", p1788_asinh, 1);
3696
+ rb_define_module_function(m_P1788, "acosh", p1788_acosh, 1);
3697
+ rb_define_module_function(m_P1788, "atanh", p1788_atanh, 1);
3698
+ rb_define_module_function(m_P1788, "sign", p1788_sign, 1);
3699
+ rb_define_module_function(m_P1788, "ceil", p1788_ceil, 1);
3700
+ rb_define_module_function(m_P1788, "floor", p1788_floor, 1);
3701
+ rb_define_module_function(m_P1788, "floorceil", p1788_floorceil, 1);
3702
+ rb_define_module_function(m_P1788, "trunc", p1788_trunc, 1);
3703
+ rb_define_module_function(m_P1788, "round_ties_to_even", p1788_round_ties_to_even, 1);
3704
+ rb_define_module_function(m_P1788, "round_ties_to_away", p1788_round_ties_to_away, 1);
3705
+ rb_define_module_function(m_P1788, "abs", p1788_abs, 1);
3706
+ rb_define_module_function(m_P1788, "pos", p1788_pos, 1);
3707
+ rb_define_module_function(m_P1788, "neg", p1788_neg, 1);
3708
+ rb_define_module_function(m_P1788, "add", p1788_add, 2);
3709
+ rb_define_module_function(m_P1788, "sub", p1788_sub, 2);
3710
+ rb_define_module_function(m_P1788, "mul", p1788_mul, 2);
3711
+ rb_define_module_function(m_P1788, "div", p1788_div, 2);
3712
+ rb_define_module_function(m_P1788, "div_to_pair", p1788_div_to_pair, 2);
3713
+ rb_define_module_function(m_P1788, "pow", p1788_pow, 2);
3714
+ rb_define_module_function(m_P1788, "pown", p1788_pown, 2);
3715
+ rb_define_module_function(m_P1788, "min", p1788_min, -1);
3716
+ rb_define_module_function(m_P1788, "max", p1788_max, -1);
3717
+ rb_define_module_function(m_P1788, "cancel_plus", p1788_cancel_plus, 2);
3718
+ rb_define_module_function(m_P1788, "cancel_minus", p1788_cancel_minus, 2);
3719
+ rb_define_module_function(m_P1788, "fma", p1788_fma, 3);
3720
+
3721
+ rb_define_module_function(m_P1788, "recip_rev", p1788_recip_rev, -1);
3722
+ rb_define_module_function(m_P1788, "sqr_rev", p1788_sqr_rev, -1);
3723
+ rb_define_module_function(m_P1788, "sqrt_rev", p1788_sqrt_rev, -1);
3724
+ rb_define_module_function(m_P1788, "exp_rev", p1788_exp_rev, -1);
3725
+ rb_define_module_function(m_P1788, "exp2_rev", p1788_exp2_rev, -1);
3726
+ rb_define_module_function(m_P1788, "exp10_rev", p1788_exp10_rev, -1);
3727
+ rb_define_module_function(m_P1788, "log_rev", p1788_log_rev, -1);
3728
+ rb_define_module_function(m_P1788, "log2_rev", p1788_log2_rev, -1);
3729
+ rb_define_module_function(m_P1788, "log10_rev", p1788_log10_rev, -1);
3730
+ rb_define_module_function(m_P1788, "sin_rev", p1788_sin_rev, -1);
3731
+ rb_define_module_function(m_P1788, "cos_rev", p1788_cos_rev, -1);
3732
+ rb_define_module_function(m_P1788, "tan_rev", p1788_tan_rev, -1);
3733
+ rb_define_module_function(m_P1788, "asin_rev", p1788_asin_rev, -1);
3734
+ rb_define_module_function(m_P1788, "acos_rev", p1788_acos_rev, -1);
3735
+ rb_define_module_function(m_P1788, "atan_rev", p1788_atan_rev, -1);
3736
+ rb_define_module_function(m_P1788, "sinh_rev", p1788_sinh_rev, -1);
3737
+ rb_define_module_function(m_P1788, "cosh_rev", p1788_cosh_rev, -1);
3738
+ rb_define_module_function(m_P1788, "tanh_rev", p1788_tanh_rev, -1);
3739
+ rb_define_module_function(m_P1788, "asinh_rev", p1788_asinh_rev, -1);
3740
+ rb_define_module_function(m_P1788, "acosh_rev", p1788_acosh_rev, -1);
3741
+ rb_define_module_function(m_P1788, "atanh_rev", p1788_atanh_rev, -1);
3742
+ rb_define_module_function(m_P1788, "abs_rev", p1788_abs_rev, -1);
3743
+ rb_define_module_function(m_P1788, "neg_rev", p1788_neg_rev, -1);
3744
+ rb_define_module_function(m_P1788, "add_rev", p1788_add_rev, -1);
3745
+ rb_define_module_function(m_P1788, "sub_rev", p1788_sub_rev, -1);
3746
+ rb_define_module_function(m_P1788, "mul_rev", p1788_mul_rev, -1);
3747
+ rb_define_module_function(m_P1788, "mul_rev_to_pair", p1788_mul_rev_to_pair, 2);
3748
+ rb_define_module_function(m_P1788, "div_rev", p1788_div_rev, -1);
3749
+ rb_define_module_function(m_P1788, "pown_rev", p1788_pown_rev, -1);
3750
+ rb_define_module_function(m_P1788, "pow_rev1", p1788_pow_rev1, -1);
3751
+ rb_define_module_function(m_P1788, "pow_rev2", p1788_pow_rev2, -1);
3752
+ rb_define_module_function(m_P1788, "test", p1788_test, -1);
3753
+
3754
+ rb_define_module_function(m_P1788, "intersection", p1788_intersection, 2);
3755
+ rb_define_module_function(m_P1788, "convex_hull", p1788_convex_hull, 2);
3756
+ }
3757
+
3758
+ extern "C" {
3759
+ void Init_p1788()
3760
+ {
3761
+ Init_p1788_func();
3762
+ }
3763
+ }
3764
+