C H A P T E R  2

C++ Interval Arithmetic Library Reference

This chapter is a reference for the syntax and semantics of the interval arithmetic library implemented in Sun Studio C++. The sections can be read in any order.


2.1 Character Set Notation

Throughout this document, unless explicitly stated otherwise, integer and floating-point constants mean literal constants. Literal constants are represented using strings, because class types do not support literal constants. Section 2.1.1, String Representation of an Interval Constant (SRIC).

TABLE 2-1 shows the character set notation used for code and mathematics.


TABLE 2-1 Font Conventions

Character Set

Notation

C++ code

interval<double> DX;

Input to programs and commands

Enter X: ? [2.3,2.4]

Placeholders for constants in code

[a, b]

Scalar mathematics

x(a + b) = xa + xb

Interval mathematics


X(A+ B) subsetXA+ XB




Note - Pay close attention to font usage. Different fonts represent an interval's exact, external mathematical value and an interval's machine-representable, internal approximation.



2.1.1 String Representation of an Interval Constant (SRIC)

In C++, it is possible to define variables of a class type, but not literal constants. So that a literal interval constant can be represented, the C++ interval class uses a string to represent an interval constant. A string representation of an interval constant (SRIC) is a character string containing one of the following:

Quotation marks delimit the string. If a degenerate interval is not machine representable, directed rounding is used to round the exact mathematical value to an internal machine representable interval known to satisfy the containment constraint.

A SRIC, such as "[0.1]" or "[0.1,0.2]", is associated with the two values: its external value and its internal approximation. The numerical value of a SRIC is its internal approximation. The external value of a SRIC is always explicitly labelled as such, by using the notation ev(SRIC). For example, the SRIC "[1, 2]" and its external value ev("[1, 2]") are both equal to the mathematical value [1, 2]. However, while ev("[0.1, 0.2]") = [0.1, 0.2], interval<double>("[0.1, 0.2]") is only an internal machine approximation containing [0.1, 0.2], because the numbers 0.1 and 0.2 are not machine representable.

Like any mathematical constant, the external value of a SRIC is invariant.

Because intervals are opaque, there is no language requirement to use any particular interval storage format to save the information needed to internally approximate an interval. Functions are provided to access the infimum and supremum of an interval. In a SRIC containing two interval endpoints, the first number is the infimum or lower bound, and the second is the supremum or upper bound.

If a SRIC contains only one integer or real number in square brackets, the represented interval is degenerate, with equal infimum and supremum. In this case, an internal interval approximation is constructed that is guaranteed to contain the SRIC's single decimal external value. If a SRIC contains only one integer or real number without square brackets, single number conversion is used. See Section 2.8.1, Input.

A valid interval must have an infimum that is less than or equal to its supremum. Similarly, a SRIC must also have an infimum that is less than or equal to its supremum. For example, the following code fragment must evaluate to true:

