Code Monkey home page Code Monkey logo

glpkerl's Introduction

Introduction

This project provides an Erlang interface to GLPK.

You probably know what GLPK is, otherwise, you wouldn't have much interest in the project.

Hello World!

In case you don't want to read all the mumbo jumbo, here's an example first solving

  min x
  0 <= x <= 100

and then

  max x
  0 <= x <= 100
% erl
Erlang (BEAM) emulator version 5.6.5 [source] [async-threads:0] [kernel-poll:fal
se]

Eshell V5.6.5  (abort with ^G)
1> glpkerl:start ().
ok
2> { ok, Lp } = glpkerl:new ().
{ok,{glpk,#Port<0.721>,false,32,64}}
3> 1 = glpkerl:add_rows (Lp, 1).
1
4> ok = glpkerl:set_row_bnds (Lp, 1, glp_up, 0, 100).
ok
5> 1 = glpkerl:add_cols (Lp, 1).
1
6> ok = glpkerl:set_col_bnds (Lp, 1, glp_lo, 0, 0).
ok
7> ok = glpkerl:set_obj_coef (Lp, 1, 1.0).
ok
8> ok = glpkerl:load_matrix (Lp, 1, [ 1 ], [ 1 ], [ 1 ]).
ok
9> glp_success = glpkerl:simplex (Lp, []).
*     0: obj =   0.000000000e+00  infeas =  0.000e+00 (0)
                                                         OPTIMAL SOLUTION FOUND
                                                                               g
lp_success
10> ok = glpkerl:set_obj_dir (Lp, glp_max).
ok
11> glp_success = glpkerl:simplex (Lp, []).
*     0: obj =   0.000000000e+00  infeas =  0.000e+00 (0)
                                                         *     1: obj =   1.0000
00000e+02  infeas =  0.000e+00 (0)
                                  OPTIMAL SOLUTION FOUND
                                                        glp_success
12>
User switch command
 --> q

Port vs. Linked-In

In Erlang you have the choice between a port (forked program communicating over a socketpair) or a linked-in driver (dynamically loaded library residing in Erlang VM's address space).

Generally linked-in drivers are dangerous because they can destabilize the VM, but are sometimes used because they offer lower latency. Since solving a linear program is a very heavyweight operation, the latency of talking over a pipe is probably moot. Furthermore, it's very easy to shut down a subprocess without blocking the Erlang VM, whereas a linked-in driver with a thread that is doing a long running computation can potentially block the Erlang VM if the port_close method is invoked during the long running computation (which could happen if the port owner dies after initiating a large linear program solve).

For these reasons the default mode of operation is port. You can select linked-in driver when constructing a handle, but it's probably a bad idea. (Really, the only reason it is there is because I have a way to convert a linked-in driver to a port, so I always write the linked-in driver first).

Calling Conventions

Much of the software is this package is auto-generated, and therefore the interface is a near-literal translation of the C api, with the following conventions:

Return Types

Any method can return { error, Reason }, which indicates an error not associated with a GLPK return value. except for the port dying, this generally means an internal_error in the driver (i.e., software defect by me!).

In addition each method can return a value which depends upon the return value of the associated glpk method. This value is never an Erlang tuple so you can distinguish it from the error case.

|| C return type || Erlang type || || void || 'ok' || || int || integer () || || enumeration || 'lowercase_first_enum_val' | 'lowercase_second_enum_val' ... || || double || float () ||

With respect to enumerations, basically an enum on the C side is associated with a sum of atoms type on the Erlang side, with lowercasing for convenience. So something like the return type for glp_get_prim_stat, which is (essentially) declared as

enum
{
GLP_UNDEF,
GLP_FEAS,
GLP_INFEAS,
GLP_NOFEAS
}

would be the Erlang type

'glp_undef' | 'glp_feas' | 'glp_infeas' | 'glp_nofeas'

Also some methods, e.g. glp_simplex, return 0 to indicate success but otherwise an enumeration. I define this as 'glp_success'.

The interface file (glpkerl.erl) generates proper EDoc and dialyzer type signatures so hopefully it is clear what is going on.

Argument Types

For each mapped GLPK function, the argument types are mapped to Erlang as follows:

|| C argument type || Erlang type ||
|| glp_prob* || implicit: contained in the glpkerl instance ||
|| int || integer () ||
|| double || number () ||
|| const int* || list (integer ()) ||
|| const double* || list (number ()) ||
|| enumeration || 'lowercase_first_enum_val' | 'lowercase_second_enum_val' ... ||
|| const struct X* || proplist () ||

With respect to enumerations, basically an enum on the C side is associated with a sum of atoms type on the Erlang side, with lowercasing for convenience. So for instance the msg_level parameter would be ( 'glp_msg_off' | 'glp_msg_err' | 'glp_msg_on' | 'glp_msg_all' ).

With respect to (pointers to) structures, I map these to proplists where the keys are atoms corresponding to the member names of the structure. So a call to glp_simplex might look like

  { ok, Lp } = glpkerl:new (),
  ...
  glp_success = glpkerl:simplex (Lp, [ { msg_level, 'glp_msg_off' } ]),

Installation

Introduction

Do NOT attempt to build from a checkout from the source code repository: that is for wizards only. Instead, grab one of the released source tarballs from the downloads tab.

This page will assist you in installing glpkerl.[[#2 2]]

Prerequisites:

  1. gnu make
  2. working glpk 4.38 installation
    • debian: aptitude install libglpk-dev=4.38-1
    • others: ??? please let me know what worked
  3. working erlang installation.
    • debian: aptitude install erlang-dev
    • os/x (with [http://www.finkproject.org/ fink]): apt-get install erlang-otp
    • freebsd: pkg_add -r erlang
    • others: ??? please let me know what worked

Go to the downloads section and grab the latest .tar.gz files: one C driver tarball, and one Erlang tarball.

C driver

# tar -zxf glpkerldrv-4.38.0.tar.gz
# cd glpkerldrv-4.38.0
# ./configure --prefix /usr/local && make && make -s check
...

The default prefix is /usr so if you are ok with that you can omit the prefix argument.

If you get compile warnings that are being interpreted as errors, drop me a line about it because I'd like to fix it, and then workaround it with the --disable-hardcore flag to configure:

# ./configure --prefix /usr/local --disable-hardcore && make && make -s check

Now you can make install, or if you have another way of managing stuff on your system, you can make DESTDIR=/whatever install and then manipulate the contents of /whatever.

Erlang source code

You'll need the C driver built and installed first.

# tar -zxf glpkerl-4.38.0.tar.gz
# cd glpkerl-4.38.0
# ./configure --prefix /usr/local && make && make -s check

Hopefully what you see[[#1 1]] is something like

PASS: module-testglpkerl
==================
All 1 tests passed
==================

There are a couple ways this could go wrong.

One way this could go wrong is because the Erlang build process cannot find the driver specification. The Erlang source code (and the linked-in driver) are generated automatically from a specification glpkerldrvspec.pm and the Erlang build process uses pkg-config to find the installed specification. Thus, if the .pc file for the C driver is not in the path for pkg-config, the build process will fail. Modifying the environment variable PKG_CONFIG_PATH might assist with this problem.

You could also inspect the test output, which for test-FOO is in tests/test-FOO.out; perhaps it is informative.

Now you can make install, or if you have another way of managing stuff on your system, you can make DESTDIR=/whatever install and then manipulate the contents of /whatever.

Footnotes

== 1 == If you see something like:

fw requires GNU make to build, you are using bsd make
*** Error code 1

Stop.

Then you are using bsd make which will not work. Try again with gnu make, e.g.,

./configure --prefix /usr/local && gmake && gmake -s check

== 2 ==

Downloadable source tarballs use automake to build. A source code checkout of the repository uses fwtemplates to build, and if you don't know what that is, you probably want to stick with the tarballs.

glpkerl's People

Contributors

pinx avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.