1.1 What Is Interval Arithmetic?

Interval arithmetic is a system for computing with intervals of numbers. Because interval arithmetic always produces intervals that contain the set of all possible result values, interval algorithms have been developed to perform surprisingly difficult computations. For more information on interval applications, see the Interval Arithmetic Readme.

1.2 C++ Interval Support Goal: Implementation Quality

The goal of interval support in C++ is to stimulate development of commercial interval solver libraries and applications by providing program developers with:

Quality interval code

Narrow-width interval results

Rapidly executing interval code

An easy-to-use software development environment

Support and features are components of implementation quality. Not all possible quality of implementation features have been implemented. Throughout this book, various unimplemented quality of implementation opportunities are described. Additional suggestions from users are welcome.

1.2.1 Quality Interval Code

As a consequence of evaluating any interval expression, a valid interval-supporting compiler must produce an interval that contains the set of all possible results. The set of all possible results is called the containment set (cset) of the given expression. The requirement to enclose an expression's cset is the containment constraint of interval arithmetic. The failure to satisfy the containment constraint is a containment failure. A silent containment failure (with no warning or documentation) is a fatal error in any interval computing system. By satisfying this single constraint, intervals provide otherwise unprecedented computing quality.

Given the containment constraint is satisfied, implementation quality is determined by the location of a point in the two-dimensional plane whose axes are runtime and interval width. On both axes, small is better. How to trade runtime for interval width depends on the application. Both runtime and interval width are obvious measures of interval-system quality. Because interval width and runtime are always available, measuring the accuracy of both interval algorithms and implementation systems is no more difficult than measuring their speed.

The Sun Studio tools for performance profiling can be used to tune interval programs. However, in C++, no interval-specific tools exist to help isolate where an algorithm may gain unnecessary interval width. Quality of implementation opportunities include adding additional interval-specific code development and debugging tools.

1.2.2 Narrow-Width Interval Results

All the normal language and compiler quality of implementation opportunities exist for intervals, including rapid execution and ease of use.

Valid interval implementation systems include a new additional quality of implementation opportunity: Minimize the width of computed intervals while always satisfying the containment constraint.

If an interval's width is as narrow as possible, it is said to be sharp. For a given floating-point precision, an interval result is sharp if its width is as narrow as possible.

The following statements apply to the width of intervals produced by the interval class:

Individual intervals are sharp approximations of their external representation.

Individual interval arithmetic functions produce sharp results.

Mathematical functions usually produce sharp results.

1.2.3 Rapidly Executing Interval Code

By providing compiler optimization and hardware instruction support, interval operations are not necessarily slower than their floating-point counterparts. The following can be said about the speed of interval operators and mathematical functions:

Arithmetic operations are reasonably fast.

The speed of interval<double> mathematical functions is generally less than half the speed of their double counterparts. interval<float> math functions are provided, but are not tuned for speed (unlike their interval<double> counterparts). The interval<longdouble> mathematical functions are not provided in this release. However, other interval<longdouble> functions are supported.

interval arithmetic operations and mathematical functions that form a closed mathematical system. (This means that valid results are produced for any possible operator-operand combination, including division by zero and other indeterminate forms involving zero and infinities.)

See the C++ Migration Guide and the C++ User's Guide for more information on these modes.

The following sections describe the ways that these compilation modes affect compilation of applications using the interval library.

1.2.5.1 namespace SUNW_interval

In standard mode only, all interval types and symbols are defined within the namespace SUNW_interval. To write applications that compile in both standard mode and compatibility mode, use the following code.

#if __cplusplus >= 199711

using namespace SUNW_interval;

#endif

1.2.5.2 Boolean Return Values

Some interval functions return boolean values. Because compatibility mode does not support boolean types by default, these functions are defined returning a type interval_bool, which is a typedef to an int (compatibility mode) or a bool (standard mode). Client code should use whatever type appropriate for boolean values and rely on the appropriate conversions from interval_bool to the client's boolean type. The library does not support explicit use of -features=bool or -features=no%bool.

1.2.5.3 Input and Output