inf(interval<double>("[0.1]") <= sup(interval<double>("[0.1]"))

CODE EXAMPLE 2-1 contains examples of valid and invalid SRICs.

For additional information regarding SRICs, see the supplementary paper [4] cited in Section 2.12, References.


CODE EXAMPLE 2-1 Valid and Invalid interval External Representations

math% cat ce2-1.cc
#include <suninterval.h>
 
#if __cplusplus >= 199711
using namespace SUNW_interval;
#endif
 
int main() {
    interval <double> X1("[1,2]");
    interval <double> X2("[1]");
    interval <double> X3("1");
    interval <double> X4("[0.1]");
    interval <double> X5("0.1");
    interval <double> X6("0.10");
    interval <double> X7("0.100");
    interval <double> X8("[2,1]");
    cout << "X1=" << X1 << endl;
    cout << "X2=" << X2 << endl;
    cout << "X3=" << X3 << endl;
    cout << "X4=" << X4 << endl;
    cout << "X5=" << X5 << endl;
    cout << "X6=" << X6 << endl;
    cout << "X7=" << X7 << endl;
    cout << "X8=" << X8 << endl;
}
math% CC -xia -o ce2-1 ce2-1.cc
math% ce2-1
X1=[0.1000000000000000E+001,0.2000000000000000E+001]
X2=[0.1000000000000000E+001,0.1000000000000000E+001]
X3=[0.0000000000000000E+000,0.2000000000000000E+001]
X4=[0.9999999999999999E-001,0.1000000000000001E+000]
X5=[0.0000000000000000E+000,0.2000000000000001E+000]
X6=[0.8999999999999999E-001,0.1100000000000001E+000]
X7=[0.9899999999999999E-001,0.1010000000000001E+000]
X8=[              -Infinity,               Infinity]
 

Constructing an interval approximation from a SRIC is an inefficient operation that should be avoided, if possible. In CODE EXAMPLE 2-2, the interval<double> constant Y is constructed only once at the start of the program, and then its internal representation is used thereafter.


CODE EXAMPLE 2-2 Efficient Use of the String-to-Interval Constructor

math% cat ce2-2.cc
#include <suninterval.h>
 
#if __cplusplus >= 199711
using namespace SUNW_interval;
#endif
 
const interval<double> Y("[0.1]");
const int limit = 100000;
 
int main()
{
   interval<double>  RESULT(0.0);
   clock_t t1= clock();
   if(t1==clock_t(-1)){cerr<< "sorry, no clock\n"; exit(1);}
   
   for (int i = 0; i < limit; i++){
            RESULT += Y;
   }
   clock_t t2= clock();
   if(t2==clock_t(-1)){cerr<< "sorry, clock overflow\n"; exit(2);}
   cout << "efficient loop took " << 
           double(t2-t1)/CLOCKS_PER_SEC << " seconds" << endl;
   cout << "result" << RESULT << endl ;
   t1= clock();
   if(t1==clock_t(-1)){cerr<< "sorry, clock overflow\n"; exit(2);}
   for (int i = 0; i < limit; i++){
            RESULT += interval<double>("[0.1]");
   }
   t2= clock();
   if(t2==clock_t(-1)){cerr<< "sorry, clock overflow\n"; exit(2);}
   cout << "inefficient loop took " << 
           double(t2-t1)/CLOCKS_PER_SEC << " seconds" << endl;
    cout << "result" << RESULT << endl ;
} 
 
math% CC -xia ce2-2.cc -o ce2-2
math% ce2-2
efficient loop took 0.16 seconds
result[0.9999999999947978E+004,0.1000000000003054E+005]
inefficient loop took 5.59 seconds
result[0.1999999999980245E+005,0.2000000000013270E+005]
 

2.1.2 Internal Approximation

The internal approximation of a floating-point constant does not necessarily equal the constant's external value. For example, because the decimal number 0.1 is not a member of the set of binary floating-point numbers, this value can only be approximated by a binary floating-point number that is close to 0.1. For floating-point data items, the approximation accuracy is unspecified in the C++ standard. For interval data items, a pair of floating-point values is used that is known to contain the set of mathematical values defined by the decimal numbers used to symbolically represent an interval constant. For example, the mathematical interval [0.1, 0.2] is represented by a string "[0.1,0.2]".

Just as there is no C++ language requirement to accurately approximate floating-point constants, there is also no language requirement to approximate an interval's external value with a narrow width interval internal representation. There is a requirement for an interval internal representation to contain its external value.

ev(inf(interval<double>("[0.1,0.2]"))) less than or equal

inf(ev("[0.1,0.2]")) = inf([0.1, 0.2])

and

sup([0.1, 0.2]) = sup(ev("[0.1,0.2]")) less than or equal ev(sup(interval<double>("[0.1,0.2]")))



Note - The arguments of ev( ) are always code expressions that produce mathematical values. The use of different fonts for code expressions and mathematical values is designed to make this distinction clear.



C++ interval internal representations are sharp. This is a quality of implementation feature.


2.2 interval Constructor

The following interval constructors are supported:


explicit interval( const char* ) ;
explicit interval( const interval<float>& ) ;
explicit interval( const interval<double>& ) ; 
explicit interval( const interval<long double>& ) ;
explicit interval( int ) ;
explicit interval( long long ) ;
explicit interval( float ) ;
explicit interval( double ) ;
explicit interval( long double ) ;
interval( int, int ) ;
interval( long long, long long ) ;
interval( float, float ) ;
interval( double, double ) ;
interval( long double, long double ) ;

The following interval constructors guarantee containment:


interval( const char*) ;
interval( const interval<float>& ) ;
interval( const interval<double>& ) 
interval( const interval<long double>& ) ;

The argument interval is rounded outward, if necessary.

The interval constructor with non-interval arguments returns [-inf,inf] if either the second argument is less then the first, or if either argument is not a mathematical real number, such as when one or both arguments is a NaN.

Interval constructors with floating-point or integer arguments might not return an interval that contains the external value of constant arguments.

For example, use interval<double>("[1.1,1.3]") to sharply contain the mathematical interval [1.1, 1.3]. However, interval<double>(1.1,1.3) might not contain [1.1, 1.3], because the internal values of floating-point literal constants are approximated with unknown accuracy.


CODE EXAMPLE 2-3 interval Constructor With Floating-Point Arguments

math% cat ce2-3.cc
#include <limits.h>
#include <strings.h>
#include <sunmath.h>
#include <stack>
#include <suninterval.h>
 
#if __cplusplus >= 199711
using namespace SUNW_interval;
#endif
 
int main()
{
   //Compute 0.7-0.1-0.2-0.3-0.1 == 0.0
   
   interval<double>  correct_result;
   const interval<double> x1("[0.1]"),
   x2("[0.2]"),x3("[0.3]"),x7("[0.7]");
   
    cout << "Exact result:" <<  0.0 << endl ;
 
    cout << "Incorrect evaluation:" <<  
    interval<double>(0.7-0.1-0.2-0.3-0.1, 0.7-0.1-0.2-0.3-0.1) << 
   endl ;
      
    correct_result = x7-x1-x2-x3-x1;
  
    cout << "Correct evaluation:" <<  correct_result << endl ;
} 
math% CC -xia -o ce2-3 ce2-3.cc
math% ce2-3
Exact result:0
Incorrect evaluation: [-.2775557561562892E-016,-.2775557561562891E-016]
Correct evaluation: [-.1942890293094024E-015,0.1526556658859591E-015]
 

The result value of an interval constructor is always a valid interval.

The interval_hull function can be used with an interval constructor to construct an interval containing two floating-point numbers, as shown in CODE EXAMPLE 2-4.


CODE EXAMPLE 2-4 Using the interval_hull Function With Interval Constructor

math% cat ce2-4.cc
#include <suninterval.h>
 
#if __cplusplus >= 199711
using namespace SUNW_interval;
#endif
 
int main() {
    interval <float> X;
    long double a,b;
    cout << "Press Control/C to terminate!"<< endl;
    cout <<" a,b =?";
    cin >>a >>b;
    for(;;){
        cout <<endl << "For a =" << a << ", and b =" <<b<< endl;
             X = interval <float>(
                     interval_hull(interval<long double>(a),
                                   interval<long double>(b)));
        if(in(a,X) && in(b,X)){
                cout << "Check" << endl ;
                cout << "X=" << X << endl ;
           }
        cout <<" a,b =?";
        cin >>a >>b;
    }
}
math% CC -xia ce2-4.cc -o ce2-4
math% ce2-4
Press Control/C to terminate!
 a,b =?1.0e+400 -0.1
For a =1e+400, and b =-0.1
Check
X=[-.10000001E+000,       Infinity]
 a,b =? ^c
 

2.2.1 interval Constructor Examples

The three examples in this section illustrate how to use the interval constructor to perform conversions from floating-point to interval-type data items. CODE EXAMPLE 2-5 shows that floating-point expression arguments of the interval constructor are evaluated using floating-point arithmetic.


CODE EXAMPLE 2-5 interval Conversion

math% cat ce2-5.cc
 
#include <suninterval.h>
 
#if __cplusplus >= 199711
using namespace SUNW_interval;
#endif
 
int main() {
    interval <float> X, Y;
    interval <double> DX, DY;
    float R = 0.1f, S = 0.2f, T = 0.3f;
    double R8 = 0.1, T1, T2;
 
    Y = interval <float>(R,R);
    X = interval <float>(0.1f);          //note 1
    if (X == Y)
        cout <<"Check1"<< endl;
    X = interval <float>(0.1f, 0.1f);
    if (X == Y)
        cout <<"Check2"<< endl;
    T1 = R + S;
    T2 = T + R8;
    DY = interval <double>(T1, T2);
    DX = interval <double>(double(R+S), double(T+R8));   //note 2
    if (DX == DY)
        cout <<"Check3"<< endl;
    DX = interval <double>(Y);          //note 3
    if (ceq(DX,interval <double>(0.1f, 0.1f)))
        cout <<"Check4"<< endl;
}
math% CC  -xia -o ce2-5 ce2-5.cc
math% ce2-5
Check1
Check2
Check3
Check4
 

CODE EXAMPLE 2-5 notes:

CODE EXAMPLE 2-6 shows how the interval constructor can be used to create the smallest possible interval, Y, such that the endpoints of Y are not elements of a given interval, X.


CODE EXAMPLE 2-6 Creating a Narrow Interval That Contains a Given Real Number

math% cat ce2-6.cc
#include <suninterval.h>
#include <values.h>
#if __cplusplus >= 199711
using namespace SUNW_interval;
#endif
 
int main() {
   interval <double> X("[10.E-10,11.E-10]");
   interval <double> Y;
   Y = interval<double>(-MINDOUBLE, MINDOUBLE) + X;
   cout << "X is " <<
   ((!in_interior(X,Y))? "not": "")<< "in interior of Y" <<endl;
}
math% CC ce2-6.cc -o ce2-6 -xia
math% ce2-6
X is  in interior of Y
 

Given an interval X, a sharp interval Y satisfying the condition in_interior(X,Y) is constructed. For information on the interior set relation, Section 2.6.3, Interior: in_interior(X,Y).

CODE EXAMPLE 2-7 illustrates when the interval constructor returns the interval
[-inf, inf] and [max_float, inf].


CODE EXAMPLE 2-7 interval(NaN)

math% cat ce2-7.cc
#include <suninterval.h>
 
#if __cplusplus >= 199711
using namespace SUNW_interval;
#endif
 
int main() {
   interval <double> DX;
   float R=0.0, S=0.0, T;
   T = R/S;                              //note  1
   cout<< T <<endl;
   cout<< interval<double>(T,S)<<endl;   //note  2
   cout<< interval<double>(T,T)<<endl;
   cout<< interval<double>(2.,1.)<<endl; //note  3 
   cout<< interval<double>(1./R)<<endl;  //note  4
}
math% CC  -xia -o ce2-7 ce2-7.cc
math% ce2-7
NaN
[              -Infinity,               Infinity]
[              -Infinity,               Infinity]
[              -Infinity,               Infinity]
[0.1797693134862315E+309,               Infinity]
 

CODE EXAMPLE 2-7 notes:


2.3 interval Arithmetic Expressions

interval arithmetic expressions are constructed from the same arithmetic operators as other numerical data types. The fundamental difference between interval and non-interval (point) expressions is that the result of any possible interval expression is a valid interval that satisfies the containment constraint of interval arithmetic. In contrast, point expression results can be any approximate value.


2.4 Operators and Functions

TABLE 2-2 lists the operators and functions that can be used with intervals. In TABLE 2-2, X and Y are intervals.


TABLE 2-2 Operators and Functions

Operator

Operation

Expression

Meaning

*

Multiplication

X*Y

Multiply X and Y

/

Division

X/Y

Divide X by Y

+

Addition

X+Y

Add X and Y

+

Identity

+X

Same as X (without a sign)

-

Subtraction

X-Y

Subtract Y from X

-

Numeric Negation

-X

Negate X

Function

Meaning

interval_hull(X,Y)

Interval hull of X and Y

intersect(X,Y)

Intersect X and Y

pow(X,Y)

Power function


Some interval-specific functions have no point analogs. These can be grouped into three categories: set, certainly, and possibly, as shown in TABLE 2-3. A number of unique set-operators have no certainly or possibly analogs.


TABLE 2-3 interval Relational Functions and Operators

Operators

==

!=

 

Set Relational Functions

superset(X,Y)

proper_superset(X,Y)

 

subset(X,Y)

proper_subset(X,Y)

 

in_interior(X,Y)

disjoint(X,Y)

 

in(r,Y)

 

seq(X,Y)

sne(X,Y)

slt(X,Y)

sle(X,Y)

sgt(X,Y)

sge(X,Y)

Certainly Relational Functions

ceq(X,Y)

cne(X,Y)

clt(X,Y)

cle(X,Y)

cgt(X,Y)

cge(X,Y)

Possibly Relational Functions

peq(X,Y)

pne(X,Y)

plt(X,Y)

ple(X,Y)

pgt(X,Y)

pge(X,Y)


Except for the in function, interval relational functions can only be applied to two interval operands with the same type.

The first argument of the in function is of any integer or floating-point type. The second argument can have any interval type.

All the interval relational functions and operators return an interval_bool-type result.

2.4.1 Arithmetic Operators +, -, *, /

Formulas for computing the endpoints of interval arithmetic operations on finite floating-point intervals are motivated by the requirement to produce the narrowest interval that is guaranteed to contain the set of all possible point results. Ramon Moore independently developed these formulas and more importantly, was the first to develop the analysis needed to apply interval arithmetic. For more information, see Interval Analysis by R. Moore (Prentice-Hall, 1966).


The set of all possible values was originally defined by performing the operation in question on any element of the operand intervals. Therefore, given finite intervals, [a, b] and [c, d], with op is an element of {+, -, x, /},

[a,b] op [c,d] is a superset of x op y where x is an element of [a,b] and y is an element of [c,d],

with division by zero being excluded. Implementation formulas, or their logical equivalent, are:


[a,b]+[c,d]=[a+c,b+d]

[a,b]-[c,d]=[a-d,b-c]

[a,b] x [c,d]=[min(a x c, a x d, b x c, b x d), max(a x c, a x d, b x c, b x d)]

 


[a,b]/[c,d]=[min(a/c,a/d,b/c,b/d), max(a/c,a/d,b/c,b/d)], if 0 is not an element of [c,d]

 

Directed rounding is used when computing with finite precision arithmetic to guarantee the set of all possible values is contained in the resulting interval.

The set of values that any interval result must contain is called the containment set (cset) of the operation or expression that produces the result.


To include extended intervals (with infinite endpoints) and division by zero, csets can only indirectly depend on the value of arithmetic operations on real operands. For extended intervals, csets are required for operations on points that are normally undefined. Undefined operations include the indeterminate forms: 1/inf. 0 x inf, 0/0, inf/inf

The containment-set closure identity solves the problem of identifying the value of containment sets of expressions at singular or indeterminate points. The identity states that containment sets are function closures. The closure of a function at a point on the boundary of its domain includes all limit or accumulation points. For details, see the Glossary and the supplementary papers [1], [3], [10], and [11] cited in Section 2.12, References.

The following is an intuitive way to justify the values included in an expression's cset. Consider the function


h(x)=1/x

The question is: what is the cset of h(x0), for x0 = 0 ? To answer this question, consider the function


f(x)=(x/(x+1))

Clearly, f(x0) = 0, for x0 = 0. But, what about


g(x)= (1/(1+(1/x)))

 

or


g(x)=(1/(1+h(x)))?

The function g(x0) is undefined for x0 = 0, because h(x0) is undefined. The cset of h(x0) for x0 = 0 is the smallest set of values for which g(x0) = f(x0). Moreover, this must be true for all composite functions of h. For example if


g'(y) = (1/(1+y)),

then g(x) = g'(h(x)). In this case, it can be proved that the cset of h(x0) = {-inf, +inf}{-inf, +inf}-inf+infif x0= 0, where {-inf, +inf}{-inf, +inf}-inf+infdenotes the setconsisting of the two values, {-inf, +inf}{-inf, +inf}-inf+infand {-inf, +inf}{-inf, +inf}-inf+inf.   

TABLE 2-4 through TABLE 2-7, contain the csets for the basic arithmetic operations. It is convenient to adopt the notation that an expression denoted by f(x) simply means its cset. Similarly, if


f(X) equals the union of f(x) with x an element of X,

the containment set of f over the interval X, then hull(f(x)) is the sharp interval that contains f(X).


TABLE 2-4 Containment Set for Addition: x + y

{-infinity}

{real: y0}

{+infinity}

{-infinity}

{-infinity}

{-infinity}


R*

{real: x0}

{-infinity}

{x0 + y0}

{+infinity}

{+infinity}


R*

{+infinity}

{+infinity}


TABLE 2-5 Containment Set for Subtraction: x - y

{-infinity}

{real: y0}

{+infinity}

{-infinity}


R*

{-infinity}

{-infinity}

{real: x0}

{+infinity}

{x0 - y0}

{-infinity}

{+infinity}

{+infinity}

{+infinity}


R*


TABLE 2-6 Containment Set for Multiplication: x × y

{-infinity}

{real: y0 < 0}

{0}

{real: y0 > 0}

{+infinity}

{-infinity}

{+infinity}

{+infinity}


R*

{-infinity}

{-infinity}

{real: x0 < 0}

{+infinity}

{x × y}

{0}

{x × y}

{-infinity}

{0}


R*

{0}

{0}

{0}


R*

{real: x0 > 0}

{-infinity}

x × y

{0}

x × y

{+infinity}

{+infinity}

{-infinity}

{-infinity}


R*

{+infinity}

{+infinity}


TABLE 2-7 Containment Set for Division: x ÷ y

{-infinity}

{real: y0 < 0}

{0}

{real: y0 > 0}

{+infinity}

{-infinity}

[0, +infinity]

{+infinity}

{-infinity, +infinity}

{-infinity}

[-infinity, 0]

{real: x0 0}

{0}

{x ÷ y}

{-infinity, +infinity}

{x ÷ y}

{0}

{0}

{0}

{0}


R*

{0}

{0}

{+infinity}

[-infinity, 0]

{-infinity}

{-infinity, +infinity}

{+infinity}

[0, +infinity]


   

All inputs in the tables are shown as sets. Results are shown as sets or intervals. Customary notation, such as (-inf)+(+inf)=-inf(-inf) +y = -inf(-inf)+(+inf)=R*, (-inf)+(+inf)=-inf(-inf) +y = -inf(-inf)+(+inf)=R*, and (-inf)+(+inf)=-inf(-inf) +y = -inf(-inf)+(+inf)=R*, is used, with the understanding that csets are implied when needed. Results for general set (or interval) inputs are the union of the results of the single-point results as they range over the input sets (or intervals).  

In one case, division by zero, the result is not an interval, but the set, {-inf, +inf}[-inf, +inf]=R*. In this case, the narrowest interval in the current system that does not violate the containment constraint of interval arithmetic is the interval {-inf, +inf}[-inf, +inf]=R*. 

Sign changes produce the expected results.


To incorporate these results into the formulas for computing interval endpoints, it is only necessary to identify the desired endpoint, which is also encoded in the rounding direction. Using down arrowup arrowto denote rounding down (towards -infinity) and down arrowup arrowto denote rounding up (towards +infinity), 

down arrow(+inf)/(+inf)=0up arrow(+inf)/(+inf)=+infdown arrow(+inf)/(+inf)=0up arrow(+inf)/(+inf)=+infand down arrow(+inf)/(+inf)=0up arrow(+inf)/(+inf)=+infdown arrow(+inf)/(+inf)=0up arrow(+inf)/(+inf)=+inf.   

down arrow0 x (+inf)=-infup arrow0 x (+inf)=+infdown arrow0 x (+inf)=-infup arrow0 x (+inf)=+infand down arrow0 x (+inf)=-infup arrow0 x (+inf)=+infdown arrow0 x (+inf)=-infup arrow0 x (+inf)=+inf.   

Similarly, because hull({-inf, +inf})=[-inf, +inf],

down arrowx/0=-infup arrowx/0=+infdown arrowx/0=-infup arrowx/0=+infand down arrowx/0=-infup arrowx/0=+infdown arrowx/0=-infup arrowx/0=+inf.   

Finally, the empty interval is represented in C++ by the character string [empty] and has the same properties as the empty set, denoted empty set in the algebra of sets. Any arithmetic operation on an empty interval produces an empty interval result. For additional information regarding the use of empty intervals, see the supplementary papers [6] and [7] cited in Section 2.12, References.

Using these results, C++ implements the closed interval system. The system is closed because all arithmetic operations and functions always produce valid interval results. See the supplementary papers [2] and [8] cited in Section 2.12, References.

2.4.2 Power Function pow(X,n) and pow(X,Y)

The power function can be used with integer or continuous exponents. With a continuous exponent, the power function has indeterminate forms, similar to the four arithmetic operators.


In the integer exponents case, the set of all values that an enclosure of X^n{z where z is an element of x^n and x is an element of X}must contain is X^n{z where z is an element of x^n and x is an element of X}. 

Monotonicity can be used to construct a sharp interval enclosure of the integer power function. When n= 0, Xn, which represents the cset of Xn,is 1 for all x is an element of [-inf, +inf]empty^n = empty, and x is an element of [-inf, +inf]empty^n = emptyfor all n. 

In the continuous exponents case, the set of all values that an interval enclosure of X**Y must contain is



where exp(Y(ln(X)))and exp(y(ln(x))) are their respective containment sets. The function exp(y(ln(x))) makes explicit that only values of x greater than or equal0 need be considered, and is consistent with the definition of X**Ywith REALarguments in C++.

The result is empty if either interval argument is empty, or if sup(X) < 0.

TABLE 2-8 displays the containment sets for all the singularities and indeterminate forms of exp(y(ln(x))).


TABLE 2-8 exp( y (ln( x )))

x0

y0

exp(y(ln(x)))

0

y0 < 0

+infinity

1

-infinity

[0,+infinity]

1

+infinity

[0,+infinity]

+infinity

0

[0,+infinity]

0

0

[0,+infinity]


The results in TABLE 2-8 can be obtained in two ways:

For most compositions, the second option is much easier. If sufficient conditions are satisfied, the closure of a composition can be computed from the composition of its closures. That is, the closure of each sub-expression can be used to compute the closure of the entire expression. In the present case,

exp(y(ln(x))) = exp(y0 × ln(x0)).

That is, the cset of the expression on the left is equal to the composition of csets on the right.

It is always the case that

exp(y(ln(x))) reflex subset exp(y0 × ln(x0)).

Note that this is exactly how interval arithmetic works on intervals. The needed closures of the ln and exp functions are:

 


ln(0) = -inf, ln(+inf)=+inf, exp(-inf)=0, exp(+inf)=+inf

 

A necessary condition for closure-composition equality is that the expression must be a single-use expression (or SUE), which means that each independent variable can appear only once in the expression.

In the present case, the expression is clearly a SUE.

The entries in TABLE 2-8 follow directly from using the containment set of the basic multiply operation in TABLE 2-6 on the closures of the ln and exp functions. For example, with x0 = 1 and y0 = -infinity, ln(x0) = 0. For the closure of multiplication on the values -infinity and 0 in TABLE 2-6, the result is [-infinity, +infinity]. Finally, exp([-infinity, +infinity]) = [0, +infinity], the second entry in TABLE 2-8. Remaining entries are obtained using the same steps. These same results are obtained from the direct derivation of the containment set of exp(y(ln(x))). At this time, sufficient conditions for closure-composition equality of any expression have not been identified. Nevertheless, the following statements apply:


2.5 Set Theoretic Functions

C++ supports the following set theoretic functions for determining the interval hull and intersection of two intervals.

CODE EXAMPLE 2-8 demonstrates the use of the interval-specific functions listed in TABLE 2-9.


TABLE 2-9 Interval-Specific Functions

Function

Name

Mathematical Symbol

interval_hull(X,Y)

Interval Hull

union

intersect(X,Y)

Intersection

intersection

disjoint(X,Y)

Disjoint


A disjoint B = empty

in(r,Y)

Element

element

in_interior(X,Y)

Interior

See Section 2.6.3, Interior: in_interior(X,Y).

proper_subset(X,Y)

Proper Subset

proper subset

proper_superset(X,Y)

Proper Superset

proper super set

subset(X,Y)

Subset

reflex subset

superset(X,Y)

Superset

reflex super set


CODE EXAMPLE 2-8 Set Operators

math% cat ce2-8.cc
 
#include <suninterval.h>
 
#if __cplusplus >= 199711
using namespace SUNW_interval;
#endif
 
int main() {
    interval <double> X, Y;
    double R;
    R = 1.5;
    cout << "Press Control/C to terminate!"<< endl;
    cout <<"X,Y=?";
    cin >>X >>Y;
    for(;;){
        cout <<endl << "For X =" <<X <<",  and" << endl << "Y =" <<Y<< 
        endl;
 
        cout <<"interval_hull(X,Y)=" << endl <<
                interval_hull(X,Y) <<endl;
 
        cout <<"intersect(X,Y)="<< intersect(X,Y) <<endl;
 
         cout <<"disjoint(X,Y)=" << (disjoint(X,Y) ?"T":"F") <<endl;
 
        cout <<"in(R,Y)=" << (in(R,Y) ?"T":"F") <<endl;
 
        cout <<"in_interior(X,Y)=" << 
                (in_interior(X,Y) ?"T":"F") <<endl;
                           
        cout <<"proper_subset(X,Y)=" << 
                (proper_subset(X,Y) ?"T":"F") <<endl;
 
        cout <<"proper_superset(X,Y)=" << 
                (proper_superset(X,Y) ?"T":"F") <<endl;
        
        cout <<"subset(X,Y)=" << (subset(X,Y) ?"T":"F") <<endl;
 
        cout <<"superset(X,Y)=" << (superset(X,Y) ?"T":"F") <<endl;
 
        cout <<"X,Y=?";
        cin >>X>>Y;
    }
}
 
math%CC  -xia -o ce2-8 ce2-8.cc
math%ce2-8
Press Control/C to terminate!
X,Y=? [1] [2]
For X =[0.1000000000000000E+001,0.1000000000000000E+001], and Y =[0.2000000000000000E+001,0.2000000000000000E+001]
interval_hull(X,Y)=[0.1000000000000000E+001,0.2000000000000000E+001]
intersect(X,Y)=[EMPTY                                          ]
disjoint(X,Y)=T
in(R,Y)=F
in_interior(X,Y)=F
proper_subset(X,Y)=F
proper_superset(X,Y)=F
subset(X,Y)=F
superset(X,Y)=F
X,Y=? [1,2] [1,3]
For X =[0.1000000000000000E+001,0.2000000000000000E+001], and Y =[0.1000000000000000E+001,0.3000000000000000E+001]
interval_hull(X,Y)=[0.1000000000000000E+001,0.3000000000000000E+001]
intersect(X,Y)=[0.1000000000000000E+001,0.2000000000000000E+001]
disjoint(X,Y)=F
in(R,Y)=T
in_interior(X,Y)=F
proper_subset(X,Y)=T
proper_superset(X,Y)=F
subset(X,Y)=T
superset(X,Y)=F
X,Y=? ^c
 

 

2.5.1 Hull: X union Y or interval_hull(X,Y)

Description: Interval hull of two intervals. The interval hull is the smallest interval that contains all the elements of the operand intervals.

Mathematical definitions:


hull definition

 


hull definition

 

Arguments: X and Y must be intervals with the same type.

Result type: Same as X.

2.5.2 Intersection: XintersectionY or intersect(X,Y)

Description: Intersection of two intervals.


Mathematical and operational definitions:
hull definition

intersection definition

Arguments: X and Y must be intervals with the same type.

Result type: Same as X.


2.6 Set Relations

C++ provides the following set relations that have been extended to support intervals.

2.6.1 Disjoint: X intersectionY = empty set or disjoint(X,Y)

Description: Test if two intervals are disjoint.


Mathematical and operational definitions:

disjoint definition


disjoint definition

 

Arguments: X and Y must be intervals with the same type.

Result type: interval_bool.

2.6.2 Element: r element Y or in(r,Y)

Description: Test if the number, r, is an element of the interval, Y.


Mathematical and operational definitions:

element definition

Arguments: The type of r is an integer or floating-point type, and the type of Y is interval.

Result type: interval_bool.


The following comments refer to the r is an element of Yset relation:

2.6.3 Interior: in_interior(X,Y)

Description: Test if X is in interior of Y.

The interior of a set in topological space is the union of all open subsets of the set.

For intervals, the function in_interior(X,Y) means that X is a subset of Y, and both of the following relations are false:




Note also that, empty is not an element of empty, but in_interior([empty],[empty])= true

The empty set is open and therefore is a subset of the interior of itself.


Mathematical and operational definitions:

interior definition

Arguments: X and Y must be intervals with the same type.

Result type: interval_bool.

2.6.4 Proper Subset: X proper subset Y or proper_subset(X,Y)

Description: Test if X is a proper subset of Y


Mathematical and operational definitions:
proper subset definitionproper subset definitionproper subset definitionproper subset definition 

Arguments: X and Y must be intervals with the same type.

Result type: interval_bool.

2.6.5 Proper Superset: X proper super set Y or proper_superset(X,Y)


Description:Seeproper subset with X equivalent to Y.

2.6.6 Subset: X reflex subset Y or subset(X,Y)

Description: Test if X is a subset of Y


Mathematical and operational definitions:
subset definitionsubset definitionsubset definitionsubset definition 

Arguments: X and Y must be intervals with the same type.

Result type: interval_bool.

2.6.7 Superset: X reflex super set Y or superset(X,Y)


Description:See subset with X equivalent to Y.


2.7 Relational Functions

2.7.1 Interval Order Relations

Ordering intervals is more complicated than ordering points. Testing whether 2 is less than 3 is unambiguous. With intervals, while the interval [2,3] is certainly less than the interval [4,5], what should be said about [2,3] and [3,4]?

Three different classes of interval relational functions are implemented:

For a certainly-relation to be true, every element of the operand intervals must satisfy the relation. A possibly-relation is true if it is satisfied by any elements of the operand intervals. The set-relations treat intervals as sets. The three classes of interval relational functions converge to the normal relational functions on points if both operand intervals are degenerate.

To distinguish the three function classes, the two-letter relation mnemonics (lt, le, eq, ne, ge, and gt) are prefixed with the letters c, p, or s. The functions seq(X,Y) and sne(X,Y) correspond to the operators == and !=. In all other cases, the relational function class must be explicitly identified, as for example in:

See Section 2.4, Operators and Functions for the syntax and semantics of all interval functions.

The following program demonstrates the use of a set-equality test.


CODE EXAMPLE 2-9 Set-Equality Test

math% cat ce2-9.cc
 
#include <suninterval.h>
 
#if __cplusplus >= 199711
using namespace SUNW_interval;
#endif
 
int main() {
    interval <double> X("[2,3]");
    interval <double> Y("[4,5]");
    if (X+Y == interval <double>("[6,8]"))
        cout << "Check." <<endl;
}
 
math% CC  -xia -o ce2-9 ce2-9.cc
math% ce2-9
Check.
 

CODE EXAMPLE 2-9 uses the set-equality test to verify that X+Y is equal to the interval [6, 8] using the == operator.

Use CODE EXAMPLE 2-10 and CODE EXAMPLE 2-8 to explore the result of interval-specific relational functions.


CODE EXAMPLE 2-10 Interval Relational Functions

math% cat ce2-10.cc
 
#include <suninterval.h>
 
#if __cplusplus >= 199711
using namespace SUNW_interval;
#endif
 
int main() {
    interval <double> X, Y;
    cout << "Press Control/C to terminate!"<< endl;
    cout <<" X,Y =?";
    cin >>X >>Y;
 
    for(;;){
        cout <<endl << "For X =" <<X << ", and Y =" <<Y<< endl;
 
        cout <<"ceq(X,Y),peq(X,Y),seq(X,Y)=" 
             << (ceq(X,Y) ?"T ":"F ")
             << (peq(X,Y) ?"T ":"F ") 
             <<(seq(X,Y) ?"T ":"F ") <<endl;
 
        cout <<"cne(X,Y),pne(X,Y),sne(X,Y)=" 
             << (cne(X,Y) ?"T ":"F ")
             << (pne(X,Y) ?"T ":"F ")
             <<(sne(X,Y) ?"T ":"F ") <<endl;
 
        cout <<"cle(X,Y),ple(X,Y),sle(X,Y)=" 
             << (cle(X,Y) ?"T ":"F ")
             << (ple(X,Y) ?"T ":"F ") 
             <<(sle(X,Y) ?"T ":"F ") <<endl;
 
        cout <<"clt(X,Y),plt(X,Y),slt(X,Y)=" 
             << (clt(X,Y) ?"T ":"F ")
             << (plt(X,Y) ?"T ":"F ") 
             <<(slt(X,Y) ?"T ":"F ") <<endl; 
        cout <<"cge(X,Y),pge(X,Y),sge(X,Y)=" 
             << (cge(X,Y) ?"T ":"F ")
             << (pge(X,Y) ?"T ":"F ") 
             <<(sge(X,Y) ?"T ":"F ") <<endl; 
 
        cout <<"cgt(X,Y),pgt(X,Y),sgt(X,Y)=" 
             << (cgt(X,Y) ?"T ":"F ")
             << (pgt(X,Y) ?"T ":"F ") 
             <<(sgt(X,Y) ?"T ":"F ") <<endl;        
 
        cout <<" X,Y =?";
        cin >>X>>Y;
    }
}
 
math% CC  -xia -o ce2-10 ce2-10.cc
math% ce2-10
 
Press Control/C to terminate!
 X,Y =? [2] [3]
For X =[0.2000000000000000E+001,0.2000000000000000E+001], and Y =[0.3000000000000000E+001,0.3000000000000000E+001]
ceq(X,Y),peq(X,Y),seq(X,Y)=F F F 
cne(X,Y),pne(X,Y),sne(X,Y)=T T T 
cle(X,Y),ple(X,Y),sle(X,Y)=T T T 
clt(X,Y),plt(X,Y),slt(X,Y)=T T T 
cge(X,Y),pge(X,Y),sge(X,Y)=F F F 
cgt(X,Y),pgt(X,Y),sgt(X,Y)=F F F 
 X,Y =? 2 3
For X =[0.1000000000000000E+001,0.3000000000000000E+001], and Y =[0.2000000000000000E+001,0.4000000000000000E+001]
ceq(X,Y),peq(X,Y),seq(X,Y)=F T F 
cne(X,Y),pne(X,Y),sne(X,Y)=F T T 
cle(X,Y),ple(X,Y),sle(X,Y)=F T T 
clt(X,Y),plt(X,Y),slt(X,Y)=F T T 
cge(X,Y),pge(X,Y),sge(X,Y)=F T F 
cgt(X,Y),pgt(X,Y),sgt(X,Y)=F T F 
 X,Y =? ^c
 

An interval relational function, denoted qop, is composed by concatenating both of the following:

In place of seq(X,Y) and sne(X,Y), == and != operators are accepted. To eliminate code ambiguity, all other interval relational functions must be made explicit by specifying a prefix.

Letting "nop" stand for the complement of the operator op, the certainly and possibly functions are related as follows:

cop equivalent !(pnop)

pop equivalent !(cnop)



Note - This identity between certainly and possibly functions holds unconditionally if op element {eq, ne}, and otherwise, only if neither argument is empty. Conversely, the identity does not hold if op element {lt, le, gt, ge} and either operand is empty.



Assuming neither argument is empty, TABLE 2-10 contains the C++ operational definitions of all interval relational functions of the form:

qop(X,Y), given X = [x,x] and Y = [y,y]).

