Showing posts with label Programming (AMPL). Show all posts
Showing posts with label Programming (AMPL). Show all posts

Sunday, October 5, 2008

AMPL/BONMIN (Linux/Ubuntu)

IMPORTANT LINKS FOR BONMIN

Below are the websites which are helpful in explaining how to download/install BONMIN in a linux box:
  • (getting started) https://projects.coin-or.org/Bonmin/wiki/GettingStarted
  • https://projects.coin-or.org/BuildTools/wiki/downloadUnix
The latest version of BONMIN can be downloaded from
  • http://www.coin-or.org/download/source/Bonmin/
CAUTION

Although, it's claimed that BONMIN is tested with "gcc version 3.* and 4.* up to 4.3", I encountered a compiler/linker error:
ERROR: ....rodata' defined in discarded section `.gnu.linkonce...
I've been using gcc-3.4.6. After googling, I found that it's because of a bug which is fixed in gcc-4.*. After switching to gcc-4.0, the error is gone.

SUMMARY

After downloading and untarring the BONMIN file, the main directory contains all the necessary tools (e.g., Bonmin, IpOpt, Cbc, CoinUtils, etc.). However, some 3rd party programs which are required for installation and run are not included (because of licencing issues).

The directories, however, for these 3rd party programs are already available:
.../Bonmin-0.100.2/ThirdParty
  • HSL
  • Blas
  • Lapack
  • ASL
You only need to download the source codes into the corresponding directories:
- Fill in "Registration Form". You don't need to activate your membership! After acquiring the username/passwd just go ahead!
- In the "Package(s) Required'' part, enter 'MA27'.
- Login the "HSL Archieve" with the acquired username and password.
- You will need the double precision versions of the MA27 (you don't need to download the dependencies such as ID05 and ZA02), MC19. In the HSL directory, you should save to files named ma27ad.f and mc19ad.f respectively.
Finally, create a new director called "build" under the main directory:
  • mkdir .../Bonmin-0.100.2/build
And, within the "build", execute the following commands
  1. ../configure -C
  2. make
  3. make test
  4. make install
"make install" will create the below directories under "build":
  • bin
  • lib
  • share
  • include
"bin" contains the executable "bonmin" and the solvers it uses: Cbc, Clp, and Ipopt. "lib" contains the neccesary libarary files for "bonmin" to run.

Create a symbolic link named "bonmin" (which points at .../Bonmin-0.100.2/build/bin/bonmin) under the directory where "ampl" executable resides so that ampl can use BONMIN as a solver.

AMPL/Linux - Setting Environment Variables

If your PATH environment variable doesn't contain the path to the solvers, AMPL complains that it couldn't find the solver:
ampl: option solver minos;
ampl: solve;
Cannot invoke minos: No such file or directory
exit code 4
You need to add the path to the solver executables in the PATH:
export PATH="$PATH":/home/user/.../Solvers
Similarly, if your model contains an external function you need to set the environment variable AMPLFUNC. It should be pointing at the shared object file (i.e., amplfunc.so), or the directory which contains this file.
export AMPLFUNC=/home/user/.../AMPL/amplfunc.so

Wednesday, July 30, 2008

How to Import User-Defined Functions to AMPL?

AMPL is a mathematical programming language for describing optimization problems. There are quite a number of solvers that accept AMPL model as input. It's a powerful language but sometimes you may need to have your own function to include in your AMPL model. Just to note, if your model includes a user-defined function, it's not possible to use NEOS solvers.

NETLIB provides some explanation on how to import user-defined functions to AMPL but I found the related information rather scattered. Here, I'll try to walk through the process of importing a very simple user-defined function.

First of all, user-defined functions are imported to AMPL through "amplfunc.dll" shared library. If this file exists then AMPL loads the defined functions. AMPL looks for this dll file in the execution directory and the directory (or file) given as a command-line option using "-i".

The same shared library makes user defined functions availbale both to AMPL and to solvers. If AMPL finds a shared-library, it sets the $AMPLFUNC environment variable to inform the linked solvers.

A function can be in one of the 3 categories: deterministic, symbolic (string) and random. Since solvers directly igonore functions returnming strings and non-deterministic functions I'll write a deterministic function.

Below is a very simple function which sums up the given two arguments and sends back the result:

  1. You need to download the header file from Netlib which inlcudes necessary definitions; for example, the defition of the structure "struct arglist" is found in this header file. You'll include it in your c program.

  2. Then, you'll begin to code your function; note that you may have more than 1 function to import. In Visual C/C++, you need to explicilty export the function you want to use in AMPL:

    http://msdn.microsoft.com/en-us/library/ms235636%28VS.80%29.aspx

    __declspec(dllexport) real foo(arglist *al){

    /* the return type is real, which is nothing but a double: see the definition in header file you downloaded */

    /* Now, you'll get the arguments passed by AMPL */

    real arg1 = al->ra[0];
    real arg2 = al->ra[1];

    /* return the result */
    return (arg1+arg2);

    }

  3. Another function you have to export is "funcadd". It'll be used by AMPL to get the information about the user-defined function(s), in this case it's just foo.

    __declspec(dllexport) void funcadd(AmplExports *ae){

    /* 1st param: name of the function to import to AMPL.
    2nd param: pointer to the function "foo"
    3rd param: function type...you can get more info from the header file by checking enumarated type FUNCADD_TYPE.
    4th param: Number of arguments passed to function "foo".
    5th param: funcinfo
    */
    addfunc("foo", (rfunc)foo, 0, 2, 0);
    }

    Again, NETLIB includes a more complicated sample: funcadd.c .

  4. After creating dll, you can name it "amplfunc.dll" and copy it under the execution directory of AMPL.

  5. Lastly, you have to declare the function in your model before using it:

    ....
    function foo;
    ...
    subject to X: ... foo(param1, var1)...;