The interval library requires the I/O mechanisms supplied in one of the three compilation modes listed in Section 1.2.5, The C++ Interval Class Compilation Interface. In particular, the flag -library=iostream must be specified on all compile and link commands if the application is using the standard mode with the traditional iostream library.

1.3 Writing Interval Code for C++

The examples in this section are designed to help new interval programmers to understand the basics and to quickly begin writing useful interval code. Modifying and experimenting with the examples is strongly recommended.

1.3.2 interval External Representations

The integer and floating-point numbers that can be represented in computers are referred to as internal machine representable numbers. These numbers are a subset of the entire set of extended (including - and +) real numbers. To make the distinction, machine representable numbers are referred to as internal and any number as external. Let x be an external (decimal) number or an interval endpoint that can be read or written in C++. Such a number can be used to represent either an external interval or an endpoint. There are three displayable forms of an external interval:

[X_inf,X_sup]represents the mathematical interval

[X] represents the degenerate mathematical interval [x, x], or [x]

X represents the non-degenerate mathematical interval [x] + [-1,+1]uld (unit in the last digit). This form is the single-number representation, in which the last decimal digit is used to construct an interval. See Section 1.3.4, interval Input/Output and Section 2.8.2, Single-Number Output. In this form, trailing zeros are significant. Thus 0.10 represents interval [0.09,0.11], 100E-1 represents interval [9.9,10.1], and 0.10000000 represents the interval [0.099999999,0.100000001].

A positive or negative infinite interval endpoint is input/output as a case-insensitive string inf or infinity prefixed with a minus sign or an optional plus sign.

The empty interval is input/output as the case-insensitive string empty enclosed in square brackets, [...]. The string, "empty", can be preceded or followed by blank spaces.

Note - If an invalid interval such as [2,1] is converted to an internal interval, [-inf,inf] is stored internally.

1.3.3 Interval Declaration and Initialization

The interval declaration statement performs the same functions for interval data items as the double and int declarations do for their respective data items. CODE EXAMPLE 1-2 uses interval variables and initialization to perform the same operation as CODE EXAMPLE 1-1.

CODE EXAMPLE 1-2 Hello Interval World With interval Variables

math% cat ce1-2.cc

#include <suninterval.h>

#if __cplusplus >= 199711

using namespace SUNW_interval;

#endif

int main() {

interval<double> X("[2,3]");

interval<double> Y("3"); // interval [2,4] is represented

cout <<"[2,3]+[2,4]=" << X + Y;

cout << endl;

}

math% CC -xia -o ce1-2 ce1-2.cc

math% ce1-2

[2,3]+[2,4]=[0.4000000000000000E+001,0.7000000000000000E+001]

Variables X and Y are declared to be of type interval<double> variables and are initialized to [2, 3] and [2, 4], respectively. The standard output stream is used to print the labeled interval sum of X and Y.

Note - To facilitate code-example readability, all interval variables are shown as uppercase characters. Interval variables can be uppercase or lowercase in code.

1.3.4 intervalInput/Output

Full support for reading and writing intervals is provided. Because reading and interactively entering interval data can be tedious, a single-number interval format is introduced. The single-number convention is that any number not contained in brackets is interpreted as an interval whose lower and upper bounds are constructed by subtracting and adding 1 unit to the last displayed digit.

Thus

2.345 = [2.344, 2.346],

2.34500 = [2.34499, 2.34501],

and

23 = [22, 24].

Symbolically,

[2.34499, 2.34501] = 2.34500 + [-1, +1]uld

where [-1, +1]uld means that the interval [-1, +1] is added to the last digit of the preceding number. The subscript, uld, is a mnemonic for "unit in the last digit."

To represent a degenerate interval, a single number can be enclosed in square brackets. For example,

[2.345] = [2.345, 2.345] = 2.345000000000.....

This convention is used both for input and constructing intervals out of an external character string representation. Thus, type [0.1] to indicate the input value is an exact decimal number, even though 0.1 is not machine representable.