The first column contains the value of the prefix, and the first row contains the value of the operator suffix. If the tabled condition holds, the result is true.


TABLE 2-10 Operational Definitions of Interval Order Relations

lt

le

eq

ge

gt

ne

s

x < y

and

x < y

x less than or equal y

and

x less than or equal y

x = y

and

x = y

x greater than or equal y

and

x greater than or equal y

x > y

and

x > y

x not equal y

or

x not equal y

c

x < y

x less than or equal y

y less than or equal x

and

x less than or equal y

x greater than or equal y

x > y

x > y

or

y > x

p

x < y

x less than or equal y

x less than or equal y

and

y less than or equal x

x greater than or equal y

x > y

y > x

or

x > y


2.7.2 Set Relational Functions

For an affirmative order relation with

op element {lt, le, eq, ge, gt} and


op is an element of {<, <=, =, >=, >},

between two points x and y, the mathematical definition of the corresponding set-relation, Sop, between two non-empty intervals X and Y is:


math equation

For the relation not equal between two points x and y, the corresponding set relation, sne(X,Y), between two non-empty intervals X and Y is:


math equation

Empty intervals are explicitly considered in each of the following relations. In each case:

Arguments: X and Y must be intervals with the same type.

Result type: interval_bool.

2.7.2.1 Set-equal: X = Y or seq(X,Y)

