# Setting Up External Functions to Be Called from *Mathematica*

If you have a function defined in an external program, then what you need to do in order to make it possible to call the function from within *Mathematica* is to add appropriate *MathLink* code that passes arguments to the function, and takes back the results it produces.

In simple cases, you can generate the necessary code just by giving an appropriate *MathLink* template for each external function.

:Begin:

:Function: f

:Pattern: f[x_Integer, y_Integer]

:Arguments: {x, y}

:ArgumentTypes: {Integer, Integer}

:ReturnType: Integer

:End:

A file f.tm containing a *MathLink* template for an external function f.

:Begin: | begin the template for a particular function |

:Function: | the name of the function in the external program |

:Pattern: | the pattern to be defined to call the function |

:Arguments: | the arguments to the function |

:ArgumentTypes: | the types of the arguments to the function |

:ReturnType: | the type of the value returned by the function |

:End: | end the template for a particular function |

:Evaluate: | Mathematica input to evaluate when the function is installed |

The elements of a *MathLink* template.

Once you have constructed a *MathLink* template for a particular external function, you have to combine this template with the actual source code for the function. Assuming that the source code is written in the C programming language, you can do this just by adding a line to include the standard *MathLink* header file, and then inserting a small main program.

#include "mathlink.h"

int f(int x, int y) {

return x+y;

}

int main(int argc, char *argv[]) {

return MLMain(argc, argv);

}

A file f.c containing C source code.

Note that the form of main required on different systems may be slightly different. The release notes included in the *MathLink* Developer Kit on your particular computer system should give the appropriate form.

Typical external programs for processing *MathLink* source files.

*MathLink* templates are conventionally put in files with names of the form file.tm. Such files can also contain C source code, interspersed between templates for different functions.

Once you have set up the appropriate files, you then need to process the *MathLink* template information, and compile all of your source code. Typically you do this by running various external programs, but the details will depend on your computer system.

Under Unix, for example, the *MathLink* Developer Kit includes a program named mcc that will preprocess *MathLink* templates in any file whose name ends with .tm, and then call cc on the resulting C source code. mcc will pass command-line options and other files directly to cc.

mcc -o f.exe f.tm f.c

In[1]:= |

Out[1]= |

In[2]:= |

Out[2]= |

In[3]:= |

Out[3]= |

On Windows, the *MathLink* Developer Kit includes a program named mprep, which you have to call directly, giving as input all of the .tm files that you want to preprocess. mprep will generate C source code as output, which you can then feed to a C compiler.

Install["prog"] | install an external program |

Uninstall[link] | uninstall an external program |

Links["prog"] | show active links associated with |

Links[] | show all active links |

LinkPatterns[link] | show patterns that can be evaluated on a particular link |

Handling links to external programs.

In[4]:= |

Out[4]= |

In[5]:= |

Out[5]= |

When a *MathLink* template file is processed, two basic things are done. First, the :Pattern: and specifications are used to generate a *Mathematica* definition that calls an external function via *MathLink*. And second, the :Function:, and specifications are used to generate C source code that calls your function within the external program.

:Begin:

:Function: prog_add

:Pattern: SkewAdd[x_Integer, y_Integer:1]

:Arguments: {x, If[x > 1, y, y + x - 2]}

:ArgumentTypes: {Integer, Integer}

:ReturnType: Integer

:End:

Both the :Pattern: and specifications in a *MathLink* template can be any *Mathematica* expressions. Whatever you give as the specification will be evaluated every time you call the external function. The result of the evaluation will be used as the list of arguments to pass to the function.

Sometimes you may want to set up *Mathematica* expressions that should be evaluated not when an external function is called, but instead only when the external function is first installed.

You can do this by inserting :Evaluate: specifications in your *MathLink* template. The expression you give after :Evaluate: can go on for several lines: it is assumed to end when there is first a blank line, or a line that does not begin with spaces or tabs.

:Evaluate: SkewAdd::usage = "SkewAdd[x, y] performs

a skew addition in an external program."

When an external program is installed, the specifications in its *MathLink* template file are used in the order they were given. This means that any expressions given in :Evaluate: specifications that appear before :Begin: will have been evaluated before definitions for the external function are set up.

*Mathematica*expressions to be evaluated before the definitions for external functions are set up.

:Evaluate: BeginPackage["XPack`"]

:Evaluate: XF1::usage = "XF1[x, y] is one external function."

:Evaluate: XF2::usage = "XF2[x] is another external function."

:Evaluate: Begin["`Private`"]

*Mathematica*should be set up to call the function f in the external C program.

:Begin:

:Function: f

:Pattern: XF1[x_Integer, y_Integer]

:Arguments: {x, y}

:ArgumentTypes: {Integer, Integer}

:ReturnType: Integer

:End:

*Mathematica*should call g. Its argument and return value are taken to be approximate real numbers.

:Begin:

:Function: g

:Pattern: XF2[x_?NumberQ]

:Arguments: {x}

:ArgumentTypes: {Real}

:ReturnType: Real

:End:

*Mathematica*expressions are evaluated after the definitions for the external functions. They end the special context used for the definitions.

:Evaluate: End[ ]

:Evaluate: EndPackage[ ]

*Mathematica*counterparts.

int f(int i, int j) {

return i + j;

}

*Mathematica*will automatically be converted into C double types before being passed to g.

double g(double x) {

return x*x;

}

By using :Evaluate: specifications, you can evaluate *Mathematica* expressions when an external program is first installed. You can also execute code inside the external program at this time simply by inserting the code in main() before the call to MLMain(). This is sometimes useful if you need to initialize the external program before any functions in it are used.

MLEvaluateString(stdlink,"string") | evaluate a string as Mathematica input |

Executing a command in *Mathematica* from within an external program.

int diff(int i, int j) {

if (i < j) MLEvaluateString(stdlink, "Print[\"negative\"]");

return i - j;

}

In[7]:= |

Out[7]= |

Note that any results generated in the evaluation requested by MLEvaluateString() are ignored. To make use of such results requires full two-way communication between *Mathematica* and external programs, as discussed in "Two-Way Communication with External Programs".