During input to a program, [0.1,0.1]=[0.1] represents the point, 0.1, while using single-number input/output, 0.1 represents the interval

0.1 + [-1, +1]uld = [0, 0.2].

The input conversion process constructs a sharp interval that contains the input decimal value. If the value is machine representable, the internal machine approximation is degenerate. If the value is not machine representable, an interval having width of 1-ulp (unit-in-the-last-place of the mantissa) is constructed.

Note - A uld and an ulp are different. A uld is a unit in the last displayed decimal digit of an external number. An ulp is the smallest possible increment or decrement that can be made to an internal machine number.

The simplest way to read and print interval data items is with standard stream input and output.

CODE EXAMPLE 1-3 is a simple tool to help users become familiar with interval arithmetic and single-number interval input/output using streams.

Note - The interval containment constraint requires that directed rounding be used during both input and output. With single-number input followed immediately by single-number output, a decimal digit of accuracy can appear to be lost. In fact, the width of the input interval is increased by at most 1-ulp, when the input value is not machine representable. See Section 1.3.5, Single-Number Input/Output and CODE EXAMPLE 1-6.

CODE EXAMPLE 1-3 Interval Input/Output

math% cat ce1-3.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 <<endl<<", and Y=" <<Y <<endl;

cout <<"X+Y=" << (X+Y) <<endl;

cout <<"X-Y=" << (X-Y) <<endl;

cout <<"X*Y=" << (X*Y) <<endl;

cout <<"X/Y=" << (X/Y) <<endl;

cout <<"pow(X,Y)=" << pow(X,Y) <<endl;

cout <<" X,Y=?";

cin >>X>>Y;

}

}

math% CC ce1-3.cc -xia -o ce1-3

math% ce1-3

Press Control/C to terminate!

X,Y=?[1,2][3,4]

For X =[0.1000000000000000E+001,0.2000000000000000E+001]

, and Y=[0.3000000000000000E+001,0.4000000000000000E+001]

X+Y=[0.4000000000000000E+001,0.6000000000000000E+001]

X-Y=[-.3000000000000000E+001,-.1000000000000000E+001]

X*Y=[0.3000000000000000E+001,0.8000000000000000E+001]

X/Y=[0.2500000000000000E+000,0.6666666666666668E+000]

pow(X,Y)=[0.1000000000000000E+001,0.1600000000000000E+002]

X,Y=?[1,2] -inf

For X =[0.1000000000000000E+001,0.2000000000000000E+001]

, and Y=[ -Infinity,-.1797693134862315E+309]

X+Y=[ -Infinity,-.1797693134862315E+309]

X-Y=[0.1797693134862315E+309, Infinity]

X*Y=[ -Infinity,-.1797693134862315E+309]

X/Y=[-.1112536929253602E-307,0.0000000000000000E+000]

pow(X,Y)=[0.0000000000000000E+000, Infinity]

X,Y=? ^c

1.3.5 Single-Number Input/Output

One of the most frustrating aspects of reading interval output is comparing interval infima and suprema to count the number of digits that agree. For example, CODE EXAMPLE 1-4 and CODE EXAMPLE 1-5 shows the interval output of a program that generates different random-width interval data.

Intervals can always be entered and displayed using the traditional [inf, sup] display format. In addition, a single number in square brackets denotes a point. For example, on input, [0.1] is interpreted as the number 1/10. To guarantee containment, directed rounding is used to construct an internal approximation that is known to contain the number 1/10.

When a non-machine representable number is read using single-number input, conversion from decimal to binary (radix conversion) and the containment constraint force the number's interval width to be increased by 1-ulp (unit in the last place of the mantissa). When this result is displayed using single-number output, it can appear that a decimal digit of accuracy has been lost. This is not so. To echo single-number interval inputs, use character input together with an interval constructor with a character string argument, as shown in CODE EXAMPLE 1-6.

Note - Not all mathematically equivalent interval expressions produce intervals having the same width. Additionally, it is often not possible to compute a sharp result by simply evaluating a single interval expression. In general, interval result width depends on the value of interval arguments and the form of the expression.