Go to the previous, next chapter.

Multiple Precision Arithmetic

This chapter describes the multiple precision arithmetic which is embedded in the PROFIL/BIAS distribution but currently not contained in it. Contact knueppel@tu-harburg.d400.de for details.

Because some subroutines in PROFIL are different when using the multiple precision arithmetic, the whole library must be rebuilt to work correctly. Every rebuild must start with a

dmake CLEAN

in the PROFIL subdirectory. To build the library without multiple precision arithmetic, use

dmake architecture

as described in the installation section of PROFIL. See section Common Installation Steps, for details.

If you want to use the multiple precision arithmetic, use

dmake LR=x architecture

On a RS/6000 architecture using gcc, the command would be

dmake LR=x ibmgcc

Before rebuilding PROFIL, the multiple precision arithmetic libraries must have been built. Change to the appropriate directory with

cd lr

After that, use

dmake architecture

as you have used it to build BIAS, e.g.

dmake ibmgcc

Note that using the multiple precision arithmetic in your programs requires an additional include path as well as 2 additional libraries. The basic multiple precision include files are contained in the subdirectory lr. This subdirectory also contains the two new libraries Lr and Li. If you want to move your include files and your libraries to a different place, see section Common Installation Steps for further information and do not forget to move the include files and libraries from the subdirectory lr, too.

Changes in Interval Input/Output

When using PROFIL with the multiple precision arithmetic, the input and output of intervals (interval vectors and matrices) changes. Without the multiple precision arithmetic, any interval value is read as 2 REAL numbers, the first denotes the lower and the latter the upper bound. On output, the lower and upper bound are separated by a comma and surrounded by square brackets. Because the interval bounds are treated as floating point numbers, the conversion routine of the C library which uses a rounding to nearest is used. Therefore, an interval that is read in as

0.1 0.1

does not contain the real value 0.1 but is a point interval whose bounds are equal to a floating point approximation of 0.1.

This is no longer true when using the multiple precision arithmetic. With the multiple precision arithmetic, the interval input and output routines use the multiple precision interval I/O routines, all bounds on input and output are correctly rounded and the input format is the same as the output format. Additionally, there are some nice improvements when using intervals with a small relative diameter. For example, the interval [12.345,12.346] can be typed as:

[12.345,12.346]
12.34[5,6]
1.234[5,6]E+1
[1.2345,1.2346]E+1
[1.2345E+1,1.2346E+1]

For intervals like [1.999,2.002] the special notation

1.99[9,12]

can be used, where the 1 in the upper bound denotes a carry to be added to the least significant common digit. Point intervals can be read as one number, e.g. 0.1 and [0.1,0.1] are the same interval, both containing the real number 0.1.

The output format for intervals is controlled by the same commands used for the multiple precision reals/intervals. See section Long Real Numbers --- LongReal.h and section Long Intervals --- LongInterval.h, for details.

Due to the same reasons discussed above, the function Hull cannot be used to get an enclosure of a real constant, e.g. by Hull(0.1). This is because Hull(0.1) returns a point interval whose bounds are equal to a floating point approximation of 0.1. If you need an enclosure of 0.1, use either DivBounds(1.0,10.0) or Enclosure("1.0"). The latter is using the multiple precision package, where the first is independent of it.

Long Real Numbers --- LongReal.h

This file defines all operations concerning multiple precision real numbers (in the following refered as long real numbers) and introduces the new data type LONGREAL.

Data Type: LONGREAL variable [(char * string [, INT precision])]
Defines a long real variable. If string is present, variable is initialized with the decimal constant contained in the string and the initial precison the determined by the precision of the decimal string constant. If the optional parameter precision is present, it denotes the initial precision in decimal digits for variable. Example:

LONGREAL a("1.234", 20);

Defines a, initializes a with the decimal constant 1.234 and sets the current precision of a to 20 decimal digits.

The current working precision (i.e. the initial precision of new declared variables and the precision of any calculated results) is controlled by the following routines:

Function: void SetDigits (INT n)
Sets the current working precision to approx. n decimal digits.

Function: void SetBaseDigits (INT n)
Sets the current working precision to n base 65536 digits.

Function: INT GetDigits ()
Returns the current working precision in approx. n decimal digits.

