A simple bridge between AMPL and Python allowing users to define external functions in Python and use those functions inside AMPL models.
This example bridge is used to define a parametric curve in Python, to be used in the AMPL model. It should generalize easily to other cases.
You may simply install the ASL by hand or use Homebrew:
brew install python --universal
brew tap homebrew/science
brew install asl
make [DEBUG=1] # Should output config options and create amplfunc.dll
There are no Python prerequisites to run the simple example supplied. You need an AMPL engine (the student version will do for this small example). AMPL comes pre-packaged with the MINOS solver. Unfortunately, MINOS doesn't seem to find a solution of this particular problem. In the example, I used SNOPT. You can download a student version of SNOPT from the AMPL website.
If you want to run plot.py
and check the results for yourself, you'll need Numpy and Matplotlib. Installing them is easy:
brew install matplotlib
If you don't use brew
, you can install them with pip
, but you might have to install some dependencies by hand:
easy_install pip
pip install numpy
pip install matplotlib
We're now ready to run the AMPL script curve.ampl
. This script does a few things:
- it defines external functions that initialize and finalize the Python interpreter, and point to our Python functions
- it loads the model
curve.mod
and datacurve.dat
- it solves the problem with
snopt
- it writes the solution to file in
x.dat
andy.dat
.
The problem described in curve.mod
consists in finding 25 points on a spiral curve that are equidistant. Here, equidistant means relative to the Euclidian distance, not to the curvilinear distance. The problem and solution process are described in these proceedings, pages 41-58. Running it is straightforward:
ampl curve.ampl
You should see output similar to
SNOPT 7.2-5 : Optimal solution found.
10 iterations, objective 8.913330871
Nonlin evals: obj = 8, grad = 7, constrs = 8, Jac = 7.
This produces x.dat
and y.dat
. Running
python plot.py
should produce a plot similar to
Alternatively, you could use Gnuplot (brew install gnuplot
).
It's probably a good idea to scan the official documentation on how to define external functions in AMPL models.
Most of the magic happens in
funcadd.c
.