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.