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,1674 @@
1
+ //
2
+ // libieeep1788
3
+ //
4
+ // An implementation of the preliminary IEEE P1788 standard for
5
+ // interval arithmetic
6
+ //
7
+ //
8
+ // Copyright 2013 - 2015
9
+ //
10
+ // Marco Nehmeier (nehmeier@informatik.uni-wuerzburg.de)
11
+ // Department of Computer Science,
12
+ // University of Wuerzburg, Germany
13
+ //
14
+ // Licensed under the Apache License, Version 2.0 (the "License");
15
+ // you may not use this file except in compliance with the License.
16
+ // You may obtain a copy of the License at
17
+ //
18
+ // http://www.apache.org/licenses/LICENSE-2.0
19
+ //
20
+ // Unless required by applicable law or agreed to in writing, software
21
+ // distributed under the License is distributed on an "AS IS" BASIS,
22
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23
+ // See the License for the specific language governing permissions and
24
+ // limitations under the License.
25
+
26
+ #ifndef LIBIEEEP1788_P1788_FLAVOR_INFSUP_SETBASED_MPFR_BIN_IEEE754_FLAVOR_REV_ELEM_FUNC_IMPL_HPP
27
+ #define LIBIEEEP1788_P1788_FLAVOR_INFSUP_SETBASED_MPFR_BIN_IEEE754_FLAVOR_REV_ELEM_FUNC_IMPL_HPP
28
+
29
+ namespace p1788
30
+ {
31
+
32
+ namespace flavor
33
+ {
34
+
35
+ namespace infsup
36
+ {
37
+
38
+ namespace setbased
39
+ {
40
+
41
+ // sqr_rev
42
+
43
+ // bare version
44
+ template<typename T>
45
+ typename mpfr_bin_ieee754_flavor<T>::representation
46
+ mpfr_bin_ieee754_flavor<T>::sqr_rev(mpfr_bin_ieee754_flavor<T>::representation const& c,
47
+ mpfr_bin_ieee754_flavor<T>::representation const& x)
48
+ {
49
+ if (!is_valid(c) || !is_valid(x) || is_empty(c) || is_empty(x) || c.second < 0.0)
50
+ return empty();
51
+
52
+
53
+ mpfr_var::setup();
54
+
55
+ mpfr_var l;
56
+ mpfr_var u;
57
+
58
+ int t_l = 0;
59
+ int t_u = 0;
60
+
61
+
62
+ if (c.first < 0.0)
63
+ {
64
+ l.set(0.0, MPFR_RNDD);
65
+
66
+ u.set(c.second, MPFR_RNDU);
67
+ t_u = u.subnormalize(mpfr_sqrt(u(), u(), MPFR_RNDU), MPFR_RNDU);
68
+ }
69
+ else
70
+ {
71
+ l.set(c.first, MPFR_RNDD);
72
+ u.set(c.second, MPFR_RNDU);
73
+
74
+ t_l = l.subnormalize(mpfr_sqrt(l(), l(), MPFR_RNDD), MPFR_RNDD);
75
+ t_u = u.subnormalize(mpfr_sqrt(u(), u(), MPFR_RNDU), MPFR_RNDU);
76
+ }
77
+
78
+ representation p = representation(l.template get<T>(MPFR_RNDD), u.template get<T>(MPFR_RNDU));
79
+ representation n = neg(p);
80
+
81
+ if ((p.second == x.first && t_u != 0)
82
+ || (x.second == p.first && t_l != 0))
83
+ p = empty();
84
+
85
+
86
+ if ((n.second == x.first && t_l != 0)
87
+ || (x.second == n.first && t_u != 0))
88
+ n = empty();
89
+
90
+ return convex_hull(intersection(p, x), intersection(n, x));
91
+ }
92
+
93
+ // bare mixed type version
94
+ template<typename T>
95
+ template<typename T1, typename T2>
96
+ typename mpfr_bin_ieee754_flavor<T>::representation
97
+ mpfr_bin_ieee754_flavor<T>::sqr_rev(mpfr_bin_ieee754_flavor<T>::representation_type<T1> const& c,
98
+ mpfr_bin_ieee754_flavor<T>::representation_type<T2> const& x)
99
+ {
100
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
101
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
102
+
103
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(c)
104
+ || !mpfr_bin_ieee754_flavor<T2>::is_valid(x)
105
+ || mpfr_bin_ieee754_flavor<T1>::is_empty(c)
106
+ || mpfr_bin_ieee754_flavor<T2>::is_empty(x))
107
+ return empty();
108
+
109
+ // determine max. precision
110
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
111
+
112
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
113
+ // Error free for floating point inf-sup intervals due to outward rounding
114
+ return convert_hull(
115
+ mpfr_bin_ieee754_flavor<T_MAX>::sqr_rev(
116
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(c),
117
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
118
+ )
119
+ );
120
+ }
121
+
122
+ // decorated version
123
+ template<typename T>
124
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
125
+ mpfr_bin_ieee754_flavor<T>::sqr_rev(mpfr_bin_ieee754_flavor<T>::representation_dec const& c,
126
+ mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
127
+ {
128
+ if (!is_valid(c) || !is_valid(x) || is_nai(c) || is_nai(x))
129
+ return nai();
130
+
131
+ // call bare version and set decoration to trv
132
+ return representation_dec(sqr_rev(c.first, x.first), p1788::decoration::decoration::trv);
133
+ }
134
+
135
+ // decorated mixedtype version
136
+ template<typename T>
137
+ template<typename T1, typename T2>
138
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
139
+ mpfr_bin_ieee754_flavor<T>::sqr_rev(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T1> const& c,
140
+ mpfr_bin_ieee754_flavor<T>::representation_dec_type<T2> const& x)
141
+ {
142
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
143
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
144
+
145
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(c) || !mpfr_bin_ieee754_flavor<T2>::is_valid(x)
146
+ || mpfr_bin_ieee754_flavor<T1>::is_nai(c) || mpfr_bin_ieee754_flavor<T2>::is_nai(x))
147
+ return nai();
148
+
149
+ // call bare mixedtype version and set decoration to trv
150
+ return representation_dec(sqr_rev(c.first, x.first), p1788::decoration::decoration::trv);
151
+ }
152
+
153
+
154
+ // bare unary version
155
+ template<typename T>
156
+ typename mpfr_bin_ieee754_flavor<T>::representation
157
+ mpfr_bin_ieee754_flavor<T>::sqr_rev(mpfr_bin_ieee754_flavor<T>::representation const& c)
158
+ {
159
+ // call bare binary version with x = entire
160
+ return sqr_rev(c, entire());
161
+ }
162
+
163
+ // bare unary mixedtype version
164
+ template<typename T>
165
+ template<typename T_>
166
+ typename mpfr_bin_ieee754_flavor<T>::representation
167
+ mpfr_bin_ieee754_flavor<T>::sqr_rev(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& c)
168
+ {
169
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
170
+
171
+ // call bare binary version with x = entire
172
+ return sqr_rev(c, entire());
173
+ }
174
+
175
+ template<typename T>
176
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
177
+ mpfr_bin_ieee754_flavor<T>::sqr_rev(mpfr_bin_ieee754_flavor<T>::representation_dec const& c)
178
+ {
179
+ // call decorated binary version with x = entire
180
+ return sqr_rev(c, entire_dec());
181
+ }
182
+
183
+ template<typename T>
184
+ template<typename T_>
185
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
186
+ mpfr_bin_ieee754_flavor<T>::sqr_rev(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& c)
187
+ {
188
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
189
+
190
+ // call decorated binary version with x = entire
191
+ return sqr_rev(c, entire_dec());
192
+ }
193
+
194
+
195
+
196
+ // abs_rev
197
+
198
+ // bare version
199
+ template<typename T>
200
+ typename mpfr_bin_ieee754_flavor<T>::representation
201
+ mpfr_bin_ieee754_flavor<T>::abs_rev(mpfr_bin_ieee754_flavor<T>::representation const& c,
202
+ mpfr_bin_ieee754_flavor<T>::representation const& x)
203
+ {
204
+ if (!is_valid(c) || !is_valid(x) || is_empty(c) || is_empty(x))
205
+ return empty();
206
+
207
+ if (c.second < 0.0)
208
+ return empty();
209
+
210
+ representation p(std::max(0.0, c.first), c.second);
211
+ representation n = neg(p);
212
+
213
+ return convex_hull(intersection(p, x), intersection(n, x));
214
+ }
215
+
216
+ // bare mixed type version
217
+ template<typename T>
218
+ template<typename T1, typename T2>
219
+ typename mpfr_bin_ieee754_flavor<T>::representation
220
+ mpfr_bin_ieee754_flavor<T>::abs_rev(mpfr_bin_ieee754_flavor<T>::representation_type<T1> const& c,
221
+ mpfr_bin_ieee754_flavor<T>::representation_type<T2> const& x)
222
+ {
223
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
224
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
225
+
226
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(c)
227
+ || !mpfr_bin_ieee754_flavor<T2>::is_valid(x)
228
+ || mpfr_bin_ieee754_flavor<T1>::is_empty(c)
229
+ || mpfr_bin_ieee754_flavor<T2>::is_empty(x))
230
+ return empty();
231
+
232
+ // determine max. precision
233
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
234
+
235
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
236
+ // Error free for floating point inf-sup intervals due to outward rounding
237
+ return convert_hull(
238
+ mpfr_bin_ieee754_flavor<T_MAX>::abs_rev(
239
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(c),
240
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
241
+ )
242
+ );
243
+ }
244
+
245
+ // decorated version
246
+ template<typename T>
247
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
248
+ mpfr_bin_ieee754_flavor<T>::abs_rev(mpfr_bin_ieee754_flavor<T>::representation_dec const& c,
249
+ mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
250
+ {
251
+ if (!is_valid(c) || !is_valid(x) || is_nai(c) || is_nai(x))
252
+ return nai();
253
+
254
+ // call bare version and set decoration to trv
255
+ return representation_dec(abs_rev(c.first, x.first), p1788::decoration::decoration::trv);
256
+ }
257
+
258
+ // decorated mixedtype version
259
+ template<typename T>
260
+ template<typename T1, typename T2>
261
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
262
+ mpfr_bin_ieee754_flavor<T>::abs_rev(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T1> const& c,
263
+ mpfr_bin_ieee754_flavor<T>::representation_dec_type<T2> const& x)
264
+ {
265
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
266
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
267
+
268
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(c) || !mpfr_bin_ieee754_flavor<T2>::is_valid(x)
269
+ || mpfr_bin_ieee754_flavor<T1>::is_nai(c) || mpfr_bin_ieee754_flavor<T2>::is_nai(x))
270
+ return nai();
271
+
272
+ // call bare mixedtype version and set decoration to trv
273
+ return representation_dec(abs_rev(c.first, x.first), p1788::decoration::decoration::trv);
274
+ }
275
+
276
+
277
+ // bare unary version
278
+ template<typename T>
279
+ typename mpfr_bin_ieee754_flavor<T>::representation
280
+ mpfr_bin_ieee754_flavor<T>::abs_rev(mpfr_bin_ieee754_flavor<T>::representation const& c)
281
+ {
282
+ // call bare binary version with x = entire
283
+ return abs_rev(c, entire());
284
+ }
285
+
286
+ // bare unary mixedtype version
287
+ template<typename T>
288
+ template<typename T_>
289
+ typename mpfr_bin_ieee754_flavor<T>::representation
290
+ mpfr_bin_ieee754_flavor<T>::abs_rev(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& c)
291
+ {
292
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
293
+
294
+ // call bare binary version with x = entire
295
+ return abs_rev(c, entire());
296
+ }
297
+
298
+ template<typename T>
299
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
300
+ mpfr_bin_ieee754_flavor<T>::abs_rev(mpfr_bin_ieee754_flavor<T>::representation_dec const& c)
301
+ {
302
+ // call decorated binary version with x = entire
303
+ return abs_rev(c, entire_dec());
304
+ }
305
+
306
+ template<typename T>
307
+ template<typename T_>
308
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
309
+ mpfr_bin_ieee754_flavor<T>::abs_rev(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& c)
310
+ {
311
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
312
+
313
+ // call decorated binary version with x = entire
314
+ return abs_rev(c, entire_dec());
315
+ }
316
+
317
+
318
+
319
+ // pown_rev
320
+
321
+ template<typename T>
322
+ int mpfr_bin_ieee754_flavor<T>::pown_rev_inf(mpfr_var const& c,
323
+ mpfr_var& x,
324
+ int p)
325
+ {
326
+ int t1;
327
+ if (p != -p)
328
+ {
329
+ t1 = -mpfr_root(x(), c(), -p, MPFR_RNDU);
330
+ }
331
+ else
332
+ {
333
+ int t2 = -mpfr_sqrt(x(), c(), MPFR_RNDU);
334
+ t1 = -mpfr_root(x(), x(), -(p >> 1), MPFR_RNDU);
335
+ if (t1 == 0) t1 = t2;
336
+ }
337
+ int t = mpfr_ui_div(x(), 1, x(), MPFR_RNDD);
338
+ if (t == 0) t = t1;
339
+ if (p == -1 || t == 0) return t;
340
+ mpfr_var cm;
341
+ for (;;)
342
+ {
343
+ mpfr_nextabove(x());
344
+ x.subnormalize(0, MPFR_RNDU);
345
+ if (!mpfr_regular_p(x())) break;
346
+ t1 = mpfr_pow_si(cm(), x(), p, MPFR_RNDU);
347
+ t = mpfr_cmp(c(), cm());
348
+ if (t == 0) t = t1;
349
+ if (t == 0) return 0;
350
+ if (t > 0) break;
351
+ }
352
+ mpfr_nextbelow(x());
353
+ x.subnormalize(0, MPFR_RNDD);
354
+ return -1;
355
+ }
356
+
357
+ template<typename T>
358
+ int mpfr_bin_ieee754_flavor<T>::pown_rev_sup(mpfr_var const& c,
359
+ mpfr_var& x,
360
+ int p)
361
+ {
362
+ int t1;
363
+ if (p != -p)
364
+ {
365
+ t1 = -mpfr_root(x(), c(), -p, MPFR_RNDD);
366
+ }
367
+ else
368
+ {
369
+ int t2 = -mpfr_sqrt(x(), c(), MPFR_RNDD);
370
+ t1 = -mpfr_root(x(), x(), -(p >> 1), MPFR_RNDD);
371
+ if (t1 == 0) t1 = t2;
372
+ }
373
+ int t = mpfr_ui_div(x(), 1, x(), MPFR_RNDU);
374
+ if (t == 0) t = t1;
375
+ if (p == -1 || t == 0) return t;
376
+ mpfr_var cm;
377
+ for (;;)
378
+ {
379
+ mpfr_nextbelow(x());
380
+ x.subnormalize(0, MPFR_RNDD);
381
+ if (!mpfr_regular_p(x())) break;
382
+ t1 = mpfr_pow_si(cm(), x(), p, MPFR_RNDD);
383
+ t = mpfr_cmp(c(), cm());
384
+ if (t == 0) t = t1;
385
+ if (t == 0) return 0;
386
+ if (t < 0) break;
387
+ }
388
+ mpfr_nextabove(x());
389
+ x.subnormalize(0, MPFR_RNDU);
390
+ return 1;
391
+ }
392
+
393
+ // bare version
394
+ template<typename T>
395
+ typename mpfr_bin_ieee754_flavor<T>::representation
396
+ mpfr_bin_ieee754_flavor<T>::pown_rev(mpfr_bin_ieee754_flavor<T>::representation const& c,
397
+ mpfr_bin_ieee754_flavor<T>::representation const& x,
398
+ int p)
399
+ {
400
+ if (!is_valid(c) || !is_valid(x) || is_empty(c) || is_empty(x))
401
+ return empty();
402
+
403
+ if (p == 0)
404
+ {
405
+ if (is_member(1.0, c))
406
+ return x;
407
+ else
408
+ return empty();
409
+ }
410
+
411
+ if (p == 1)
412
+ return intersection(x, c);
413
+
414
+
415
+ // even
416
+ if (p % 2 == 0)
417
+ {
418
+ if (p < 0) // negative even
419
+ {
420
+ if (c.second <= 0.0)
421
+ return empty();
422
+
423
+ mpfr_var::setup();
424
+
425
+ mpfr_var cl(c.first <= 0.0 ? 0.0 : c.first, MPFR_RNDD);
426
+ mpfr_var cu(c.second, MPFR_RNDU);
427
+
428
+ mpfr_var xu;
429
+ int t_u = pown_rev_sup(cl, xu, p);
430
+
431
+ mpfr_var xl;
432
+ int t_l = pown_rev_inf(cu, xl, p);
433
+
434
+ representation rp = representation(xl.template get<T>(MPFR_RNDD), xu.template get<T>(MPFR_RNDU));
435
+ representation rn = neg(rp);
436
+
437
+ if ((rp.second == x.first && t_u != 0)
438
+ || (x.second == rp.first && t_l != 0))
439
+ rp = empty();
440
+
441
+ if ((rn.second == x.first && t_l != 0)
442
+ || (x.second == rn.first && t_u != 0))
443
+ rn = empty();
444
+
445
+ return convex_hull(intersection(rp, x), intersection(rn, x));
446
+ }
447
+ else // positive even
448
+ {
449
+ if (c.second < 0.0)
450
+ return empty();
451
+
452
+ mpfr_var::setup();
453
+
454
+ if (c.first <= 0.0)
455
+ {
456
+ mpfr_var cu(c.second, MPFR_RNDU);
457
+
458
+ cu.subnormalize(mpfr_root(cu(), cu(), p, MPFR_RNDU), MPFR_RNDU);
459
+
460
+ return intersection(x, representation(-cu.template get<T>(MPFR_RNDU), cu.template get<T>(MPFR_RNDU)));
461
+ }
462
+
463
+ mpfr_var cl(c.first, MPFR_RNDD);
464
+ mpfr_var cu(c.second, MPFR_RNDU);
465
+
466
+ cl.subnormalize(mpfr_root(cl(), cl(), p, MPFR_RNDD), MPFR_RNDD);
467
+ cu.subnormalize(mpfr_root(cu(), cu(), p, MPFR_RNDU), MPFR_RNDU);
468
+
469
+ return convex_hull(intersection(x, representation(-cu.template get<T>(MPFR_RNDU), -cl.template get<T>(MPFR_RNDD))),
470
+ intersection(x, representation(cl.template get<T>(MPFR_RNDD), cu.template get<T>(MPFR_RNDU))));
471
+ }
472
+ }
473
+ else // odd
474
+ {
475
+ if (p < 0) // negative odd
476
+ {
477
+ if (c.first == 0.0 && c.second == 0.0)
478
+ {
479
+ return empty();
480
+ }
481
+ else if (c.first >= 0.0 || c.second <= 0.0)
482
+ {
483
+ mpfr_var::setup();
484
+
485
+ mpfr_var cl(c.first, MPFR_RNDD);
486
+ mpfr_var cu(c.second, MPFR_RNDU);
487
+
488
+ mpfr_var xu;
489
+ int t_u;
490
+ if (c.first != 0.0)
491
+ {
492
+ t_u = pown_rev_sup(cl, xu, p);
493
+ }
494
+ else
495
+ {
496
+ mpfr_set_inf(xu(), 1);
497
+ t_u = 0;
498
+ }
499
+
500
+ mpfr_var xl;
501
+ int t_l;
502
+ if (c.second != 0.0)
503
+ {
504
+ t_l = pown_rev_inf(cu, xl, p);
505
+ }
506
+ else
507
+ {
508
+ mpfr_set_inf(xl(), -1);
509
+ t_l = 0;
510
+ }
511
+
512
+ representation r = representation(xl.template get<T>(MPFR_RNDD), xu.template get<T>(MPFR_RNDU));
513
+
514
+ if ((r.second == x.first && t_u != 0)
515
+ || (x.second == r.first && t_l != 0))
516
+ r = empty();
517
+
518
+ return intersection(x, r);
519
+ }
520
+ else
521
+ {
522
+ mpfr_var::setup();
523
+
524
+ mpfr_var cl(c.first, MPFR_RNDD);
525
+ mpfr_var cu(c.second, MPFR_RNDU);
526
+
527
+ mpfr_var xu;
528
+ int t_u = pown_rev_sup(cl, xu, p);
529
+ representation rn = representation(-std::numeric_limits<T>::infinity(), xu.template get<T>(MPFR_RNDU));
530
+ if (rn.second == x.first && t_u != 0)
531
+ rn = empty();
532
+
533
+ mpfr_var xl;
534
+ int t_l = pown_rev_inf(cu, xl, p);
535
+ representation rp = representation(xl.template get<T>(MPFR_RNDD), std::numeric_limits<T>::infinity());
536
+ if (x.second == rp.first && t_l != 0)
537
+ rp = empty();
538
+
539
+ return convex_hull(intersection(x, rn), intersection(x, rp));
540
+ }
541
+ }
542
+ else // positive odd
543
+ {
544
+ mpfr_var::setup();
545
+
546
+ mpfr_var cl(c.first, MPFR_RNDD);
547
+ mpfr_var cu(c.second, MPFR_RNDU);
548
+
549
+ cl.subnormalize(mpfr_root(cl(), cl(), p, MPFR_RNDD), MPFR_RNDD);
550
+ cu.subnormalize(mpfr_root(cu(), cu(), p, MPFR_RNDU), MPFR_RNDU);
551
+
552
+ return intersection(x, representation(cl.template get<T>(MPFR_RNDD), cu.template get<T>(MPFR_RNDU)));
553
+ }
554
+ }
555
+ }
556
+
557
+ // bare mixed type version
558
+ template<typename T>
559
+ template<typename T1, typename T2>
560
+ typename mpfr_bin_ieee754_flavor<T>::representation
561
+ mpfr_bin_ieee754_flavor<T>::pown_rev(mpfr_bin_ieee754_flavor<T>::representation_type<T1> const& c,
562
+ mpfr_bin_ieee754_flavor<T>::representation_type<T2> const& x,
563
+ int p)
564
+ {
565
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
566
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
567
+
568
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(c)
569
+ || !mpfr_bin_ieee754_flavor<T2>::is_valid(x)
570
+ || mpfr_bin_ieee754_flavor<T1>::is_empty(c)
571
+ || mpfr_bin_ieee754_flavor<T2>::is_empty(x))
572
+ return empty();
573
+
574
+ // determine max. precision
575
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
576
+
577
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
578
+ // Error free for floating point inf-sup intervals due to outward rounding
579
+ return convert_hull(
580
+ mpfr_bin_ieee754_flavor<T_MAX>::pown_rev(
581
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(c),
582
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x),
583
+ p
584
+ )
585
+ );
586
+ }
587
+
588
+ // decorated version
589
+ template<typename T>
590
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
591
+ mpfr_bin_ieee754_flavor<T>::pown_rev(mpfr_bin_ieee754_flavor<T>::representation_dec const& c,
592
+ mpfr_bin_ieee754_flavor<T>::representation_dec const& x,
593
+ int p)
594
+ {
595
+ if (!is_valid(c) || !is_valid(x) || is_nai(c) || is_nai(x))
596
+ return nai();
597
+
598
+ // call bare version and set decoration to trv
599
+ return representation_dec(pown_rev(c.first, x.first, p), p1788::decoration::decoration::trv);
600
+ }
601
+
602
+ // decorated mixedtype version
603
+ template<typename T>
604
+ template<typename T1, typename T2>
605
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
606
+ mpfr_bin_ieee754_flavor<T>::pown_rev(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T1> const& c,
607
+ mpfr_bin_ieee754_flavor<T>::representation_dec_type<T2> const& x,
608
+ int p)
609
+ {
610
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
611
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
612
+
613
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(c) || !mpfr_bin_ieee754_flavor<T2>::is_valid(x)
614
+ || mpfr_bin_ieee754_flavor<T1>::is_nai(c) || mpfr_bin_ieee754_flavor<T2>::is_nai(x))
615
+ return nai();
616
+
617
+ // call bare mixedtype version and set decoration to trv
618
+ return representation_dec(pown_rev(c.first, x.first, p), p1788::decoration::decoration::trv);
619
+ }
620
+
621
+
622
+ // bare unary version
623
+ template<typename T>
624
+ typename mpfr_bin_ieee754_flavor<T>::representation
625
+ mpfr_bin_ieee754_flavor<T>::pown_rev(mpfr_bin_ieee754_flavor<T>::representation const& c, int p)
626
+ {
627
+ // call bare binary version with x = entire
628
+ return pown_rev(c, entire(), p);
629
+ }
630
+
631
+ // bare unary mixedtype version
632
+ template<typename T>
633
+ template<typename T_>
634
+ typename mpfr_bin_ieee754_flavor<T>::representation
635
+ mpfr_bin_ieee754_flavor<T>::pown_rev(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& c, int p)
636
+ {
637
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
638
+
639
+ // call bare binary version with x = entire
640
+ return pown_rev(c, entire(), p);
641
+ }
642
+
643
+ template<typename T>
644
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
645
+ mpfr_bin_ieee754_flavor<T>::pown_rev(mpfr_bin_ieee754_flavor<T>::representation_dec const& c, int p)
646
+ {
647
+ // call decorated binary version with x = entire
648
+ return pown_rev(c, entire_dec(), p);
649
+ }
650
+
651
+ template<typename T>
652
+ template<typename T_>
653
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
654
+ mpfr_bin_ieee754_flavor<T>::pown_rev(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& c, int p)
655
+ {
656
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
657
+
658
+ // call decorated binary version with x = entire
659
+ return pown_rev(c, entire_dec(), p);
660
+ }
661
+
662
+
663
+
664
+
665
+ // sin_rev
666
+
667
+ // bare version
668
+ template<typename T>
669
+ typename mpfr_bin_ieee754_flavor<T>::representation
670
+ mpfr_bin_ieee754_flavor<T>::sin_rev(mpfr_bin_ieee754_flavor<T>::representation const& c,
671
+ mpfr_bin_ieee754_flavor<T>::representation const& x)
672
+ {
673
+ if (!is_valid(c) || !is_valid(x) || is_empty(x))
674
+ return empty();
675
+
676
+ representation cc = intersection(c, representation(-1.0, 1.0));
677
+
678
+ // c is disjoint with [-1,1]
679
+ if (is_empty(cc))
680
+ return cc;
681
+
682
+ // c contains the whole range [-1,1]
683
+ if (equal(cc, representation(-1.0, 1.0)))
684
+ return x;
685
+
686
+ mpfr_var::setup();
687
+
688
+ mpfr_var xl(x.first, MPFR_RNDD);
689
+ mpfr_var xu(x.second, MPFR_RNDU);
690
+
691
+ mpfr_var cl(cc.first, MPFR_RNDD);
692
+ mpfr_var cu(cc.second, MPFR_RNDU);
693
+
694
+ // lower and the upper bound of asin(c), result is contained in [-1/2pi, 1/2pi]
695
+ mpfr_asin(cl(), cl(), MPFR_RNDD);
696
+ mpfr_asin(cu(), cu(), MPFR_RNDU);
697
+
698
+ // lower and upper bound of pi
699
+ mpfr_var pid;
700
+ mpfr_var piu;
701
+ mpfr_const_pi(pid(), MPFR_RNDD);
702
+ mpfr_const_pi(piu(), MPFR_RNDU);
703
+
704
+ mpfr_var rl;
705
+ mpfr_var ru;
706
+ mpfr_var tmp;
707
+ long n;
708
+
709
+
710
+ // move result of asin(c) to the left bound of x (pi-stepwise)
711
+ // to compute the left box of the result
712
+
713
+
714
+ representation lbox = empty(); // left box
715
+
716
+ // if left bound of x is -oo then the left box is [-oo,-max]
717
+ if (x.first == -std::numeric_limits<T>::infinity())
718
+ {
719
+ lbox.first = -std::numeric_limits<T>::infinity();
720
+ lbox.second = -std::numeric_limits<T>::max();
721
+ }
722
+ else
723
+ {
724
+ // Compute max integer n with: n * pi <= lower bound of x
725
+ mpfr_remquo(tmp(), &n, xl(), x.first < 0.0 ? pid() : piu(), MPFR_RNDD);
726
+ if (mpfr_cmp_si(tmp(),0) < 0)
727
+ --n;
728
+
729
+ for (int i = 0; is_empty(lbox) && i <= 1; i++)
730
+ {
731
+ if ((n + i) % 2 == 0) // n is even => move asin(c)
732
+ {
733
+ tmp.set(n + i, MPFR_RNDN);
734
+
735
+ mpfr_fma(rl(), tmp(), x.first < 0.0 ? piu() : pid(), cl(), MPFR_RNDD);
736
+ mpfr_fma(ru(), tmp(), x.first < 0.0 ? pid() : piu(), cu(), MPFR_RNDU);
737
+
738
+ lbox.first = rl.template get<T>(MPFR_RNDD);
739
+ lbox.second = ru.template get<T>(MPFR_RNDU);
740
+ }
741
+ else // n is even => move mirrored asin(c)
742
+ {
743
+ tmp.set(-n - i, MPFR_RNDN);
744
+
745
+ mpfr_fma(rl(), tmp(), x.first < 0.0 ? piu() : pid(), cu(), MPFR_RNDU);
746
+ mpfr_fma(ru(), tmp(), x.first < 0.0 ? pid() : piu(), cl(), MPFR_RNDD);
747
+
748
+ lbox.first = -rl.template get<T>(MPFR_RNDD);
749
+ lbox.second = -ru.template get<T>(MPFR_RNDU);
750
+ }
751
+
752
+ lbox = intersection(lbox, x);
753
+ }
754
+ }
755
+
756
+
757
+
758
+ // move result of asin(c) to the right bound of x (pi-stepwise)
759
+ // to compute the right box of the result
760
+
761
+
762
+ representation rbox = empty(); // right box
763
+
764
+ // if right bound of x is +oo then the right box is [max,+oo]
765
+ if (x.second == std::numeric_limits<T>::infinity())
766
+ {
767
+ rbox.first = std::numeric_limits<T>::max();
768
+ rbox.second = std::numeric_limits<T>::infinity();
769
+ }
770
+ else
771
+ {
772
+ // Compute min integer n with: n * pi >= upper bound of x
773
+ mpfr_remquo(tmp(), &n, xu(), x.second > 0.0 ? pid() : piu(), MPFR_RNDU);
774
+ if (mpfr_cmp_si(tmp(),0) > 0)
775
+ ++n;
776
+
777
+ for (int i = 0; is_empty(rbox) && i <= 1; i++)
778
+ {
779
+ if ((n - i) % 2 == 0) // n is even => move asin(c)
780
+ {
781
+ tmp.set(n - i, MPFR_RNDN);
782
+
783
+ mpfr_fma(rl(), tmp(), x.second > 0.0 ? pid() : piu(), cl(), MPFR_RNDD);
784
+ mpfr_fma(ru(), tmp(), x.second > 0.0 ? piu() : pid(), cu(), MPFR_RNDU);
785
+
786
+ rbox.first = rl.template get<T>(MPFR_RNDD);
787
+ rbox.second = ru.template get<T>(MPFR_RNDU);
788
+ }
789
+ else // n is even => move mirrored asin(c)
790
+ {
791
+ tmp.set(-n + i, MPFR_RNDN);
792
+
793
+ mpfr_fma(rl(), tmp(), x.second > 0.0 ? pid() : piu(), cu(), MPFR_RNDU);
794
+ mpfr_fma(ru(), tmp(), x.second > 0.0 ? piu() : pid(), cl(), MPFR_RNDD);
795
+
796
+ rbox.first = -rl.template get<T>(MPFR_RNDD);
797
+ rbox.second = -ru.template get<T>(MPFR_RNDU);
798
+ }
799
+
800
+ rbox = intersection(rbox, x);
801
+ }
802
+ }
803
+
804
+ return convex_hull(lbox, rbox);
805
+ }
806
+
807
+ // bare mixed type version
808
+ template<typename T>
809
+ template<typename T1, typename T2>
810
+ typename mpfr_bin_ieee754_flavor<T>::representation
811
+ mpfr_bin_ieee754_flavor<T>::sin_rev(mpfr_bin_ieee754_flavor<T>::representation_type<T1> const& c,
812
+ mpfr_bin_ieee754_flavor<T>::representation_type<T2> const& x)
813
+ {
814
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
815
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
816
+
817
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(c)
818
+ || !mpfr_bin_ieee754_flavor<T2>::is_valid(x)
819
+ || mpfr_bin_ieee754_flavor<T1>::is_empty(c)
820
+ || mpfr_bin_ieee754_flavor<T2>::is_empty(x))
821
+ return empty();
822
+
823
+ // determine max. precision
824
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
825
+
826
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
827
+ // Error free for floating point inf-sup intervals due to outward rounding
828
+ return convert_hull(
829
+ mpfr_bin_ieee754_flavor<T_MAX>::sin_rev(
830
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(c),
831
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
832
+ )
833
+ );
834
+ }
835
+
836
+ // decorated version
837
+ template<typename T>
838
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
839
+ mpfr_bin_ieee754_flavor<T>::sin_rev(mpfr_bin_ieee754_flavor<T>::representation_dec const& c,
840
+ mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
841
+ {
842
+ if (!is_valid(c) || !is_valid(x) || is_nai(c) || is_nai(x))
843
+ return nai();
844
+
845
+ // call bare version and set decoration to trv
846
+ return representation_dec(sin_rev(c.first, x.first), p1788::decoration::decoration::trv);
847
+ }
848
+
849
+ // decorated mixedtype version
850
+ template<typename T>
851
+ template<typename T1, typename T2>
852
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
853
+ mpfr_bin_ieee754_flavor<T>::sin_rev(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T1> const& c,
854
+ mpfr_bin_ieee754_flavor<T>::representation_dec_type<T2> const& x)
855
+ {
856
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
857
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
858
+
859
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(c) || !mpfr_bin_ieee754_flavor<T2>::is_valid(x)
860
+ || mpfr_bin_ieee754_flavor<T1>::is_nai(c) || mpfr_bin_ieee754_flavor<T2>::is_nai(x))
861
+ return nai();
862
+
863
+ // call bare mixedtype version and set decoration to trv
864
+ return representation_dec(sin_rev(c.first, x.first), p1788::decoration::decoration::trv);
865
+ }
866
+
867
+
868
+ // bare unary version
869
+ template<typename T>
870
+ typename mpfr_bin_ieee754_flavor<T>::representation
871
+ mpfr_bin_ieee754_flavor<T>::sin_rev(mpfr_bin_ieee754_flavor<T>::representation const& c)
872
+ {
873
+ // call bare binary version with x = entire
874
+ return sin_rev(c, entire());
875
+ }
876
+
877
+ // bare unary mixedtype version
878
+ template<typename T>
879
+ template<typename T_>
880
+ typename mpfr_bin_ieee754_flavor<T>::representation
881
+ mpfr_bin_ieee754_flavor<T>::sin_rev(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& c)
882
+ {
883
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
884
+
885
+ // call bare binary version with x = entire
886
+ return sin_rev(c, entire());
887
+ }
888
+
889
+ template<typename T>
890
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
891
+ mpfr_bin_ieee754_flavor<T>::sin_rev(mpfr_bin_ieee754_flavor<T>::representation_dec const& c)
892
+ {
893
+ // call decorated binary version with x = entire
894
+ return sin_rev(c, entire_dec());
895
+ }
896
+
897
+ template<typename T>
898
+ template<typename T_>
899
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
900
+ mpfr_bin_ieee754_flavor<T>::sin_rev(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& c)
901
+ {
902
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
903
+
904
+ // call decorated binary version with x = entire
905
+ return sin_rev(c, entire_dec());
906
+ }
907
+
908
+
909
+
910
+
911
+
912
+ // cos_rev
913
+
914
+ // bare version
915
+ template<typename T>
916
+ typename mpfr_bin_ieee754_flavor<T>::representation
917
+ mpfr_bin_ieee754_flavor<T>::cos_rev(mpfr_bin_ieee754_flavor<T>::representation const& c,
918
+ mpfr_bin_ieee754_flavor<T>::representation const& x)
919
+ {
920
+ if (!is_valid(c) || !is_valid(x) || is_empty(x))
921
+ return empty();
922
+
923
+ representation cc = intersection(c, representation(-1.0, 1.0));
924
+
925
+ // c is disjoint with [-1,1]
926
+ if (is_empty(cc))
927
+ return cc;
928
+
929
+ // c contains the whole range [-1,1]
930
+ if (equal(cc, representation(-1.0, 1.0)))
931
+ return x;
932
+
933
+ mpfr_var::setup();
934
+
935
+ mpfr_var xl(x.first, MPFR_RNDD);
936
+ mpfr_var xu(x.second, MPFR_RNDU);
937
+
938
+ mpfr_var cl(cc.second, MPFR_RNDU);
939
+ mpfr_var cu(cc.first, MPFR_RNDD);
940
+
941
+ // lower and the upper bound of acos(c), result is contained in [0, pi]
942
+ mpfr_acos(cl(), cl(), MPFR_RNDD);
943
+ mpfr_acos(cu(), cu(), MPFR_RNDU);
944
+
945
+ // lower and upper bound of pi
946
+ mpfr_var pid;
947
+ mpfr_var piu;
948
+ mpfr_const_pi(pid(), MPFR_RNDD);
949
+ mpfr_const_pi(piu(), MPFR_RNDU);
950
+
951
+ mpfr_var rl;
952
+ mpfr_var ru;
953
+ mpfr_var tmp;
954
+ long n;
955
+
956
+
957
+ // move result of acos(c) to the left bound of x (pi-stepwise)
958
+ // to compute the left box of the result
959
+
960
+
961
+ representation lbox = empty(); // left box
962
+
963
+ // if left bound of x is -oo then the left box is [-oo,-max]
964
+ if (x.first == -std::numeric_limits<T>::infinity())
965
+ {
966
+ lbox.first = -std::numeric_limits<T>::infinity();
967
+ lbox.second = -std::numeric_limits<T>::max();
968
+ }
969
+ else
970
+ {
971
+ // Compute max integer n with: n * pi <= lower bound of x
972
+ mpfr_remquo(tmp(), &n, xl(), x.first < 0.0 ? pid() : piu(), MPFR_RNDD);
973
+ if (mpfr_cmp_si(tmp(),0) < 0)
974
+ --n;
975
+
976
+ for (int i = 0; is_empty(lbox) && i <= 1; i++)
977
+ {
978
+ if ((n + i) % 2 == 0) // n is even => move acos(c)
979
+ {
980
+ tmp.set(n + i, MPFR_RNDN);
981
+
982
+ mpfr_fma(rl(), tmp(), x.first < 0.0 ? piu() : pid(), cl(), MPFR_RNDD);
983
+ mpfr_fma(ru(), tmp(), x.first < 0.0 ? pid() : piu(), cu(), MPFR_RNDU);
984
+
985
+ lbox.first = rl.template get<T>(MPFR_RNDD);
986
+ lbox.second = ru.template get<T>(MPFR_RNDU);
987
+ }
988
+ else // n is even => move mirrored acos(c)
989
+ {
990
+ tmp.set(-n - i - 1, MPFR_RNDN);
991
+
992
+ mpfr_fma(rl(), tmp(), x.first < 0.0 ? piu() : pid(), cu(), MPFR_RNDU);
993
+ mpfr_fma(ru(), tmp(), x.first < 0.0 ? pid() : piu(), cl(), MPFR_RNDD);
994
+
995
+ lbox.first = -rl.template get<T>(MPFR_RNDD);
996
+ lbox.second = -ru.template get<T>(MPFR_RNDU);
997
+ }
998
+
999
+ lbox = intersection(lbox, x);
1000
+ }
1001
+ }
1002
+
1003
+
1004
+
1005
+ // move result of acos(c) to the right bound of x (pi-stepwise)
1006
+ // to compute the right box of the result
1007
+
1008
+
1009
+ representation rbox = empty(); // right box
1010
+
1011
+ // if right bound of x is +oo then the right box is [max,+oo]
1012
+ if (x.second == std::numeric_limits<T>::infinity())
1013
+ {
1014
+ rbox.first = std::numeric_limits<T>::max();
1015
+ rbox.second = std::numeric_limits<T>::infinity();
1016
+ }
1017
+ else
1018
+ {
1019
+ // Compute max integer n with: n * pi <= upper bound of x
1020
+ mpfr_remquo(tmp(), &n, xu(), x.second > 0.0 ? pid() : piu(), MPFR_RNDU);
1021
+ if (mpfr_cmp_si(tmp(),0) < 0)
1022
+ --n;
1023
+
1024
+ for (int i = 0; is_empty(rbox) && i <= 1; i++)
1025
+ {
1026
+ if ((n - i) % 2 == 0) // n is even => move acos(c)
1027
+ {
1028
+ tmp.set(n - i, MPFR_RNDN);
1029
+
1030
+ mpfr_fma(rl(), tmp(), x.second > 0.0 ? pid() : piu(), cl(), MPFR_RNDD);
1031
+ mpfr_fma(ru(), tmp(), x.second > 0.0 ? piu() : pid(), cu(), MPFR_RNDU);
1032
+
1033
+ rbox.first = rl.template get<T>(MPFR_RNDD);
1034
+ rbox.second = ru.template get<T>(MPFR_RNDU);
1035
+ }
1036
+ else // n is even => move mirrored acos(c)
1037
+ {
1038
+ tmp.set(-n + i - 1, MPFR_RNDN);
1039
+
1040
+ mpfr_fma(rl(), tmp(), x.second > 0.0 ? pid() : piu(), cu(), MPFR_RNDU);
1041
+ mpfr_fma(ru(), tmp(), x.second > 0.0 ? piu() : pid(), cl(), MPFR_RNDD);
1042
+
1043
+ rbox.first = -rl.template get<T>(MPFR_RNDD);
1044
+ rbox.second = -ru.template get<T>(MPFR_RNDU);
1045
+ }
1046
+
1047
+ rbox = intersection(rbox, x);
1048
+ }
1049
+ }
1050
+
1051
+ return convex_hull(lbox, rbox);
1052
+ }
1053
+
1054
+ // bare mixed type version
1055
+ template<typename T>
1056
+ template<typename T1, typename T2>
1057
+ typename mpfr_bin_ieee754_flavor<T>::representation
1058
+ mpfr_bin_ieee754_flavor<T>::cos_rev(mpfr_bin_ieee754_flavor<T>::representation_type<T1> const& c,
1059
+ mpfr_bin_ieee754_flavor<T>::representation_type<T2> const& x)
1060
+ {
1061
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1062
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1063
+
1064
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(c)
1065
+ || !mpfr_bin_ieee754_flavor<T2>::is_valid(x)
1066
+ || mpfr_bin_ieee754_flavor<T1>::is_empty(c)
1067
+ || mpfr_bin_ieee754_flavor<T2>::is_empty(x))
1068
+ return empty();
1069
+
1070
+ // determine max. precision
1071
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
1072
+
1073
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
1074
+ // Error free for floating point inf-sup intervals due to outward rounding
1075
+ return convert_hull(
1076
+ mpfr_bin_ieee754_flavor<T_MAX>::cos_rev(
1077
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(c),
1078
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
1079
+ )
1080
+ );
1081
+ }
1082
+
1083
+ // decorated version
1084
+ template<typename T>
1085
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1086
+ mpfr_bin_ieee754_flavor<T>::cos_rev(mpfr_bin_ieee754_flavor<T>::representation_dec const& c,
1087
+ mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
1088
+ {
1089
+ if (!is_valid(c) || !is_valid(x) || is_nai(c) || is_nai(x))
1090
+ return nai();
1091
+
1092
+ // call bare version and set decoration to trv
1093
+ return representation_dec(cos_rev(c.first, x.first), p1788::decoration::decoration::trv);
1094
+ }
1095
+
1096
+ // decorated mixedtype version
1097
+ template<typename T>
1098
+ template<typename T1, typename T2>
1099
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1100
+ mpfr_bin_ieee754_flavor<T>::cos_rev(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T1> const& c,
1101
+ mpfr_bin_ieee754_flavor<T>::representation_dec_type<T2> const& x)
1102
+ {
1103
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1104
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1105
+
1106
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(c) || !mpfr_bin_ieee754_flavor<T2>::is_valid(x)
1107
+ || mpfr_bin_ieee754_flavor<T1>::is_nai(c) || mpfr_bin_ieee754_flavor<T2>::is_nai(x))
1108
+ return nai();
1109
+
1110
+ // call bare mixedtype version and set decoration to trv
1111
+ return representation_dec(cos_rev(c.first, x.first), p1788::decoration::decoration::trv);
1112
+ }
1113
+
1114
+
1115
+ // bare unary version
1116
+ template<typename T>
1117
+ typename mpfr_bin_ieee754_flavor<T>::representation
1118
+ mpfr_bin_ieee754_flavor<T>::cos_rev(mpfr_bin_ieee754_flavor<T>::representation const& c)
1119
+ {
1120
+ // call bare binary version with x = entire
1121
+ return cos_rev(c, entire());
1122
+ }
1123
+
1124
+ // bare unary mixedtype version
1125
+ template<typename T>
1126
+ template<typename T_>
1127
+ typename mpfr_bin_ieee754_flavor<T>::representation
1128
+ mpfr_bin_ieee754_flavor<T>::cos_rev(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& c)
1129
+ {
1130
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1131
+
1132
+ // call bare binary version with x = entire
1133
+ return cos_rev(c, entire());
1134
+ }
1135
+
1136
+ template<typename T>
1137
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1138
+ mpfr_bin_ieee754_flavor<T>::cos_rev(mpfr_bin_ieee754_flavor<T>::representation_dec const& c)
1139
+ {
1140
+ // call decorated binary version with x = entire
1141
+ return cos_rev(c, entire_dec());
1142
+ }
1143
+
1144
+ template<typename T>
1145
+ template<typename T_>
1146
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1147
+ mpfr_bin_ieee754_flavor<T>::cos_rev(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& c)
1148
+ {
1149
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1150
+
1151
+ // call decorated binary version with x = entire
1152
+ return cos_rev(c, entire_dec());
1153
+ }
1154
+
1155
+
1156
+ // tan_rev
1157
+
1158
+ // bare version
1159
+ template<typename T>
1160
+ typename mpfr_bin_ieee754_flavor<T>::representation
1161
+ mpfr_bin_ieee754_flavor<T>::tan_rev(mpfr_bin_ieee754_flavor<T>::representation const& c,
1162
+ mpfr_bin_ieee754_flavor<T>::representation const& x)
1163
+ {
1164
+ if (!is_valid(c) || !is_valid(x) || is_empty(c) || is_empty(x))
1165
+ return empty();
1166
+
1167
+
1168
+ mpfr_var::setup();
1169
+
1170
+ mpfr_var xl(x.first, MPFR_RNDD);
1171
+ mpfr_var xu(x.second, MPFR_RNDU);
1172
+
1173
+ mpfr_var cl(c.first, MPFR_RNDD);
1174
+ mpfr_var cu(c.second, MPFR_RNDU);
1175
+
1176
+ // lower and the upper bound of atan(c), result is contained in [-1/2pi, 1/2pi]
1177
+ mpfr_atan(cl(), cl(), MPFR_RNDD);
1178
+ mpfr_atan(cu(), cu(), MPFR_RNDU);
1179
+
1180
+ // lower and upper bound of pi
1181
+ mpfr_var pid;
1182
+ mpfr_var piu;
1183
+ mpfr_const_pi(pid(), MPFR_RNDD);
1184
+ mpfr_const_pi(piu(), MPFR_RNDU);
1185
+
1186
+ mpfr_var rl;
1187
+ mpfr_var ru;
1188
+ mpfr_var tmp;
1189
+ long n;
1190
+
1191
+
1192
+ // move result of atan(c) to the left bound of x (pi-stepwise)
1193
+ // to compute the left box of the result
1194
+
1195
+
1196
+ representation lbox = empty(); // left box
1197
+
1198
+ // if left bound of x is -oo then the left box is [-oo,-max]
1199
+ if (x.first == -std::numeric_limits<T>::infinity())
1200
+ {
1201
+ lbox.first = -std::numeric_limits<T>::infinity();
1202
+ lbox.second = -std::numeric_limits<T>::max();
1203
+ }
1204
+ else
1205
+ {
1206
+ // Compute max integer n with: n * pi <= lower bound of x
1207
+ mpfr_remquo(tmp(), &n, xl(), x.first < 0.0 ? pid() : piu(), MPFR_RNDD);
1208
+ if (mpfr_cmp_si(tmp(),0) < 0)
1209
+ --n;
1210
+
1211
+ // move atan(c)
1212
+ for (int i = 0; is_empty(lbox) && i <= 1; i++)
1213
+ {
1214
+ tmp.set(n + i, MPFR_RNDN);
1215
+
1216
+ mpfr_fma(rl(), tmp(), x.first < 0.0 ? piu() : pid(), cl(), MPFR_RNDD);
1217
+ mpfr_fma(ru(), tmp(), x.first < 0.0 ? pid() : piu(), cu(), MPFR_RNDU);
1218
+
1219
+ lbox.first = rl.template get<T>(MPFR_RNDD);
1220
+ lbox.second = ru.template get<T>(MPFR_RNDU);
1221
+
1222
+ lbox = intersection(lbox, x);
1223
+ }
1224
+ }
1225
+
1226
+
1227
+
1228
+ // move result of atan(c) to the right bound of x (pi-stepwise)
1229
+ // to compute the right box of the result
1230
+
1231
+
1232
+ representation rbox = empty(); // right box
1233
+
1234
+ // if right bound of x is +oo then the right box is [max,+oo]
1235
+ if (x.second == std::numeric_limits<T>::infinity())
1236
+ {
1237
+ rbox.first = std::numeric_limits<T>::max();
1238
+ rbox.second = std::numeric_limits<T>::infinity();
1239
+ }
1240
+ else
1241
+ {
1242
+ // Compute min integer n with: n * pi >= upper bound of x
1243
+ mpfr_remquo(tmp(), &n, xu(), x.second > 0.0 ? pid() : piu(), MPFR_RNDU);
1244
+ if (mpfr_cmp_si(tmp(),0) > 0)
1245
+ ++n;
1246
+
1247
+ // move atan(c)
1248
+ for (int i = 0; is_empty(rbox) && i <= 1; i++)
1249
+ {
1250
+ tmp.set(n - i, MPFR_RNDN);
1251
+
1252
+ mpfr_fma(rl(), tmp(), x.second > 0.0 ? pid() : piu(), cl(), MPFR_RNDD);
1253
+ mpfr_fma(ru(), tmp(), x.second > 0.0 ? piu() : pid(), cu(), MPFR_RNDU);
1254
+
1255
+ rbox.first = rl.template get<T>(MPFR_RNDD);
1256
+ rbox.second = ru.template get<T>(MPFR_RNDU);
1257
+
1258
+ rbox = intersection(rbox, x);
1259
+ }
1260
+ }
1261
+
1262
+ return convex_hull(lbox, rbox);
1263
+ }
1264
+
1265
+ // bare mixed type version
1266
+ template<typename T>
1267
+ template<typename T1, typename T2>
1268
+ typename mpfr_bin_ieee754_flavor<T>::representation
1269
+ mpfr_bin_ieee754_flavor<T>::tan_rev(mpfr_bin_ieee754_flavor<T>::representation_type<T1> const& c,
1270
+ mpfr_bin_ieee754_flavor<T>::representation_type<T2> const& x)
1271
+ {
1272
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1273
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1274
+
1275
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(c)
1276
+ || !mpfr_bin_ieee754_flavor<T2>::is_valid(x)
1277
+ || mpfr_bin_ieee754_flavor<T1>::is_empty(c)
1278
+ || mpfr_bin_ieee754_flavor<T2>::is_empty(x))
1279
+ return empty();
1280
+
1281
+ // determine max. precision
1282
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
1283
+
1284
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
1285
+ // Error free for floating point inf-sup intervals due to outward rounding
1286
+ return convert_hull(
1287
+ mpfr_bin_ieee754_flavor<T_MAX>::tan_rev(
1288
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(c),
1289
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
1290
+ )
1291
+ );
1292
+ }
1293
+
1294
+ // decorated version
1295
+ template<typename T>
1296
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1297
+ mpfr_bin_ieee754_flavor<T>::tan_rev(mpfr_bin_ieee754_flavor<T>::representation_dec const& c,
1298
+ mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
1299
+ {
1300
+ if (!is_valid(c) || !is_valid(x) || is_nai(c) || is_nai(x))
1301
+ return nai();
1302
+
1303
+ // call bare version and set decoration to trv
1304
+ return representation_dec(tan_rev(c.first, x.first), p1788::decoration::decoration::trv);
1305
+ }
1306
+
1307
+ // decorated mixedtype version
1308
+ template<typename T>
1309
+ template<typename T1, typename T2>
1310
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1311
+ mpfr_bin_ieee754_flavor<T>::tan_rev(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T1> const& c,
1312
+ mpfr_bin_ieee754_flavor<T>::representation_dec_type<T2> const& x)
1313
+ {
1314
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1315
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1316
+
1317
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(c) || !mpfr_bin_ieee754_flavor<T2>::is_valid(x)
1318
+ || mpfr_bin_ieee754_flavor<T1>::is_nai(c) || mpfr_bin_ieee754_flavor<T2>::is_nai(x))
1319
+ return nai();
1320
+
1321
+ // call bare mixedtype version and set decoration to trv
1322
+ return representation_dec(tan_rev(c.first, x.first), p1788::decoration::decoration::trv);
1323
+ }
1324
+
1325
+
1326
+ // bare unary version
1327
+ template<typename T>
1328
+ typename mpfr_bin_ieee754_flavor<T>::representation
1329
+ mpfr_bin_ieee754_flavor<T>::tan_rev(mpfr_bin_ieee754_flavor<T>::representation const& c)
1330
+ {
1331
+ // call bare binary version with x = entire
1332
+ return tan_rev(c, entire());
1333
+ }
1334
+
1335
+ // bare unary mixedtype version
1336
+ template<typename T>
1337
+ template<typename T_>
1338
+ typename mpfr_bin_ieee754_flavor<T>::representation
1339
+ mpfr_bin_ieee754_flavor<T>::tan_rev(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& c)
1340
+ {
1341
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1342
+
1343
+ // call bare binary version with x = entire
1344
+ return tan_rev(c, entire());
1345
+ }
1346
+
1347
+ template<typename T>
1348
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1349
+ mpfr_bin_ieee754_flavor<T>::tan_rev(mpfr_bin_ieee754_flavor<T>::representation_dec const& c)
1350
+ {
1351
+ // call decorated binary version with x = entire
1352
+ return tan_rev(c, entire_dec());
1353
+ }
1354
+
1355
+ template<typename T>
1356
+ template<typename T_>
1357
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1358
+ mpfr_bin_ieee754_flavor<T>::tan_rev(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& c)
1359
+ {
1360
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1361
+
1362
+ // call decorated binary version with x = entire
1363
+ return tan_rev(c, entire_dec());
1364
+ }
1365
+
1366
+
1367
+ // cosh_rev
1368
+
1369
+ // bare version
1370
+ template<typename T>
1371
+ typename mpfr_bin_ieee754_flavor<T>::representation
1372
+ mpfr_bin_ieee754_flavor<T>::cosh_rev(mpfr_bin_ieee754_flavor<T>::representation const& c,
1373
+ mpfr_bin_ieee754_flavor<T>::representation const& x)
1374
+ {
1375
+ if (!is_valid(c) || !is_valid(x) || is_empty(c) || is_empty(x) || c.second < 1.0)
1376
+ return empty();
1377
+
1378
+
1379
+ mpfr_var::setup();
1380
+
1381
+ mpfr_var l;
1382
+ mpfr_var u;
1383
+
1384
+ int t_l = 0;
1385
+ int t_u = 0;
1386
+
1387
+
1388
+ if (c.first < 1.0)
1389
+ {
1390
+ l.set(0.0, MPFR_RNDD);
1391
+
1392
+ u.set(c.second, MPFR_RNDU);
1393
+ t_u = u.subnormalize(mpfr_acosh(u(), u(), MPFR_RNDU), MPFR_RNDU);
1394
+ }
1395
+ else
1396
+ {
1397
+ l.set(c.first, MPFR_RNDD);
1398
+ u.set(c.second, MPFR_RNDU);
1399
+
1400
+ t_l = l.subnormalize(mpfr_acosh(l(), l(), MPFR_RNDD), MPFR_RNDD);
1401
+ t_u = u.subnormalize(mpfr_acosh(u(), u(), MPFR_RNDU), MPFR_RNDU);
1402
+ }
1403
+
1404
+ representation p = representation(l.template get<T>(MPFR_RNDD), u.template get<T>(MPFR_RNDU));
1405
+ representation n = neg(p);
1406
+
1407
+ if ((p.second == x.first && t_u != 0)
1408
+ || (x.second == p.first && t_l != 0))
1409
+ p = empty();
1410
+
1411
+
1412
+ if ((n.second == x.first && t_l != 0)
1413
+ || (x.second == n.first && t_u != 0))
1414
+ n = empty();
1415
+
1416
+ return convex_hull(intersection(p, x), intersection(n, x));
1417
+ }
1418
+
1419
+ // bare mixed type version
1420
+ template<typename T>
1421
+ template<typename T1, typename T2>
1422
+ typename mpfr_bin_ieee754_flavor<T>::representation
1423
+ mpfr_bin_ieee754_flavor<T>::cosh_rev(mpfr_bin_ieee754_flavor<T>::representation_type<T1> const& c,
1424
+ mpfr_bin_ieee754_flavor<T>::representation_type<T2> const& x)
1425
+ {
1426
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1427
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1428
+
1429
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(c)
1430
+ || !mpfr_bin_ieee754_flavor<T2>::is_valid(x)
1431
+ || mpfr_bin_ieee754_flavor<T1>::is_empty(c)
1432
+ || mpfr_bin_ieee754_flavor<T2>::is_empty(x))
1433
+ return empty();
1434
+
1435
+ // determine max. precision
1436
+ typedef typename p1788::util::max_precision_type<T,T1,T2>::type T_MAX;
1437
+
1438
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
1439
+ // Error free for floating point inf-sup intervals due to outward rounding
1440
+ return convert_hull(
1441
+ mpfr_bin_ieee754_flavor<T_MAX>::cosh_rev(
1442
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(c),
1443
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
1444
+ )
1445
+ );
1446
+ }
1447
+
1448
+ // decorated version
1449
+ template<typename T>
1450
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1451
+ mpfr_bin_ieee754_flavor<T>::cosh_rev(mpfr_bin_ieee754_flavor<T>::representation_dec const& c,
1452
+ mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
1453
+ {
1454
+ if (!is_valid(c) || !is_valid(x) || is_nai(c) || is_nai(x))
1455
+ return nai();
1456
+
1457
+ // call bare version and set decoration to trv
1458
+ return representation_dec(cosh_rev(c.first, x.first), p1788::decoration::decoration::trv);
1459
+ }
1460
+
1461
+ // decorated mixedtype version
1462
+ template<typename T>
1463
+ template<typename T1, typename T2>
1464
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1465
+ mpfr_bin_ieee754_flavor<T>::cosh_rev(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T1> const& c,
1466
+ mpfr_bin_ieee754_flavor<T>::representation_dec_type<T2> const& x)
1467
+ {
1468
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1469
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1470
+
1471
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(c) || !mpfr_bin_ieee754_flavor<T2>::is_valid(x)
1472
+ || mpfr_bin_ieee754_flavor<T1>::is_nai(c) || mpfr_bin_ieee754_flavor<T2>::is_nai(x))
1473
+ return nai();
1474
+
1475
+ // call bare mixedtype version and set decoration to trv
1476
+ return representation_dec(cosh_rev(c.first, x.first), p1788::decoration::decoration::trv);
1477
+ }
1478
+
1479
+
1480
+ // bare unary version
1481
+ template<typename T>
1482
+ typename mpfr_bin_ieee754_flavor<T>::representation
1483
+ mpfr_bin_ieee754_flavor<T>::cosh_rev(mpfr_bin_ieee754_flavor<T>::representation const& c)
1484
+ {
1485
+ // call bare binary version with x = entire
1486
+ return cosh_rev(c, entire());
1487
+ }
1488
+
1489
+ // bare unary mixedtype version
1490
+ template<typename T>
1491
+ template<typename T_>
1492
+ typename mpfr_bin_ieee754_flavor<T>::representation
1493
+ mpfr_bin_ieee754_flavor<T>::cosh_rev(mpfr_bin_ieee754_flavor<T>::representation_type<T_> const& c)
1494
+ {
1495
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1496
+
1497
+ // call bare binary version with x = entire
1498
+ return cosh_rev(c, entire());
1499
+ }
1500
+
1501
+ template<typename T>
1502
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1503
+ mpfr_bin_ieee754_flavor<T>::cosh_rev(mpfr_bin_ieee754_flavor<T>::representation_dec const& c)
1504
+ {
1505
+ // call decorated binary version with x = entire
1506
+ return cosh_rev(c, entire_dec());
1507
+ }
1508
+
1509
+ template<typename T>
1510
+ template<typename T_>
1511
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1512
+ mpfr_bin_ieee754_flavor<T>::cosh_rev(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T_> const& c)
1513
+ {
1514
+ static_assert(std::numeric_limits<T_>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1515
+
1516
+ // call decorated binary version with x = entire
1517
+ return cosh_rev(c, entire_dec());
1518
+ }
1519
+
1520
+
1521
+
1522
+
1523
+ // mul_rev
1524
+
1525
+ // bare version
1526
+ template<typename T>
1527
+ typename mpfr_bin_ieee754_flavor<T>::representation
1528
+ mpfr_bin_ieee754_flavor<T>::mul_rev(mpfr_bin_ieee754_flavor<T>::representation const& b,
1529
+ mpfr_bin_ieee754_flavor<T>::representation const& c,
1530
+ mpfr_bin_ieee754_flavor<T>::representation const& x)
1531
+ {
1532
+ if (!is_valid(b) || !is_valid(c) || !is_valid(x))
1533
+ return empty();
1534
+
1535
+ int t_fl, t_fu, t_sl, t_su;
1536
+ auto tmp = mul_rev_to_pair(t_fl, t_fu, t_sl, t_su, b, c);
1537
+
1538
+ if ((tmp.first.second == x.first && t_fu != 0)
1539
+ || (x.second == tmp.first.first && t_fl != 0))
1540
+ tmp.first = empty();
1541
+
1542
+ if ((tmp.second.second == x.first && t_su != 0)
1543
+ || (x.second == tmp.second.first && t_sl != 0))
1544
+ tmp.second = empty();
1545
+
1546
+
1547
+ return convex_hull(intersection(tmp.first, x), intersection(tmp.second, x));
1548
+ }
1549
+
1550
+ // bare mixed type version
1551
+ template<typename T>
1552
+ template<typename T1, typename T2, typename T3>
1553
+ typename mpfr_bin_ieee754_flavor<T>::representation
1554
+ mpfr_bin_ieee754_flavor<T>::mul_rev(mpfr_bin_ieee754_flavor<T>::representation_type<T1> const& b,
1555
+ mpfr_bin_ieee754_flavor<T>::representation_type<T2> const& c,
1556
+ mpfr_bin_ieee754_flavor<T>::representation_type<T3> const& x)
1557
+ {
1558
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1559
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1560
+ static_assert(std::numeric_limits<T3>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1561
+
1562
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(b)
1563
+ || !mpfr_bin_ieee754_flavor<T2>::is_valid(c)
1564
+ || !mpfr_bin_ieee754_flavor<T3>::is_valid(x))
1565
+ return empty();
1566
+
1567
+ // determine max. precision
1568
+ typedef typename p1788::util::max_precision_type<T,T1,T2,T3>::type T_MAX;
1569
+
1570
+ // 1.) convert inputs to max precision; 2.) compute result in max precision; 3.) convert result to desired precision
1571
+ // Error free for floating point inf-sup intervals due to outward rounding
1572
+ return convert_hull(
1573
+ mpfr_bin_ieee754_flavor<T_MAX>::mul_rev(
1574
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(b),
1575
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(c),
1576
+ mpfr_bin_ieee754_flavor<T_MAX>::convert_hull(x)
1577
+ )
1578
+ );
1579
+ }
1580
+
1581
+ // decorated version
1582
+ template<typename T>
1583
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1584
+ mpfr_bin_ieee754_flavor<T>::mul_rev(mpfr_bin_ieee754_flavor<T>::representation_dec const& b,
1585
+ mpfr_bin_ieee754_flavor<T>::representation_dec const& c,
1586
+ mpfr_bin_ieee754_flavor<T>::representation_dec const& x)
1587
+ {
1588
+ if (!is_valid(b) || !is_valid(c) || !is_valid(x) || is_nai(b) || is_nai(c) || is_nai(x))
1589
+ return nai();
1590
+
1591
+ // call bare version and set decoration to trv
1592
+ return representation_dec(mul_rev(b.first, c.first, x.first), p1788::decoration::decoration::trv);
1593
+ }
1594
+
1595
+ // decorated mixedtype version
1596
+ template<typename T>
1597
+ template<typename T1, typename T2, typename T3>
1598
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1599
+ mpfr_bin_ieee754_flavor<T>::mul_rev(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T1> const& b,
1600
+ mpfr_bin_ieee754_flavor<T>::representation_dec_type<T2> const& c,
1601
+ mpfr_bin_ieee754_flavor<T>::representation_dec_type<T3> const& x)
1602
+ {
1603
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1604
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1605
+ static_assert(std::numeric_limits<T3>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1606
+
1607
+ if (!mpfr_bin_ieee754_flavor<T1>::is_valid(b) || !mpfr_bin_ieee754_flavor<T2>::is_valid(c) || !mpfr_bin_ieee754_flavor<T3>::is_valid(x)
1608
+ || mpfr_bin_ieee754_flavor<T1>::is_nai(b) || mpfr_bin_ieee754_flavor<T2>::is_nai(c) || mpfr_bin_ieee754_flavor<T3>::is_nai(x))
1609
+ return nai();
1610
+
1611
+ // call bare mixedtype version and set decoration to trv
1612
+ return representation_dec(mul_rev(b.first, c.first, x.first), p1788::decoration::decoration::trv);
1613
+ }
1614
+
1615
+
1616
+ // bare unary version
1617
+ template<typename T>
1618
+ typename mpfr_bin_ieee754_flavor<T>::representation
1619
+ mpfr_bin_ieee754_flavor<T>::mul_rev(mpfr_bin_ieee754_flavor<T>::representation const& b,
1620
+ mpfr_bin_ieee754_flavor<T>::representation const& c)
1621
+ {
1622
+ // call bare ternary version with x = entire
1623
+ return mul_rev(b, c, entire());
1624
+ }
1625
+
1626
+ // bare unary mixedtype version
1627
+ template<typename T>
1628
+ template<typename T1, typename T2>
1629
+ typename mpfr_bin_ieee754_flavor<T>::representation
1630
+ mpfr_bin_ieee754_flavor<T>::mul_rev(mpfr_bin_ieee754_flavor<T>::representation_type<T1> const& b,
1631
+ mpfr_bin_ieee754_flavor<T>::representation_type<T2> const& c)
1632
+ {
1633
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1634
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1635
+
1636
+ // call bare ternary version with x = entire
1637
+ return mul_rev(b, c, entire());
1638
+ }
1639
+
1640
+ template<typename T>
1641
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1642
+ mpfr_bin_ieee754_flavor<T>::mul_rev(mpfr_bin_ieee754_flavor<T>::representation_dec const& b,
1643
+ mpfr_bin_ieee754_flavor<T>::representation_dec const& c)
1644
+ {
1645
+ // call decorated ternary version with x = entire
1646
+ return mul_rev(b, c, entire_dec());
1647
+ }
1648
+
1649
+ template<typename T>
1650
+ template<typename T1, typename T2>
1651
+ typename mpfr_bin_ieee754_flavor<T>::representation_dec
1652
+ mpfr_bin_ieee754_flavor<T>::mul_rev(mpfr_bin_ieee754_flavor<T>::representation_dec_type<T1> const& b,
1653
+ mpfr_bin_ieee754_flavor<T>::representation_dec_type<T2> const& c)
1654
+ {
1655
+ static_assert(std::numeric_limits<T1>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1656
+ static_assert(std::numeric_limits<T2>::is_iec559, "Only IEEE 754 binary compliant types are supported!");
1657
+
1658
+ // call decorated ternary version with x = entire
1659
+ return mul_rev(b, c, entire_dec());
1660
+ }
1661
+
1662
+
1663
+
1664
+
1665
+ } // namespace setbased
1666
+
1667
+ } // namespace infsup
1668
+
1669
+ } // namespace flavor
1670
+
1671
+ } // namespace p1788
1672
+
1673
+
1674
+ #endif // LIBIEEEP1788_P1788_FLAVOR_INFSUP_SETBASED_MPFR_BIN_IEEE754_FLAVOR_REV_ELEM_FUNC_IMPL_HPP