# Introduction

Getting started

The aim of this section is to give you a quick feel for the effort
required to make a link to an external function or procedure through a
short illustrative example linking a `C`

implementation of the
Cobb-Douglas function (discussed in Example: the Cobb-Douglas function) into an
AIMMS application. Introduction contains a more elaborate
example of an external procedure which uses AIMMS API functions to
obtain additional information about the passed arguments.

External procedures and functions

The interface to external procedures and functions is arranged through
special `ExternalProcedure`

and `ExternalFunction`

declarations
which behave just like internal procedures and functions. Instead of
specifying a body to initiate internal AIMMS computations, the execution
of external procedures and functions is relayed to the indicated
procedures and functions inside one or more DLL’s.

The Cobb-Douglas function

Consider the `Cobb-Douglas`

function discussed in
Example: the Cobb-Douglas function. Given the cardinality `n`

of the set
`InputFactors`

and two arrays `a`

and `c`

of doubles representing
the one-dimensional input arguments of the Cobb-Douglas function (both
defined over `InputFactors`

), the following simple `C`

function
computes its value.

```
double Cobb_Douglas( int n, double *a, double *c ) {
int i;
double CD = 1.0 ;
for ( i = 0; i < n; i++ )
CD = CD * pow(c[i],a[i]) ;
return CD;
}
```

In the sequel it is assumed that this function is contained in a DLL
named `"Userfunc.dll"`

.

Linking to AIMMS

In order to make the function available in AIMMS you have to declare an
`ExternalFunction`

`CobbDouglasExternal`

, which just relays its
execution to the `C`

implementation of the Cobb-Douglas function
discussed above. The declaration of `CobbDouglasExternal`

looks as
follows.

```
ExternalFunction CobbDouglasExternal {
Arguments : (a,c);
Range : nonnegative;
DLLName : "Userfunc.dll";
ReturnType : double;
BodyCall : Cobb_Douglas( card : InputFactors, array: a, array: c );
}
```

The arguments `a`

and `c`

must be declared in the same way as for
the internal `CobbDouglas`

function discussed on
Example: the Cobb-Douglas function, with the exception that for the external
implementation we will also compute the Jacobian with respect to the
argument `c(f)`

. For this reason, the argument `c(f)`

is declared as
a `Variable`

.

```
Set InputFactors {
Index : f;
}
Parameter a {
IndexDomain : f;
}
Variable c {
IndexDomain : f;
}
```

Explanation

The translation type `card`

of the set argument `InputFactors`

causes AIMMS to pass the cardinality of the set as an integer value to
the external function `Cobb_Douglas`

. The translation type `array`

of the arguments `a`

and `c`

are instructions to AIMMS to pass these
arguments as full arrays of double precision values. As function
arguments are always of type `Input`

, AIMMS will disregard any changes
made to the arguments by the external function. The `double`

return
value of the `C`

function `Cobb_Douglas`

will become the result of
the function `CobbDouglasExternal`

.

Calling external functions

After the declaration of an external function or procedure you can use
it as if it were an internal function or procedure. Thus, to call the
external function `CobbDouglasExternal`

in the body of a procedure the
following statement suffices.

```
CobbDouglasValue := CobbDouglasExternal(a,c) ;
```

Of course, any two (possibly sliced) identifiers with single common index domain could have been used as arguments. AIMMS will determine this common index domain, and pass its cardinality to the external function.

Use in constraints

Unlike internal functions, external functions can be called inside
constraints. To accomplish this, the declaration has to be extended with
a `DerivativeCall`

attribute. For this attribute you specify the
external call that has to be made when AIMMS also needs the partial
derivatives of all variable arguments inside constraints of mathematical
programs. In the absence of a `DerivativeCall`

attribute, AIMMS will
use a differencing scheme to estimate these derivatives. The details of
using external functions in constraints, as well as the obvious
extension to compute the derivative of the Cobb-Douglas function
directly, are given in External Functions in Constraints.

Setting up external libraries

Once you have developed a collection of external functions and procedures, it may be a good idea to make this available in the form of a library for use in AIMMS applications. In this way, the users of your library do not have to spend any time translating their AIMMS arguments into external arguments of the appropriate type in the external procedure and function declarations.

Save library as include file

To provide a library as an entity on its own, you can store all the external procedures and functions in a separate model section, and save this section as a source file. The functions and procedures in the library can then be made available by simply including this source file into a model.

Hiding the interface

When you want to protect the interface to your external library, you can accomplish this by encrypting the include file containing the function library. Thus, the interface to the external library becomes invisible, effectively preventing misuse of the library outside AIMMS.