A Wolfram Mathematica neosAPI package

The neosAPI package allows the access to the NEOS server directly within Wolfram Mathematica.

Prerequisites

The package requires a working installation of Wolfram Mathematica and of the xmlRPC package.

Install instructions

The software is available on GitHub, and is installed as follows.

  1. Clone the neosAPI repository locally.
  2. Copy the file neosAPI.m according to the following table, depending on the operating system you use and your preference for a user-based or a system-wide installation.
    OS User-based installation System-wide installation
    Mac OS X ~/Library/Mathematica/Applications /Library/Mathematica/Applications
    Linux ~/.Mathematica/Applications R/AddOns/Applications
    Windows ~/Applications Data/Mathematica/Applications R/AddOns/Applications
    In the table ~ denotes the user's home directory in Mac OS X and Linux and the user's directory inside Documents and Settings in Windows, while R denotes the Mathematica root directory.
    Note If you like the non-standard way, saving the package file in any directory contained in Mathematica's $Path variable will also work.
  3. Read the user manual notebook neosAPI-usage.nb.

Using the package

The package is loaded as follows:

In[1]:= <<neosAPI`

The functions neosVersion and neosPing can be used in order to check that the server is running:

In[2]:= neosVersion[]
Out[2]= neos version 5 (Madison)
In[3]:= neosPing[]
Out[3]= NeosServer is alive

The server load can be checked using neosPrintQueue:

In[4]:= neosPrintQueue[]
Out[4]= Running:
job# 555551  0.02X  0.02XX    0.02X  submitted  MM/DD HH:MM started  MM/DD HH:MM on domain.name.tld  
job# 555552  0.02X  0.02XX    0.02X  submitted  MM/DD HH:MM started  MM/DD HH:MM on domain.name.tld  
job# 555553  0.02X  0.02XX    0.02X  submitted  MM/DD HH:MM started  MM/DD HH:MM on domain.name.tld  
job# 555554  0.02X  0.02XX    0.02X  submitted  MM/DD HH:MM started  MM/DD HH:MM on domain.name.tld  
job# 555555  0.02X  0.02XX    0.02X  submitted  MM/DD HH:MM started  MM/DD HH:MM on domain.name.tld  
 
Queued:
No Jobs in Queue.

The output (with fake data in this example) shows a line per job, listing job number, category, user name, input method, submit date, execution date and server address.

A job is submitted encoding its description in the chosen modeling language using the corresponding XML format. More information on this can be found on the NEOS solvers page, selecting the used solver and then following the «XML-RPC» link on the upper-right part of the shown page. For instance the following string encodes in AMPL the simple problem of learning the binary OR function through a linear support vector machine:

In[5]:= request="<document>
<category>nco</category>
<solver>SNOPT</solver>
<inputMethod>AMPL</inputMethod>
<model><![CDATA[

param m integer > 0 default 4; # number of sample points
param n integer > 0 default 2; # sample space dimension

param x {1..m,1..n}; # sample points
param y {1..m}; # sample labels
param dot{i in 1..m,j in 1..m}:=sum{k in 1..n}(x[i,k]*x[j,k]);

var alpha{1..m}>=0;
var w{1..n};

maximize quadratic_form:
sum{i in 1..m} alpha[i]
-1/2*sum{i in 1..m,j in 1..m}alpha[i]*alpha[j]*y[i]*y[j]*dot[i,j];

subject to linear_constraint:
sum{i in 1..m} alpha[i]*y[i]=0;

subject to w_def{k in 1..n}:
w[k]=sum{i in 1..m} alpha[i]*y[i]*x[i,k];

]]></model>

<data><![CDATA[

data;

param   x:      1       2       :=
1       0    0
2       0    1
3       1    0
4       1    1     ;

param y :=
1       -1
2       1
3       1
4       1;

]]></data>

<commands><![CDATA[

option solver snopt;

solve;

printf: \"{{\";
printf {k in 1..n-1}:\"%f,\",w[k];
printf: \"%f},\",w[n];
printf: \"%f}\\n\",sum{i in 1..m:alpha[i]>0} (y[i]-sum{k in 1..n}w[k]*x[i,k])/sum{j in 1..m:alpha[j]>0} 1;

]]></commands>

</document>";

Once written, this description is submitted to the server through the neosSubmitJob function:

In[6]:= {jobNum, jobPwd} = neosSubmitJob[request]
Out[6]= {318165, jumqWRgF}

If no errors occurred, the function returns a list containing the assigned job number and a password, both to be used in order to pose queries for the submitted job. Otherwise, a string describing the error is returned. Typical queries concerns the job status retrieval, obtained through the function neosGetJobStatus, returning either Done, Running, Waiting, Unknown Job, or Bad Password:

In[7]:= neosGetJobStatus[jobNum,jobPwd]
Out[7]= Done

Once a job has been executed, its results are fetched through the function neosGetFinalResults:

In[8]:= res=neosGetFinalResults[jobNum,jobPwd]
Out[8]= Job 318165 sent to neos-4.chtc.wisc.edu
password: jumqWRgF
---------- Begin Solver Output -----------
Executing /opt/neos/Drivers/snopt-ampl/snopt-driver.py at time: 2012-10-09 19:55:43.936867
File exists
You are using the solver snopt.
Executing AMPL.
processing data.
processing commands.

6 variables:
	3 nonlinear variables
	3 linear variables
3 constraints, all linear; 10 nonzeros
	3 equality constraints
1 nonlinear objective; 4 nonzeros.

SNOPT 7.2-10 : Optimal solution found.
2 iterations, objective 4
{{2.000000,2.000000},-1.000000}

Finally, the function neosSolveJob handles all the communication with the NEOS server, submitting a job and blocking until it completes, subsequently returning the results:

In[8]:= theResult=neosSolveJob[request]
Out[8]= Job 318262 sent to neos-4.chtc.wisc.edu
password: ZPVuIzvC
---------- Begin Solver Output -----------
Executing /opt/neos/Drivers/snopt-ampl/snopt-driver.py at time: 2012-10-09 19:55:52.992457
File exists
You are using the solver snopt.
Executing AMPL.
processing data.
processing commands.

6 variables:
	3 nonlinear variables
	3 linear variables
3 constraints, all linear; 10 nonzeros
	3 equality constraints
1 nonlinear objective; 4 nonzeros.

SNOPT 7.2-10 : Optimal solution found.
2 iterations, objective 4
{{2.000000,2.000000},-1.000000}

Of course, in order to actually process the obtained results it will be necessary to strip out the initial part of the output and possibly convert the remaining part:

In[9]:= StringReplace[theResult,___~~"{{"~~o__~~"}"~~___ -> "{{"~~o~~"}"]//ToExpression
Out[9]= {{1.11111, 1.11111},1.}

Advanced use

The package provides the Wolfram Mathematica analogous of the functions from the API specifications in the following table.

Wolfram Mathematica function Corresponding NEOS function
neosHelp help
neosEmailHelp emailHelp
neosWelcome welcome
neosVersion version
neosPing ping
neosPrintQueue printQueue
neosSubmitJob submitJob
neosGetJobStatus getJobStatus
neosGetFinalResults getFinalResults
neosGetJobInfo getJobInfo
neosKillJob killJob
neosGetIntermediateResults getIntermediateResults
neosListCategories listCategories
neosListAllSolvers listAllSolvers
neosListSolversInCategory listSolversInCategory
neosGetSolverTemplate getSolverTemplate
neosGetIntermediateResultsNonBlocking getIntermediateResultsNonBlocking
neosGetFinalResultsNonBlocking getFinalResultsNonBlocking

In addition, the function neosSolveJob is provided, which automatically places a job in the execution queue, waits for the server to execute it, and retrieves the results.

These functions are described in the documentation notebook neosAPI-usage.nb.

License

neosAPI is licensed uder the LGPL license.