35 #ifndef _FINRESDYN_OPENSINE_H_ 36 #define _FINRESDYN_OPENSINE_H_ 50 template <
class NumType,
int nTerms>
55 static int compute (
const NumType &xLeft,
const NumType &xRight,
56 NumType &yLeft, NumType &yRight);
62 NumType *lower_x2k, NumType *upper_x2k,
int n);
74 static int shifted1pi (
const NumType &xLeft,
const NumType &xRight,
75 NumType &yLeft, NumType &yRight);
79 static int shifted2pi (
const NumType &xLeft,
const NumType &xRight,
80 NumType &yLeft, NumType &yRight);
86 template <
class NumType,
int nTerms>
88 (
const NumType &x, NumType *lower_x2k, NumType *upper_x2k,
int n)
95 NumType lowerDiff = (x <= pi::lowerBound () / 2) ?
96 rnd::sub_down (pi::lowerBound () / 2, x) :
97 rnd::sub_down (x, pi::upperBound () / 2);
100 NumType lower_x2 = rnd::mul_down (lowerDiff, lowerDiff);
101 NumType upperDiff = (x <= pi::upperBound () / 2) ?
102 rnd::sub_up (pi::upperBound () / 2, x) :
103 rnd::sub_up (x, pi::lowerBound () / 2);
104 NumType upper_x2 = rnd::mul_up (upperDiff, upperDiff);
109 for (
int k = 0; k < n; ++ k)
118 lower_x2k [1] = lower_x2 / 2;
119 upper_x2k [1] = upper_x2 / 2;
123 long int factor = ((k << 1) - 1) * (k << 1);
124 lower_x2k [k] = rnd::mul_down (lower_x2k [k - 1],
126 lower_x2k [k] = rnd::div_down (lower_x2k [k],
128 upper_x2k [k] = rnd::mul_up (upper_x2k [k - 1],
130 upper_x2k [k] = rnd::div_up (upper_x2k [k],
138 template <
class NumType,
int nTerms>
145 int n = (nTerms & 1) ? (nTerms + 1) : (nTerms);
148 NumType lower_x2k [nTerms + 1];
149 NumType upper_x2k [nTerms + 1];
154 for (
int k = n - 1; k >= 0; -- k)
158 result = rnd::sub_down (result, upper_x2k [k]);
162 result = rnd::add_down (result, lower_x2k [k]);
168 template <
class NumType,
int nTerms>
175 int n = (nTerms & 1) ? (nTerms) : (nTerms + 1);
178 NumType lower_x2k [nTerms + 1];
179 NumType upper_x2k [nTerms + 1];
184 for (
int k = n - 1; k >= 0; -- k)
188 result = rnd::sub_up (result, lower_x2k [k]);
192 result = rnd::add_up (result, upper_x2k [k]);
200 template <
class NumType,
int nTerms>
202 (
const NumType &xLeft,
const NumType &xRight,
203 NumType &yLeft, NumType &yRight)
210 NumType lower2pi = pi::lowerBound () * 2;
211 NumType upper2pi = pi::upperBound () * 2;
216 int periods =
static_cast<int> ((-xLeft) / upper2pi) + 1;
217 NumType shiftMin = rnd::mul_down (periods, lower2pi);
218 NumType shiftMax = rnd::mul_up (periods, upper2pi);
219 NumType newLeft = rnd::add_down (xLeft, shiftMin);
220 NumType newRight = rnd::add_up (xRight, shiftMax);
224 newLeft = rnd::add_down (newLeft, lower2pi);
225 newRight = rnd::add_up (newRight, upper2pi);
227 while (newLeft > lower2pi)
230 newLeft = rnd::sub_down (newLeft, lower2pi);
231 newRight = rnd::sub_up (newRight, upper2pi);
233 return shifted2pi (newLeft, newRight, yLeft, yRight);
235 else if (xLeft > upper2pi)
237 int periods =
static_cast<int> (xLeft / upper2pi);
238 NumType shiftMin = rnd::mul_down (periods, lower2pi);
239 NumType shiftMax = rnd::mul_up (periods, upper2pi);
240 NumType newLeft = rnd::sub_down (xLeft, shiftMax);
241 NumType newRight = rnd::sub_up (xRight, shiftMin);
242 while (newLeft > upper2pi)
245 newLeft = rnd::sub_down (newLeft, upper2pi);
246 newRight = rnd::sub_up (newRight, lower2pi);
248 return shifted2pi (newLeft, newRight, yLeft, yRight);
252 return shifted2pi (xLeft, xRight, yLeft, yRight);
256 template <
class NumType,
int nTerms>
258 (
const NumType &xLeft,
const NumType &xRight,
259 NumType &yLeft, NumType &yRight)
266 const NumType lowerPi = pi::lowerBound ();
267 const NumType upperPi = pi::upperBound ();
270 const NumType lower2pi = lowerPi * 2;
271 const NumType upper2pi = upperPi * 2;
282 const NumType lowerPi2 = lowerPi / 2;
283 const NumType upperPi2 = upperPi / 2;
286 if (xRight <= upperPi2)
294 NumType upper3pi2 = rnd::add_up (upperPi, upperPi2);
298 if (xLeft <= upperPi2)
301 if (xRight <= upperPi)
303 if (rnd::sub_up (upperPi2, xLeft) <=
304 rnd::sub_down (xRight, upperPi2))
308 else if (rnd::sub_down (lowerPi2, xLeft) >=
309 rnd::sub_up (xRight, lowerPi2))
317 yLeft = (leftVal < rightVal) ?
320 yRight = rnd::add_up (1, rnd::min_number ());
325 if (xRight <= upper3pi2)
328 (rnd::sub_up (xRight, lowerPi));
329 yRight = rnd::add_up (1, rnd::min_number ());
334 yLeft = rnd::sub_down (-1, rnd::min_number ());
335 yRight = rnd::add_up (1, rnd::min_number ());
343 if (xRight <= upperPi)
351 if (xRight <= upper3pi2)
354 (rnd::sub_up (xRight, lowerPi));
360 if (xRight <= upper2pi)
362 yLeft = rnd::sub_down (-1, rnd::min_number ());
368 if (xRight <= rnd::add_up (upper2pi, upperPi2))
370 if (rnd::sub_up (upperPi, xLeft) <=
371 rnd::sub_down (xRight, upper2pi))
374 (rnd::sub_up (xRight, lower2pi));
376 else if (rnd::sub_down (lowerPi, xLeft) >=
377 rnd::sub_up (xRight, lower2pi))
385 (rnd::sub_up (xRight, lower2pi));
386 yRight = (leftVal < rightVal) ?
389 yLeft = rnd::sub_down (-1, rnd::min_number ());
394 yLeft = rnd::sub_down (-1, rnd::min_number ());
395 yRight = rnd::add_up (1, rnd::min_number ());
400 template <
class NumType,
int nTerms>
402 (
const NumType &xLeft,
const NumType &xRight,
403 NumType &yLeft, NumType &yRight)
410 if (xLeft <= pi::upperBound ())
411 return shifted1pi (xLeft, xRight, yLeft, yRight);
415 shifted1pi (rnd::sub_down (xLeft, pi::upperBound ()),
416 rnd::sub_up (xRight, pi::upperBound ()),
426 #endif // _FINRESDYN_OPENSINE_H_ Rigorous bounds for the number pi.
Rigorous rounding of arithmetic operations.
static NumType lowerBoundTaylor(const NumType &x)
Returns a lower bound for the sine function.
static void computeTaylorTerms(const NumType &x, NumType *lower_x2k, NumType *upper_x2k, int n)
Computes the provided number of terms in the expansion of sin(pi+x) in the Taylor series at pi...
static int shifted1pi(const NumType &xLeft, const NumType &xRight, NumType &yLeft, NumType &yRight)
Computes the sine function in the open interval arithmetic with the arguments shifted so that xLeft i...
static int shifted2pi(const NumType &xLeft, const NumType &xRight, NumType &yLeft, NumType &yRight)
Computes the sine function in the open interval arithmetic with the arguments shifted so that xLeft i...
A class for rounding operations which uses the BOOST library.
static NumType upperBoundTaylor(const NumType &x)
Returns an upper bound for the sine function.
Computes the sine function using the expansion into the Taylor series at pi/2.
A class that holds the number pi.
static int compute(const NumType &xLeft, const NumType &xRight, NumType &yLeft, NumType &yRight)
Computes the sine function in the open interval arithmetic.