funcs4.gms : Rules for getting derivs/intervals of intrinsics

Description

```In this model we test the syntax and symantics for getting the
derivatives and intervals for the GAMS intrinsic functions

For a given function func, GAMS has always allowed its use as:

f = func(x)

We can now test the derivatives and intervals that are defined
along with function func using GAMS syntax (new with Rev 139):

d2f = func.hess(x)   - Hessian of func
d2f = func.hessn(x)      - Hessian of func, computed numerically
L = func.low(xlo:xup)  - lower bound for func(x) on [xlo,xup]
H = func.high(xlo:xup)  - upper bound for func(x) on [xlo,xup]

An extended syntax from that above allows for multivariate functions
and is illustrated below.

Contributor: Steven Dirkse, July 2004

the following requires at least version 139
```

Small Model of Type : GAMS

Category : GAMS Test library

Main file : funcs4.gms

``````\$title rules for getting derivs/intervals of intrinsics (FUNCS4,SEQ=148)

\$ontext
In this model we test the syntax and symantics for getting the
derivatives and intervals for the GAMS intrinsic functions

For a given function func, GAMS has always allowed its use as:

f = func(x)

We can now test the derivatives and intervals that are defined
along with function func using GAMS syntax (new with Rev 139):

d2f = func.hess(x)   - Hessian of func
d2f = func.hessn(x)      - Hessian of func, computed numerically
L = func.low(xlo:xup)  - lower bound for func(x) on [xlo,xup]
H = func.high(xlo:xup)  - upper bound for func(x) on [xlo,xup]

An extended syntax from that above allows for multivariate functions
and is illustrated below.

Contributor: Steven Dirkse, July 2004
\$offtext

* the following requires at least version 139
\$version 139

Set i / i1 * i6 /;
Set j / j1 * j6 /;

* first check using a scalar function

* set delta for computing gradients numerically
* this is a better value than the default for exp(x)
option FDDelta=1e-4;

\$onundf
scalar undef / UNDF /;
\$offundf
scalar ntol / 1e-8 /;
scalar x, f, df, d2f, L, H, gL, gH;

x = 0;
f = exp(x);              abort\$(  f ne 1) 'should get 1';
df = exp.grad(1:x);       abort\$( df ne 1) 'should get 1';
df = exp.gradn(1:x);      abort\$(abs(df-1) gt ntol) 'should get near 1';
d2f = exp.hess(1:1:x);     abort\$(d2f ne 1) 'should get 1';
d2f = exp.hessn(1:1:x);    abort\$(abs(d2f-1)gt ntol) 'should get near 1';
L = exp.low(x:x+1);      abort\$(  L ne 1) 'should get 1';
H = exp.high(x-1:x);     abort\$(  H ne 1) 'should get 1';
gL = exp.gradl(1:x:x+1);  abort\$( gL ne 1) 'should get 1';
gH = exp.gradh(1:x-1:x);  abort\$( gH ne 1) 'should get 1';

\$ontext
set k / 1 * 16 /;
parameter dat(k,*);
scalar delta / 1 /;
loop {k,
delta = delta * .1;
option optcr = delta;
option FDDelta = delta;
dat(k,'delta') = delta;
dat(k,'df') = df;
dat(k,'dfm1') = df-1;
};
option decimals = 8;
option FDDelta = 1e-1;
dat('1','delta') = 1e-1;
df = exp.hessn(x);
dat('1','df') = df;
dat('1','dfm1') = df-1;

option FDDelta = 1e-2;
dat('2','delta') = 1e-2;
df = exp.hessn(x);
dat('2','df') = df;
dat('2','dfm1') = df-1;

option FDDelta = 1e-3;
dat('3','delta') = 1e-3;
df = exp.hessn(x);
dat('3','df') = df;
dat('3','dfm1') = df-1;

option FDDelta = 1e-4;
dat('4','delta') = 1e-4;
df = exp.hessn(x);
dat('4','df') = df;
dat('4','dfm1') = df-1;

option FDDelta = 1e-5;
dat('5','delta') = 1e-5;
df = exp.hessn(x);
dat('5','df') = df;
dat('5','dfm1') = df-1;