Function: INT GetBaseDigits ()
Returns the current working precision in n base 65536 digits.

The basic operations +, -, *, and /, the unary operators + and - as well as +=, -=, *=, and /= are defined for long real numbers. The operand type REAL is also allowed as long as at least one operand is of type LONGREAL.

The predecessor and successor of a long real expression can be obtained by -- and ++.

Comparisons of long real numbers are possible with ==, !=, <, <=, >, and >=.

Additionally, the following functions are provided:

Function: void MakeTemporary (LONGREAL a)
Defines a to be a temporary variable. This is only important when the improved memory management is used.

See section Vector Operations --- Vector.h, function MakeTemporary for more information.

Function: void MakePermanent (LONGREAL a)
Changes the temporary variable a into a permanent one.

See section Configuration, for details.

Function: REAL RoundToReal (LONGREAL a [, INT rounding mode])
Returns the value of a rounded to a REAL value. The following values are possible for rounding mode, where the rounding to nearest is the default:

LR_RND_NEAR
Rounds to the nearest REAL value.

LR_RND_DOWN
Rounds downwards to the next REAL value.

LR_RND_UP
Rounds upwards to the next REAL value.

Function: void Accumulate (LONGREAL a, VECTOR v, VECTOR w)
Calculates the accurate scalar product of v and w and adds it to a.

Important: The precision of a is unchanged!

Function: LONGREAL StringToLongReal (char * s)
Converts the decimal string constant s to a long real number.

The input and output of long real numbers is written as for all other data types. Currently, long real numbers are always output using an exponential format. Only the number of digits and the output rounding mode can be controlled. The following functions are used to control the output format for long real numbers and for the long intervals described in the next section:

Function: void SetOutFracDigits (INT n)
Sets the number of fractional digits on output to n.

Function: void SetOutIntDigits (INT n)
Sets the maxmium number of integer digits to n. If the true number of integer digits is larger, the exponential format will be used.

This function affects only the output of long intervals.

Function: void SetOutRndMode (INT n)
Sets the output rounding mode for long real numbers. Possible values for n are:

0
Round to nearest.

1
Round downwards.

2
Round upwards.

3
Round by chopping.

Function: INT GetOutFracDigits ()
Returns the current number of fractional digits.

Function: INT GetOutIntDigits ()
Returns the current number of integer digits.

Function: INT GetOutRndMode ()
Returns the current output rounding mode.

Long Intervals --- LongInterval.h

This file defines all operations concerning multiple precision intervals (in the following refered as long intervals) and introduces the new data type LONGINTERVAL.

Data Type: LONGINTERVAL variable [(char * string [, INT precision])]
Defines a long interval variable. If string is present, variable is initialized with the decimal constant interval contained in the string. If the optional parameter precision is present, it denotes the initial precision in decimal digits for variable. Example:

LONGINTERVAL a("[1.2,1.3]", 20);

Defines a, initialized a with the decimal constant interval [1.2,1.3] and sets the current precision of a to 20 decimal digits.

The basic operations +, -, *, and /, the unary operators + and - as well as +=, -=, *=, and /= are defined for long intervals. The operand types REAL, INTERVAL, and LONGREAL are also allowed as long as at least one operand is of type LONGINTERVAL.

The current working precision is controlled by the same commands used for the long real numbers. See section Long Real Numbers --- LongReal.h, for details.

Additionally, the following functions are provided:

Function: void MakeTemporary (LONGINTERVAL a)
Defines a to be a temporary variable. This is only important when the improved memory management is used.

See section Vector Operations --- Vector.h, function MakeTemporary for more information.

Function: void MakePermanent (LONGINTERVAL a)
Changes the temporary variable a into a permanent one.

See section Configuration, for details.

Function: LONGREAL Inf (LONGINTERVAL a)
Returns the lower bound of a.

Function: LONGREAL Sup (LONGINTERVAL a)
Returns the upper bound of a.

Function: LONGINTERVAL Hull (LONGREAL a)
Returns an enclosure of the long real number a.

See section Changes in Interval Input/Output, for more information about Hull.

Function: LONGINTERVAL Hull (LONGREAL a, LONGREAL b)
Returns an enclosure of the convex hull of a and b.

