Application Center - Maplesoft

# INTERVALs Package

You can switch back to the summary page by clicking here.

INTERVALs.mws

Interval Arithmetic Package

Douglas Wilhelm Harder 2001/10/17

This package is meant to give a front end package to Maple's already existing interval arithmetic tools, including the interval object and the command . It over-rides the operations +, -, *, /, ^, and the functions and and the various trigonometric, hyperbolic and their inverse functions, and the exponential and logrithmic functions. It solves two problems: the need to call evalr on the result of operations, and cancelation of equal objects.

The obscure name simply ensures that if any new package in Maple associated with intervals is introduced then no name collision will occur.

The Source Code

> restart;

INTERVALs := module()
export `+`, `-`, `*`, `/`, `^`, eval,
ln, exp,
sin, cos, tan, sec, csc, cot,
arcsin, arccos, arctan, arcsec, arccsc, arccot,
sinh, cosh, tanh, sech, csch, coth,
arcsinh, arccosh, arctanh, arcsech, arccsch, arccoth,
signum;
local combine, i;

`+` := proc(x, y)
if nargs = 0 then
0;
elif nargs = 1 then
x;
elif nargs = 2 then
if type( x, 'specfunc'('`..`', 'INTERVAL') ) or
type( y, 'specfunc'('`..`', 'INTERVAL') ) then
evalr( x + y );
else
x + y;
end if;
else
procname( procname( x, y ), args[3..-1] );
end if;
end proc;

`-` := proc(x, y)
if nargs = 1 then
if type( x, 'specfunc'('`..`', 'INTERVAL') ) then
INTERVAL( seq( -op( 2, i )..-op( 1, i ), i = x ) );
else
-x;
end if;
elif nargs = 2 then
`+`( x, `-`(y) );
else
error "expecting 1 or 2 arguments, but got %1", nargs;
end if;
end proc;

`*` := proc(x, y)
if nargs = 0 then
1;
elif nargs = 1 then
x;
elif nargs = 2 then
if type( x, 'specfunc'('`..`', 'INTERVAL') ) or
type( y, 'specfunc'('`..`', 'INTERVAL') ) then
evalr( x * y );
else
x * y;
end if;
else
procname( procname( x, y ), args[3..-1] );
end if;
end proc;

`/` := proc(x, y)
if nargs = 1 then
if type( x, 'specfunc'('`..`', 'INTERVAL') ) then
evalr( 1/x );
else
1/x;
end if;
elif nargs = 2 then
`*`( x, `/`(y) );
else
error "expecting 1 or 2 arguments, but got %1", nargs;
end if;
end proc;

`^` := proc(x, y)
if nargs = 2 then
if type( x, 'specfunc'('`..`', 'INTERVAL') ) or
type( y, 'specfunc'('`..`', 'INTERVAL') ) then
evalr( x ^ y );
else
x ^ y;
end if;
else
error "expecting 2 arguments, but got %1", nargs;
end if;
end proc;

eval := proc( x::uneval, y )
if nargs = 1 then
:-eval( ':-eval'( x ) );
elif type( y, 'posint' ) then
:-eval( ':-eval'( x, y ) );
elif type( y, {'`=`', 'list'('`=`')} ) then
try
combine( :-eval(x), y );
catch:
error;
end try;
else
error "wrong number (or type) of parameters in function eval";
end if;
end proc;

combine := proc(x, y)
local M, i, result;

if type( x, atomic ) then
:-eval( x, y );
elif type( x, 'specfunc'('`..`', INTERVAL) ) then
:-eval( x, y );
elif type( x, ':-`*`' ) then
result := seq( procname( i, args[2..-1] ), i = x );

`*`( result );
elif type( x, ':-`+`' ) then
result := seq( procname( i, args[2..-1] ), i = x );

`+`( result );
elif type( x, ':-`^`' ) then
result := seq( procname( i, args[2..-1] ), i = x );

`^`( result );
elif type( x, 'function' ) then
evalr( :-eval( op( 0, x ), y )( seq( procname( i, args[2..-1] ), i = x ) ) );
else
map( procname, x, args[2..-1] );
end if;
end proc;

for i in [
ln, exp,
sin, cos, tan, sec, csc, cot,
arcsin, arccos, arctan, arcsec, arccsc, arccot,
sinh, cosh, tanh, sech, csch, coth,
arcsinh, arccosh, arctanh, arcsech, arccsch, arccoth
] do
assign( i = FromInert(
_Inert_PROC(
_Inert_PARAMSEQ( _Inert_NAME("x") ),
_Inert_LOCALSEQ(),
_Inert_OPTIONSEQ(),
_Inert_EXPSEQ(),
_Inert_STATSEQ(
_Inert_FUNCTION(
_Inert_NAME("evalr"),
_Inert_EXPSEQ(
_Inert_FUNCTION(
_Inert_MEMBER(
_Inert_EXPSEQ(),
_Inert_NAME(convert(i, 'string'))
),
_Inert_EXPSEQ(
_Inert_PARAM(1)
)
)
)
)
),
_Inert_DESCRIPTIONSEQ(),
_Inert_GLOBALSEQ(),
_Inert_LEXICALSEQ()
)
) );
end do;

signum := proc(x)
local result;

if nargs = 1 then
result := evalr( Signum( x ) );

if result = FAIL then
undefined;
else
result;
end if;
else
error "not yet implemented";
end if;
end proc;
end module:

> with(INTERVALs);

```Warning, these protected names have been redefined and unprotected: *, +, -, /, ^, arccos, arccosh, arccot, arccoth, arccsc, arccsch, arcsec, arcsech, arcsin, arcsinh, arctan, arctanh, cos, cosh, cot, coth, csc, csch, eval, exp, ln, sec, sech, signum, sin, sinh, tan, tanh
```

Subtraction Problem: INTERVAL(1..2) - INTERVAL(1..2) = 0

> INTERVAL(1..2) - INTERVAL(1..2);

> eval( a - b, [a = INTERVAL(1..2), b = INTERVAL(1..2)] );

Division Problem: INTERVAL(1..2) / INTERVAL(1..2) = 1

> INTERVAL(1..2) / INTERVAL(1..2);

> eval( a / b, [a = INTERVAL(1..2), b = INTERVAL(1..2)] );

Problems Which Exist Despite this Package

You must either assign names beforehand, or you must use the eval command. The following shows how assigning an expression to a name and then re-evaluating that expressions results in unexpected output.

> c := a - b;

> d := a / b;

> a := INTERVAL(1..2);

> b := INTERVAL(1..2);

> c;

> d;

> a - b;

> a / d;

Functions

> sin(INTERVAL(1..2));

> signum(INTERVAL(1..3));

In the case of taking a signum of an interval which crosses , instead of is returned.

> signum(INTERVAL(-1..3));

>