Description: Test if two intervals are set-equal.

Mathematical and operational definitions:

 


set-equal definition

 

Any interval is set-equal to itself, including the empty interval. Therefore, seq([a,b],[a,b]) is true.

2.7.2.2 Set-greater-or-equal: sge(X,Y)


Description:See set-less-or-equal with X equivalent to Y.

2.7.2.3 Set-greater: sgt(X,Y)


Description:See set-less with X equivalent to Y.

2.7.2.4 Set-less-or-equal: sle(X,Y)

Description: Test if one interval is set-less-or-equal to another.

Mathematical and operational definitions:


set-less-or-equal definition

set-less-or-equal definition

 

Any interval is set-equal to itself, including the empty interval. Therefore sle([X,X]) is true.

2.7.2.5 Set-less: slt(X,Y)

Description: Test if one interval is set-less than another.


set-less definition

set-less definition

2.7.2.6 Set-not-equal: X not equal to Yor sne(X,Y)

Description: Test if two intervals are not set-equal.

Mathematical and operational definitions:


set-not-equal definition

set-not-equal definition

 

Any interval is set-equal to itself, including the empty interval. Therefore sne([X,X]) is false.

2.7.3 Certainly Relational Functions


Thecertainly relational functions are true if the underlying relation is true for every element of the operand intervals. For example, clt([a,b],[c,d])is true if x< yfor all x is an element of [a, b]y is an element of [c, d]and x is an element of [a, b]y is an element of [c, d]. This is equivalent to b< c. 

