(* Last edited on 1999-11-01 07:06:22 by stolfi *) INTERFACE IA; (* Interval arithmetic (shoddy implementation, without rounding control). *) FROM Fmt IMPORT Style; FROM LongReal IMPORT MaxSignifDigits; TYPE T = RECORD lo, hi: LONG END; (* A value "x" of this type represents the set "R(x)" of all real numbers "z" such that "x.lo <= z <= x.hi". The endpoint "x.lo" may be a finite "LONG" or "-Infinity". The endpoint "x.hi" may be a finite "LONG" or "+Infinity". Neither endpoint may be "NaN". Note that "-Infinity" and "+Infinity" are not real numbers, so "T{0.0d0, +Infinity}" includes "0" and "Pi", but not "+Infinity". Thus "R(x) = {}" if and only if "x.lo > x.hi". *) LONG = LONGREAL; CONST Infinity = LAST(LONG); Empty = T{+1.0d0, -1.0d0}; (* A representation of the empty set. *) Full = T{-Infinity, +Infinity}; (* The set of all real numbers. *) (* MATHEMATICAL OPERATIONS *) (* Each procedure in this section is associated to some real-valued function "f(x,y,...)" of real arguments. The procedure returns the narrowest "T" value that contains all results "f(x,y...)" when "x,y,..." range over the sets represented by the given "T" values. For an associative function "f" this interface often provides also a ternary and N-ary version of the basic procedure, with names ending in "3" and "N" respectively. The procedures generally return "Empty" if any "T" argument is "Empty", or if "f" is not defined for any combination of real numbers in the given "T" values. The current implementation does NOT take rounding errors into account. *) PROCEDURE Add(x, y: T): T; PROCEDURE Add3(x, y, z: T): T; PROCEDURE AddN(READONLY x: ARRAY OF T): T; (* "f(x,y) = x + y" *) PROCEDURE Sub(x, y: T): T; (* "f(x,y) = x - y" *) PROCEDURE Shift(alpha: LONG; x: T): T; (* "f(x) = x + alpha" *) PROCEDURE Avg(x, y: T): T; (* "f(x,y) = (x + y)/2" *) PROCEDURE Neg(x: T): T; (* "f(x) = -x" *) PROCEDURE Scale(alpha: LONG; x: T): T; (* "f(x) = alpha*x" *) PROCEDURE Mix(alpha: LONG; x: T; beta: LONG; y: T): T; (* "f(x,y) = alpha*x + beta*y" *) PROCEDURE Mul(x, y: T): T; PROCEDURE Mul3(x, y, z: T): T; PROCEDURE MulN(READONLY x: ARRAY OF T): T; (* "f(x,y) = x*y" *) PROCEDURE Sqr(x: T): T; (* "f(x,y) = x^2" *) PROCEDURE Div(x, y: T): T; (* "f(x,y) = x/y"; any real value if "x = 0" and "y = 0"; undefined if "y = 0" and "x" is not zero. *) PROCEDURE Inv(x: T): T; (* "f(x) = 1/x"; undefined if "x=0". *) PROCEDURE Sqrt(x: T): T; (* "f(x,y) = ABS(sqrt(x))" if "x > 0", else undefined. *) PROCEDURE Pow(x: T; e: LONG): T; (* "f(x,y) = x^e"; undefined if "x" is negative and "e" is not integer, or "x" is 0 and "e" is negative. *) PROCEDURE Tanh(x: T): T; (* "f(x) = tanh(x)", where "tanh" is the hyperbolic tangent, (exp(x)-exp(-x))/(exp(x)+exp(-x)). *) PROCEDURE Max(x, y: T): T; PROCEDURE Max3(x, y, z: T): T; PROCEDURE MaxN(READONLY x: ARRAY OF T): T; (* "f(x,y) = max{x,y}" *) PROCEDURE Min(x, y: T): T; PROCEDURE Min3(x, y, z: T): T; PROCEDURE MinN(READONLY x: ARRAY OF T): T; (* "f(x,y) = min{x,y}" *) PROCEDURE Clip(x: T; range: T): T; (* Clips "x" to the interval "range", which must be non-empty. Basically the same as "Min(Max(x, range), range)". *) (* AUXILIARY PROCEDURES *) PROCEDURE Meet(x, y: T): T; (* A "T" value "z" such that "R(z)" is the intersection of "R(x)" and "R(y)". *) PROCEDURE Join(x, y: T): T; (* The narrowest "T" value "z" such that "R(z)" contains both of "R(x)" and "R(y)". *) PROCEDURE Mid(x: T): LONG; (* The midpoint of "x", rounded to the nearest "LONG". An error if "x" is empty. *) PROCEDURE Rad(x: T): LONG; (* The smallest "LONG" "r" such that "ABS(z - Mid(x)) <= r" for all "z" in "R(x)". *) PROCEDURE ToText( x: T; style: Style := Style.Auto; prec: CARDINAL := MaxSignifDigits - 1; width: CARDINAL := 0; literal: BOOLEAN := FALSE; ): TEXT; (* Converts "x" to legible text. Formats each bound with the formatting parameters "style", "prec", and "literal", padded to the given width. *) END IA.