option FDDelta = 1e-6;
dat('6','delta') = 1e-6;
df = exp.hessn(x);
dat('6','df') = df;
dat('6','dfm1') = df-1;

option FDDelta = 1e-7;
dat('7','delta') = 1e-7;
df = exp.hessn(x);
dat('7','df') = df;
dat('7','dfm1') = df-1;

display dat;
\$offtext

* if no index list is given, 1's are assumed
df = exp.grad(x);         abort\$( df ne 1) 'should get 1';
df = exp.gradn(x);        abort\$(abs(df-1) gt ntol) 'should get near 1';
d2f = exp.hess(x);         abort\$(d2f ne 1) 'should get 1';
d2f = exp.hessn(x);        abort\$(abs(d2f-1)gt ntol) 'should get near 1';
d2f = exp.hess(1:x);       abort\$(d2f ne 1) 'should get 1';
d2f = exp.hessn(1:x);      abort\$(abs(d2f-1)gt ntol) 'should get near 1';
gL = exp.gradl(x:x+1);    abort\$( gL ne 1) 'should get 1';
gH = exp.gradh(x-1:x);    abort\$( gH ne 1) 'should get 1';

* if index list values are out of range, 0 is returned sometimes
* and sometimes, UNDF is returned
df = exp.grad(-1:x);      abort\$( df ne 0) 'should get 0';
df = exp.gradn(0:x);      abort\$( df ne 0) 'should get 0';
df = exp.gradn(2:x);      abort\$( df ne 0) 'should get 0';
df = exp.gradn(INF:x);    abort\$( df ne 0) 'should get 0';
d2f = exp.hess(1:0:x);     abort\$(d2f ne 0) 'should get 0';
d2f = exp.hessn(0:1:x);    abort\$(d2f ne 0) 'should get 0';
gH = exp.gradh(INF:x-1:x);abort\$( gH ne undef) 'should get UNDF';
gL = exp.gradl(NA:x:x+1); abort\$( gL ne undef) 'should get UNDF';

* EPS works like 0, for funcs & derivs & ranges
x = EPS;
f = exp(x);              abort\$(  f ne 1) 'should get 1';
df = exp.grad(1:x);       abort\$( df ne 1) 'should get 1';
df = exp.gradn(1:x);      abort\$(abs(df-1) gt ntol) 'should get near 1';
d2f = exp.hess(1:1:x);     abort\$(d2f ne 1) 'should get 1';
d2f = exp.hessn(1:1:x);    abort\$(abs(d2f-1)gt ntol) 'should get near 1';
L = exp.low(x:x+1);      abort\$(  L ne 1) 'should get 1';
H = exp.high(x-1:x);     abort\$(  H ne 1) 'should get 1';
gL = exp.gradl(1:x:x+1);  abort\$( gL ne 1) 'should get 1';
gH = exp.gradh(1:x-1:x);  abort\$( gH ne 1) 'should get 1';

* do some tests with non-EPS special values
x = NA;

* function vals work one way - they take special vals as input
f = exp(x);              abort\$(f ne NA) 'should get NA';

* derivatives do not work like the functions vis-a-vis special vals
* if special values are used as input, we get execution errors
abort\$(execerror>0) 'no previous errors expected';
df = exp.grad(x);  abort\$(execerror=0) 'execErrorExpected'; execerror = 0;
df = exp.gradn(x); abort\$(execerror=0) 'execErrorExpected'; execerror = 0;
d2f = exp.hess(x);  abort\$(execerror=0) 'execErrorExpected'; execerror = 0;
d2f = exp.hessn(x); abort\$(execerror=0) 'execErrorExpected'; execerror = 0;
L = exp.low(x:x+1);  abort\$(execerror=0) 'execErrorExpected'; execerror = 0;
H = exp.high(x-1:x); abort\$(execerror=0) 'execErrorExpected'; execerror = 0;
gL = exp.gradl(x:x+1); abort\$(execerror=0) 'execErrorExpected'; execerror = 0;
gH = exp.gradh(x-1:x); abort\$(execerror=0) 'execErrorExpected'; execerror = 0;
``````
GAMS Development Corp.
GAMS Software GmbH

General Information and Sales
U.S. (+1) 202 342-0180
Europe: (+49) 221 949-9170