For an affirmative order relation with

op element {lt, le, eq, ge, gt} and


op is an element of {<, <=, =, >=, >},

between two points x and y, the corresponding certainly-true relation cop between two intervals, X and Y, is


math equation.

With the exception of the anti-affirmative certainly-not-equal relation, if either operand of a certainly relation is empty, the result is false. The one exception is the certainly-not-equal relation, cne(X,Y), which is true in this case.

Mathematical and operational definitions cne(X,Y):


certainly relational function definition

certainly relational function definition

For each of the certainly relational functions:

Arguments: X and Y must be intervals with the same type.

Result type: interval_bool.

2.7.4 Possibly Relational Functions


The possibly relational functions are true if any element of the operand intervals satisfy the underlying relation. For example, plt([X,Y])is true if there exists an x is an element of [X]y is an element of [Y]inf(x) less than sup(y)and a x is an element of [X]y is an element of [Y]inf(x) less than sup(y)such that x< y. This is equivalent to x is an element of [X]y is an element of [Y]inf(x) less than sup(y).  

For an affirmative order relation with

op element {lt, le, eq, ge, gt} and


op is an element of {<, <=, =, >=, >},

between two points x and y, the corresponding possibly-true relation Pop between two intervals X and Y is defined as follows:


math equation.

If the empty interval is an operand of a possibly relation then the result is false. The one exception is the anti-affirmative possibly-not-equal relation, pne(X,Y), which is true in this case.