Function: LONGREAL Diam (LONGINTERVAL a)
Returns the diameter of a.

Function: LONGREAL Mid (LONGINTERVAL a)
Returns the midpoint of a.

Function: INTERVAL RoundToInterval (LONGINTERVAL a)
Returns the value of a rounded to the smallest enclosing INTERVAL value.

Function: void Accumulate (LONGINTERVAL a, v, w)
Calculates the accurate scalar product of the vectors v and w (the types VECTOR and INTERVAL_VECTOR are possible either) and adds the result to a.

Important: The precision of a is unchanged!

Function: INTERVAL Enclosure (char * s)
Returns an interval which encloses the interval given by the decimal string constant s.

Function: LONGINTERVAL LongIntervalEnclosure (char * s)
Same as Enclosure, but returns a long interval.

The output format of long intervals is controlled by the same commands used for the long real numbers. Additionally, the appearance of the output can be changed by the following command:

Function: void SetOutOptions (INT n)
Defines the output format for long intervals. Allowed values for n are:

LI_FSTR_INT
If the interval bounds are integer values and the number of decimal digits is less than the value returned by GetIntDigits, the bounds are written to output without any fractional digits.

Otherwise, the next format is tried.

LI_FSTR_FRACCOM
If there are common leading digits for the interval bounds, they are extracted and displayed only once. For example the interval [1.234,1.235] is displayed as 1.23[4,5].

Otherwise, the next format is tried.

LI_FSTR_FRACSEP
If the interval bounds are not too large (less than GetIntDigits integer digits), they are displayed as two floating point numbers.

Otherwise, the exponential format is used.

If LI_STR_SINGLE is added to any of the above values, all spaces used for indentation are removed.

The default output format is

(LI_FSTR_INT | LI_STR_SINGLE)

High Precision Vector and Matrix Operations --- HighPrec.h

This file provides several vector and matrix operations using an accurate scalar product instead of a normal floating point or interval accumulator.

Function: REAL HighPrecMul (VECTOR v, VECTOR w)
Returns the accurate scalar product of v and w rounded to the nearest REAL value.

Function: VECTOR HighPrecMul (MATRIX A, VECTOR w)
Returns the accurate matrix-vector product of A and w where every component of the result is rounded to the nearest REAL value.

Function: MATRIX HighPrecMul (MATRIX A, MATRIX A)
Returns the accurate matrix product of A and A where every component of the result is rounded to the nearest REAL value.

Function: INTERVAL HighPrecMulBounds (VECTOR v, VECTOR w)
Returns an enclosure of the accurate scalar product of v and w.

Function: INTERVAL_VECTOR HighPrecMulBounds (MATRIX A, VECTOR w)
Returns an enclosure of the accurate matrix-vector product of A and w.

Function: INTERVAL_MATRIX HighPrecMulBounds (MATRIX A, MATRIX B)
Returns an enclosure of the accurate matrix product of A and B.

Function: INTERVAL HighPrecMul (v, w)
Returns an enclosure of the accurate scalar product of the v and w. The parameters v and w may either be of type VECTOR or INTERVAL_VECTOR but not both VECTOR.

Function: INTERVAL_VECTOR HighPrecMul (A, w)
Returns an enclosure of the accurate matrix-vector product of A and w. The parameter v may either be MATRIX or INTERVAL_MATRIX and the parameter w may either be VECTOR or INTERVAL_VECTOR.

The type combination MATRIX and VECTOR is not allowed.

Function: INTERVAL_MATRIX HighPrecMul (A, B)
Returns an enclosure of the accurate matrix product of A and B. The parameters v and w may either be of type MATRIX or INTERVAL_MATRIX but not both MATRIX.

Function: INTERVAL_MATRIX IdMinusHighPrecMul (A, B)
Returns an enclosure of the identity matrix minus the accurate matrix product of A and B. The parameters v and w may either be of type MATRIX or INTERVAL_MATRIX.

Acknowledgements

Thomas Simenec wrote the test matrices contained in the PROFIL/BIAS extension package. He frequently tested many nearly similar revisions of all packages and gave many helpful hints for the DOS and OS/2 versions.

Many thanks go to Dirk Husung, whose long real package is the basis of all multiple precision routines.