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.
- checksums.yaml +7 -0
- data/.yardopts +8 -0
- data/AUTHORS +6 -0
- data/LICENSE +201 -0
- data/NOTICE +29 -0
- data/README.md +65 -0
- data/ext/libieeep1788_copy/README +3 -0
- data/ext/libieeep1788_copy/p1788/AUTHORS +16 -0
- data/ext/libieeep1788_copy/p1788/LICENSE +202 -0
- data/ext/libieeep1788_copy/p1788/NOTICE +14 -0
- data/ext/libieeep1788_copy/p1788/decoration/decoration.hpp +265 -0
- data/ext/libieeep1788_copy/p1788/exception/exception.hpp +302 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor.hpp +3443 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_bool_func_impl.hpp +608 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_cancel_func_impl.hpp +229 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_class_impl.hpp +526 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_elem_func_impl.hpp +4533 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_io_impl.hpp +1421 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_mul_rev_to_pair_func_impl.hpp +347 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_num_func_impl.hpp +655 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_rec_bool_func_impl.hpp +146 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_rec_overlap_impl.hpp +188 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_rev_func_impl.hpp +1674 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_set_op_impl.hpp +216 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_setup_func_impl.hpp +68 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_util_func_impl.hpp +135 -0
- data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_validation_func_impl.hpp +93 -0
- data/ext/libieeep1788_copy/p1788/infsup/base_interval.hpp +1529 -0
- data/ext/libieeep1788_copy/p1788/infsup/base_interval_bool_func_impl.hpp +481 -0
- data/ext/libieeep1788_copy/p1788/infsup/base_interval_cancel_func_impl.hpp +126 -0
- data/ext/libieeep1788_copy/p1788/infsup/base_interval_elem_func_impl.hpp +1581 -0
- data/ext/libieeep1788_copy/p1788/infsup/base_interval_io_impl.hpp +59 -0
- data/ext/libieeep1788_copy/p1788/infsup/base_interval_mul_rev_to_pair_func_impl.hpp +88 -0
- data/ext/libieeep1788_copy/p1788/infsup/base_interval_num_func_impl.hpp +345 -0
- data/ext/libieeep1788_copy/p1788/infsup/base_interval_rec_bool_func_impl.hpp +92 -0
- data/ext/libieeep1788_copy/p1788/infsup/base_interval_rec_overlap_impl.hpp +72 -0
- data/ext/libieeep1788_copy/p1788/infsup/base_interval_rev_func_impl.hpp +656 -0
- data/ext/libieeep1788_copy/p1788/infsup/base_interval_set_op_impl.hpp +126 -0
- data/ext/libieeep1788_copy/p1788/infsup/decorated_interval.hpp +464 -0
- data/ext/libieeep1788_copy/p1788/infsup/forward_declaration.hpp +66 -0
- data/ext/libieeep1788_copy/p1788/infsup/interval.hpp +275 -0
- data/ext/libieeep1788_copy/p1788/io/io_manip.hpp +531 -0
- data/ext/libieeep1788_copy/p1788/overlapping/overlapping.hpp +241 -0
- data/ext/libieeep1788_copy/p1788/p1788.hpp +45 -0
- data/ext/libieeep1788_copy/p1788/reduction/reduction.hpp +341 -0
- data/ext/libieeep1788_copy/p1788/util/io.hpp +63 -0
- data/ext/libieeep1788_copy/p1788/util/mixed_type_traits.hpp +140 -0
- data/ext/libieeep1788_copy/p1788/util/mpfr_util.hpp +77 -0
- data/ext/libieeep1788_copy/p1788/util/mpfr_var.hpp +119 -0
- data/ext/libieeep1788_copy/p1788/util/mpfr_var_impl.hpp +382 -0
- data/ext/libieeep1788_copy/p1788/version.hpp +34 -0
- data/ext/p1788/extconf.rb +49 -0
- data/ext/p1788/p1788.cc +3764 -0
- data/lib/p1788/version.rb +4 -0
- data/lib/p1788.rb +25 -0
- data/p1788.gemspec +72 -0
- metadata +99 -0
data/ext/libieeep1788_copy/p1788/flavor/infsup/setbased/mpfr_bin_ieee754_flavor_rev_func_impl.hpp
ADDED
@@ -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
|