Mathematical and operational definitions pne(X,Y):


possibly relational function definition

possibly relational function definition

For each of the possibly relational functions:

Arguments: X and Y must be intervals with the same type.

Result type: interval_bool.


2.8 Input and Output

The process of performing interval stream input/output is the same as for other non-interval data types.



Note - Floating-point stream manipulations do not influence interval input/output.



2.8.1 Input

When using the single-number form of an interval, the last displayed digit is used to determine the interval's width. See Section 2.8.2, Single-Number Output. For more detailed information, see M. Schulte, V. Zelov, G.W. Walster, D. Chiriaev, "Single-Number Interval I/O," Developments in Reliable Computing, T. Csendes (ed.), (Kluwer 1999).

If an infimum is not internally representable, it is rounded down to an internal approximation known to be less than the exact value. If a supremum is not internally representable, it is rounded up to an internal approximations known to be greater than the exact input value. If the degenerate interval is not internally representable, it is rounded down and rounded up to form an internal interval approximation known to contain the exact input value. These results are shown in CODE EXAMPLE 2-11.


CODE EXAMPLE 2-11 Single-Number Output Examples

math% cat ce2-11.cc
#include <suninterval.h>
 
#if __cplusplus >= 199711
using namespace SUNW_interval;
#endif
 
main() {
    interval<double> X[8];
    for (int i = 0; i < 8 ; i++) {
      cin >> X[i];
      cout << X[i] << endl;
    }
}
 
math% CC -xia ce2-11.cc -o ce2-11
math% ce2-11
1.234500
[0.1234498999999999E+001,0.1234501000000001E+001]
[1.2345]
[0.1234499999999999E+001,0.1234500000000001E+001]
[-inf,2]
[              -Infinity,0.2000000000000000E+001]
[-inf]
[              -Infinity,-.1797693134862315E+309]
[EMPTY]
[EMPTY                                          ]
[1.2345,1.23456]
[0.1234499999999999E+001,0.1234560000000001E+001]
[inf]
  [0.1797693134862315E+309,               Infinity]
[Nan]
[              -Infinity,               Infinity]
 

2.8.2 Single-Number Output

The function single_number_output() is used to display intervals in the single-number form and has the following syntax, where cout is an output stream.


single_number_output(interval<float> X, ostream& out=cout)
single_number_output(interval<double> X, ostream& out=cout)
single_number_output(interval<long double> X, ostream& out=cout)

If the external interval value is not degenerate, the output format is a floating-point or integer literal (X without square brackets, "["..."]"). The external value is interpreted as a non-degenerate mathematical interval [x] + [-1,1]uld.

The single-number interval representation is often less precise than the [inf, sup] representation. This is particularly true when an interval or its single-number representation contains zero or infinity.


For example, the external value of the single-number representation for [-15, +75] is ev([0E2]) = [-100, +100]. The external value of the single-number representation for [1, infinity] is ev([0E+inf]) = [-inf, +inf].

In these cases, to produce a narrower external representation of the internal approximation, the [inf, sup] form is used to display the maximum possible number of significant digits within the output field.


CODE EXAMPLE 2-12 Single-Number [ inf , sup ]-Style Output

math% cat ce2-12.cc
 
#include <suninterval.h>
 
#if __cplusplus >= 199711
using namespace SUNW_interval;
#endif
 
int main() {
    interval <double> X(-1, 10);
    interval <double> Y(1, 6);
    single_number_output(X, cout);
    cout << endl;
 
    single_number_output(Y, cout);
    cout << endl;
}
 
math% CC  -xia -o ce2-12 ce2-12.cc
math% ce2-12
[ -1.0000     , 10.000     ]
[ 1.0000     , 6.0000     ]
 

If it is possible to represent a degenerate interval within the output field, the output string for a single number is enclosed in obligatory square brackets, "[", ... "]" to signify that the result is a point.

An example of using ndigits to display the maximum number of significant decimal digits in the single-number representation of the non-empty interval X is shown in CODE EXAMPLE 2-13.



Note - If the argument of ndigits is a degenerate interval, the result is int_max.




CODE EXAMPLE 2-13 ndigits

math% cat ce2-13.cc
#include <suninterval.h>
 
#if __cplusplus >= 199711
using namespace SUNW_interval;
#endif
 
main() {
    interval<double> X[4];
    X[0] = interval<double>("[1.2345678, 1.23456789]");
    X[1] = interval<double>("[1.234567, 1.2345678]");
    X[2] = interval<double>("[1.23456, 1.234567]");
    X[3] = interval<double>("[1.2345, 1.23456]");
    for (int i = 0; i < 4 ; i++) {
      single_number_output((interval<long double>)X[i], cout);
      cout << " ndigits =" << ndigits(X[i]) << endl;
    }
}
math% CC ce2-13.cc -xia -o ce2-13 
math% ce2-13
                    0.12345679 E+001  ndigits =8
                    0.1234567  E+001  ndigits =7
                    0.123456   E+001  ndigits =6
                    0.12345    E+001  ndigits =5
 

Increasing interval width decreases the number of digits displayed in the single-number representation. When the interval is degenerate all remaining positions are filled with zeros and brackets are added if the degenerate interval value is represented exactly.

2.8.3 Single-Number Input/Output and Base Conversions

Single-number interval input, immediately followed by output, can appear to suggest that a decimal digit of accuracy has been lost, when in fact radix conversion has caused a 1 or 2 ulp increase in the width of the stored input interval. For example, an input of 1.37 followed by an immediate print will result in 1.3 being output.

As shown in CODE EXAMPLE 1-6, programs must use character input and output to exactly echo input values and internal reads to convert input character strings into valid internal approximations.


2.9 Mathematical Functions


This section lists the type-conversion, trigonometric, and other functions that accept intervalarguments. The symbols inf(x)sup(x)[inf(x), sup(x)]and inf(x)sup(x)[inf(x), sup(x)]in the interval inf(x)sup(x)[inf(x), sup(x)]are used to denote its ordered elements, the infimum, or lower bound and supremum, or upper bound, respectively. In point (non-interval) function definitions, lowercase letters xand yare used to denote floating-point or integer values.  

When evaluating a function, f, of an interval argument, X, the interval result, f(X), must be an enclosure of its containment set, f(x). Therefore,


math equation

A similar result holds for functions of n-variables. Determining the containment set of values that must be included when the interval [inf(x), sup(x)]contains values outside the domain of fis discussed in the supplementary paper [1] cited in Section 2.12, References. The results therein are needed to determine the set of values that a function can produce when evaluated on the boundary of, or outside its domain of definition. This set of values, called the containment setis the key to defining interval systems that return valid results, no matter what the value of a function's arguments or an operator's operands. As a consequence, there are no argument restrictions on any intervalfunctions in C++.

2.9.1 Inverse Tangent Function atan2(Y,X)

This sections provides additional information about the inverse tangent function. For further details, see the supplementary paper [9] cited in Section 2.12, References.

Description: Interval enclosure of the inverse tangent function over a pair of intervals.

Mathematical definition:

 


math equation

 

Special values: TABLE 2-11 and CODE EXAMPLE 2-14 display the atan2 indeterminate forms.


TABLE 2-11 atan2 Indeterminate Forms

y0

x0


math equation


math equation


math equation

0

0

[-1, 1]

[-1, 1]


[-pi, pi]

+infinity

+infinity

[0, 1]

[0, 1]


[0, pi/2]

+infinity

-infinity

[0, 1]

[-1, 0]


[pi/2, pi]

-infinity

-infinity

[-1, 0]

[-1, 0]


[-pi, -pi/2]

-infinity

+infinity

[-1, 0]

[0, 1]


[-pi/2, 0]


CODE EXAMPLE 2-14 atan2 Indeterminate Forms

math% cat ce2-14.cc
#include <suninterval.h>
 
#if __cplusplus >= 199711
using namespace SUNW_interval;
#endif
 
int main() {
    interval <double> X,Y;
    cout << "Press Control/C to terminate!"<< endl;
    cout <<"Y,X=?";
    cin >>Y >>X;
 
    for(;;) {
        cout <<endl << "For X =" <<X << endl;
        cout << "For Y =" <<Y << endl;
        cout << atan2(Y,X) << endl << endl;
        cout << "Y,X=?";
        cin >>Y >>X;
    }
}
math% CC  -xia -o ce2-14 ce2-14.cc
math% ce2-14
Press Control/C to terminate!
Y,X=? [0] [0]
For X =[0.0000000000000000E+000,0.0000000000000000E+000]
For Y =[0.0000000000000000E+000,0.0000000000000000E+000]
[-.3141592653589794E+001,0.3141592653589794E+001]
 
Y,X=? inf inf
For X =[0.1797693134862315E+309,               Infinity]
For Y =[0.1797693134862315E+309,               Infinity]
[0.0000000000000000E+000,0.1570796326794897E+001]
 
Y,X=? inf -inf
For X =[              -Infinity,-.1797693134862315E+309]
For Y =[0.1797693134862315E+309,               Infinity]
[0.1570796326794896E+001,0.3141592653589794E+001]
 
Y,X=? -inf inf
For X =[0.1797693134862315E+309,               Infinity]
For Y =[              -Infinity,-.1797693134862315E+309]
[-.1570796326794897E+001,0.0000000000000000E+000]
 
Y,X=? -inf -inf
For X =[              -Infinity,-.1797693134862315E+309]
For Y =[              -Infinity,-.1797693134862315E+309]
[-.3141592653589794E+001,-.1570796326794896E+001]
 
Y,X=? ^c
 

 

Result value: The interval result value is an enclosure for the specified interval. An ideal enclosure is an interval of minimum width that contains the exact mathematical interval in the description.

The result is empty if one or both arguments are empty.


In the case where x< 0 and 0 is an element of Y, to get a sharp interval enclosure (denoted by capital Theta symbol), the following convention uniquely defines the set of all possible returned interval angles:

math equation

This convention, together with


math equation

results in a unique definition of the interval angles capital Theta symbol that atan2(Y,X) must include.

TABLE 2-12 contains the tests and arguments of the floating-point atan2 function that are used to compute the endpoints of capital Theta symbol in the algorithm that satisfies the constraints required to produce sharp interval angles. The first two columns define the distinguishing cases. The third column contains the range of possible values of the midpoint, m(capital Theta symbol), of the interval capital Theta symbol. The last two columns show how the endpoints of capital Theta symbol are computed using the floating-point atan2 function. Directed rounding must be used to guarantee containment.


TABLE 2-12 Tests and Arguments of the Floating-Point atan2 Function

Y

X

m(Q)

theta symbol

theta symbol


-inf(y)< y

x < 0


math equation

atan2(y, x)


atan2(inf(y), x) + 2pi symbol


-inf(y)= y

x < 0


math equation

atan2(y, x)

2pi symbol - theta symbol


sup(y)inf(y)< -sup(y)inf(y) 

x < 0


math equation

atan2(y, x) - 2pi symbol


atan2(inf(y), x)


2.9.2 Maximum: maximum(X1,X2)

Description: Range of maximum.

The containment set for max(X1,..., Xn) is:


math equation.

The implementation of the max function must satisfy:


maximum(X1,X2,[X3,...])subset{max(X1, ..., Xn)}.

2.9.3 Minimum: minimum(X1,X2)

Description: Range of minimum.

The containment set for min(X1,..., Xn) is:


math equation.

The implementation of the min function must satisfy:


minimum(X1,X2,[X3,...])subset{min(X1, ..., Xn)}.

2.9.4 Functions That Accept Interval Arguments

TABLE 2-14 through TABLE 2-18 list the properties of functions that accept interval arguments. TABLE 2-13 lists the tabulated properties of interval functions in these tables.


TABLE 2-13 Tabulated Properties of Each interval Function

Tabulated Property

Description

Function

What the function does

Definition

Mathematical definition

No. of Args.

Number of arguments the function accepts

Name

The function's name

Argument Type

Valid argument types

Function Type

Type returned for specific argument data type


Because indeterminate forms are possible, special values of the pow and atan2 function are contained in Section 2.4.2, Power Function pow(X,n) and pow(X,Y) and Section 2.9.1, Inverse Tangent Function atan2(Y,X), repectively. The remaining functions do not require this treatment.


TABLE 2-14 interval Constructor

Conversion To

No. of Args.

Name

Argument Type

Function Type

interval

1, 2

interval

const char*

const interval<float>&

const interval<double>&

const interval<long double>&

int

long long

float

double

long double

int, int

long long, long long

float, float

double, double

long double, long double

The function type can be

interval<float>, interval<double>, or interval<long double> for each argument type.


TABLE 2-15 interval Arithmetic Functions

Function

Point

Definition

No. of Args.

Name

Argument Type

Function Type

Absolute value

|a|

1

fabs

interval <double>

interval <float>

interval <long double>

interval <double>

interval <float>

interval <long double>

Remainder

a-b(int(a/b))

2

fmod

interval <double>

interval <float>

interval <long double>

interval <double>

interval <float>

interval <long double>

Choose largest value1

max(a,b)

2

maximum

interval <double>

interval <float>

interval <long double>

interval <double>

interval <float>

interval <long double>

Choose smallest value1

min(a,b)

2

minimum

interval <double>

interval <float>

interval <long double>

interval <double>

interval <float>

interval <long double>

(1) The minimum and maximum functions ignore empty interval arguments unless all arguments are empty, in which case, the empty interval is returned.

TABLE 2-16 interval Trigonometric Functions

Function

Point

Definition

No. of

Args.

Name

Argument Type

Function Type

Sine

sin(a)

1

sin

interval <double>

interval <float>

interval <double>

interval <float>

Cosine

cos(a)

1

cos

interval <double>

interval <float>

interval <double>

interval <float>

Tangent

tan(a)

1

tan

interval <double>

interval <float>

interval <double>

interval <float>

Arcsine

arcsin(a)

1

asin

interval <double>

interval <float>

interval <double>

interval <float>

Arccosine

arccos(a)

1

acos

interval <double>

interval <float>

interval <double>

interval <float>

Arctangent

arctan(a)

1

atan

interval <double>

interval <float>

interval <double>

interval <float>

Arctangent1

arctan(a/b)

2

atan2

interval <double>

interval <float>

interval <double>

interval <float>

Hyperbolic Sine

sinh(a)

1

sinh

interval <double>

interval <float>

interval <double>

interval <float>

Hyperbolic Cosine

cosh(a)

1

cosh

interval <double>

interval <float>

interval <double>

interval <float>

Hyperbolic Tangent

tanh(a)

1

tanh

interval <double>

interval <float>

interval <double>

interval <float>

(1) arctan(a/b) = theta symbol, given a = h sintheta symbol, b = h costheta symbol, and h2 = a2 + b2.

TABLE 2-17 Other interval Mathematical Functions

Function

Point

Definition

No. of

Args.

Name

Argument Type

Function Type

Square Root1

exp{ln(a)/2}

1

sqrt

interval <double>

interval <float>

interval <double>

interval <float>

Exponential

exp(a)

1

exp

interval <double>

interval <float>

interval <double>

interval <float>

Natural logarithm

ln(a)

1

log

interval <double>

interval <float>

interval <double>

interval <float>

Common logarithm

log(a)

1

log10

interval <double>

interval <float>

interval <double>

interval <float>

(1) sqrt(a) is multi-valued. A proper interval enclosure must contain both the positive and negative square roots. Defining the sqrt function to be
exp{ln(a)/2}  eliminates this difficulty.

TABLE 2-18 interval -Specific Functions

Function

Definition

No. of Args.

Name

Argument Type

Function Type

Infimum

inf([a, b]) = a

1

inf

interval <double>

interval <float>

interval <long double>

double

float

long double

Supremum

sup([a, b]) = b

1

sup

interval <double>

interval <float>

interval <long double>

double

float

long double

Width

w([a, b]) = b - a

1

wid

interval <double>

interval <float>

interval <long double>

double

float

long double

Midpoint

mid([a, b]) =

(a + b)/2

1

mid

interval <double>

interval <float>

interval <long double>

double

float

long double

Magnitude1

max(|a|) elementA

1

mag

interval <double>

interval <float>

interval <long double>

double

float

long double

Mignitude2

min(|a|) elementA

1

mig

interval <double>

interval <float>

interval <long double>

double

float

long double

Test for empty interval

true if A

is empty

1

is_empty

interval <double>

interval <float>

interval <long double>

interval_bool

interval_bool

interval_bool

Floor

floor(A)

1

floor

interval <double>

interval <float>

interval <long double>

double

double

double

Ceiling

ceiling(A)

1

ceil

interval <double>

interval <float>

interval <long double>

double

double

double

Number of digits3

Maximum number of significant decimal digits in the single-number representation of a non-empty interval

1

ndigits

interval <double>

interval <float>

interval <long double>

int

int

int

(1) mag([a, b]) = max(|a|,|b|) (2) mig([a, b]) = min(|a|,|b|), if a > 0 or b < 0, otherwise 0 (3) Special cases: ndigits([-inf, +inf]) = ndigits([empty]) = 0

    


2.10 Interval Types and the Standard Template Library

When interval types are used as template arguments for STL classes, a blank must be inserted between two consecutive > symbols, as shown on the line marked note 1 in CODE EXAMPLE 2-15.


CODE EXAMPLE 2-15 Example of Using an Interval Type as a Template Argument for STL Classes

math% cat ce2-15.cc
#include <limits.h>
#include <strings.h>
#include <sunmath.h>
#include <stack>
#include <suninterval.h>
#if __cplusplus >= 199711
using namespace SUNW_interval;
#endif
 
int main()
{
   std::stack<interval<double> > st; //note 1
    return 0;
} 
math% CC -xia ce2-15.cc
 

Otherwise, >> is incorrectly interpreted as the right shift operator, as shown on the line marked note 1 in CODE EXAMPLE 2-16.


CODE EXAMPLE 2-16 >> Incorrectly Interpreted as the Right Shift Operator

math% cat ce2-16.cc
#include <limits.h>
#include <strings.h>
#include <sunmath.h>
#include <stack>
#include <suninterval.h>
 
#if __cplusplus >= 199711
using namespace SUNW_interval;
#endif
 
int main()
{
   std::stack<interval<double>> st; //note 1 
    return 0;
} 
math% CC -xia -o ce2-16 ce2-16.cc
"ce2-16.cc", line 13: Error: "," expected instead of ">>".
"ce2-16.cc", line 13: Error: Illegal value for template parameter.
"ce2-16.cc", line 13: Error: "," expected instead of ";".
"ce2-16.cc", line 13: Error: Illegal value for template parameter.
4 Error(s) detected.
 



Note - Interpreting >> as a right shift operator is a general design problem in C++.




2.11 nvector and nmatrix Template Classes

The C++ interval arithmetic library includes the nvector<T> and nmatrix<T> template classes. The nvector<T> class represents and manipulates one-dimensional arrays of values. The nmatrix<T> class represents and manipulates two-dimensional arrays of values.

2.11.1 nvector<T> Class

The nvector<T> class represents and manipulates one-dimensional arrays of values. Elements in a vector are indexed sequentially beginning with zero.

Template specializations are available for the following types:

To write applications that use objects and operations of nvector<T> class, use the following header files and namespace:

#include <iostream.h>

#include <suninterval_vector.h>

 

using namespace SUNW_interval;



Note - Because these classes are based on the C++ standard library, the classes are not available in compatibility mode (-compat).



For a detailed description of the nvector<T> class, see the nvector(3C++) man page.

CODE EXAMPLE 2-17 illustrates the nvector class usage.


CODE EXAMPLE 2-17 Example of Using the nvector Class

math% cat ce2-17.cc
 
#include <iostream.h>
#include <suninterval_vector.h>
using namespace SUNW_interval;
 
main ()
{
	// create two vectors
	nvector< interval<double> > v1 ( interval<double> (2.0, 3.0), 10);
	nvector< double > v2 (10);
 
	// compute middle points of v1 elements
	v2 = mid (v1);
 
	// print them out
	cout << v2 << endl;
 
	// print scalar product of vectors v1 and v1*v1
	cout << dot_product (v1, v1*v1) << endl;
}
 
math% CC ce2-17.cc  -xia
math% a.out
2.5
2.5
2.5
2.5
2.5
2.5
2.5
2.5
2.5
2.5
[0.8000000000000000E+002,0.2700000000000000E+003]
 

2.11.2 nmatrix<T> Class

The nmatrix<T> class represents and manipulates two-dimensional arrays of values. Arrays are stored internally in column-major order (FORTRAN-style). Indexes of matrix elements begin with zero.

Template specializations are available for the following types:

To write applications that use objects and operations of nmatrix<T> class use the following header files and namespace:

#include <iostream.h>

#include <suninterval_matrix.h>

 

using namespace SUNW_interval;



Note - Because these classes are based on the C++ standard library, the classes are not available in compatibility mode (-compat).



For a detailed description of the nmatrix<T> class, see the nmatrix(3C++) man page.

CODE EXAMPLE 2-18 illustrates the nvector class usage.


CODE EXAMPLE 2-18 Example of Using the nmatrix Class

math% cat ce2-18.cc
#include <iostream.h>
#include <suninterval_matrix.h>
 
using namespace SUNW_interval;
 
main()
{
        // create matrix and vector
        nmatrix< interval<double> > m( interval<double>(2.0, 3.0), 3, 3);
        nvector< interval<double> > v( interval<double>(2.0, 3.0), 3);
 
        // examples of equivalent references to 
        // element at line 2 and column 3
        m(1,2) = interval<double>(4.0);
        cout << m(1)(2)<< endl;
        cout << m(1)[2]<< endl;
        cout << m[1](2)<< endl;
        cout << m[1][2]<< endl;
 
        // print result of multiplication of matrix by column
        cout << matmul(m,v) << endl;
 
        // print result of multiplication of line by matrix
        cout << matmul(v,m) << endl;
}
 
math% CC ce2-18.cc  -xia
math% a.out
 
[0.4000000000000000E+001,0.4000000000000000E+001]
[0.4000000000000000E+001,0.4000000000000000E+001]
[0.4000000000000000E+001,0.4000000000000000E+001]
[0.4000000000000000E+001,0.4000000000000000E+001]
[0.1200000000000000E+002,0.2700000000000000E+002]
[0.1600000000000000E+002,0.3000000000000000E+002]
[0.1200000000000000E+002,0.2700000000000000E+002]
[0.1200000000000000E+002,0.2700000000000000E+002]
[0.1200000000000000E+002,0.2700000000000000E+002]
[0.1600000000000000E+002,0.3000000000000000E+002]
 


2.12 References

The following technical reports are available online. See the interval arithmetic readme for the location of these files.

1. G.W. Walster, E.R. Hansen, and J.D. Pryce, "Extended Real Intervals and the Topological Closure of Extended Real Relations," Technical Report, Sun Microsystems. February 2000.

2. G. William Walster, "Empty Intervals," Technical Report, Sun Microsystems. April 1998.

3. G. William Walster, "Closed Interval Systems," Technical Report, Sun Microsystems. August 1999.

4. G. William Walster, "Literal Interval Constants," Technical Report, Sun Microsystems. August 1999.

5. G. William Walster, "Widest-Need Interval Expression Evaluation," Technical Report, Sun Microsystems. August 1999.

6. G. William Walster, "Compiler Support of Interval Arithmetic With Inline Code Generation and Nonstop Exception Handling," Technical Report, Sun Microsystems. February 2000.

7. G. William Walster, "Finding Roots on the Edge of a Function's Domain," Technical Report, Sun Microsystems. February 2000.

8. G. William Walster, "Implementing the `Simple' Closed Interval System," Technical Report, Sun Microsystems. February 2000.

9. G. William Walster, "Interval Angles and the Fortran ATAN2 Intrinsic Function," Technical Report, Sun Microsystems. February 2000.

10. G. William Walster, "The `Simple' Closed Interval System," Technical Report, Sun Microsystems. February 2000.

11. G. William Walster, Margaret S. Bierman, "Interval Arithmetic in Forte Developer Fortran," Technical Report, Sun Microsystems. March 2000.