Initializing help system before first use

Folio - remote execution of optimization models


Type: Portfolio optimization
Rating: 4 (medium-difficult)
Description: Various XPRD program versions running the memory I/O version of the 'Folio' portfolio optimization example form the 'Getting Started' guide.
  • runfoliodistr.[c|java] (requires: foliomemio.mos, folio10.dat): run an optimization model and retrieve detailed solution info, defining a file manager for data exchange in memory (XPRD version of runfoliodistr.mos)
  • distfolio.[c|java] (requires: foliomemio.mos, folio250.dat): run an optimization model and retrieve detailed solution info, reading binary solution files
  • distfoliopar.[c|java] (requires: foliomemio.mos, folio250.dat): run several optimization models on different remote Mosel instances and retrieve detailed solution info, reading binary solution files (XPRD version of runfoliopardistr.mos)
  • distfoliocbioev.[c|java] (requires: foliocbioev.mos, folio250.dat): retrieve solution info during optimization model run, coordination via events
File(s): runfoliodistr.c, runfoliodistr.java, foliomemio.mos, distfolio.c, distfolio.java, distfoliopar.c, distfoliopar.java, distfoliocbioev.c, distfoliocbioev.java, foliocbioev.mos
Data file(s): folio250.dat, folio10.dat

runfoliodistr.c
/*******************************************************
   Mosel Example Problems
   ====================== 

   file runfoliodistr.c
   ````````````````````
   Running a Mosel model from a C application
   with data exchange between model and host application.
   (Use Mosel running remotely controlled via XPRD)
   - Using the bindrv utility -
   
   (c) 2012 Fair Isaac Corporation
       author: S. Heipcke, Apr. 2012
********************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xprd.h"
#include "bindrv.h"

static char datafile[10*1024];	 /* Memory block to store the output data */
                                 /* (using static size for simplicity's sake) */
static int datafilesize;

typedef struct
	{
	 char *buffer;
	 int mode;
	 int bufsize;
	 int curpos;
	} s_memfile;

          /* Array to receive solution values */
struct MySolArray
{
 char *ind;                       /*   index name */
 double val;                      /*   solution value */
 struct MySolArray *next;
};

struct MySolArray *solfrac;
struct MySolArray *solbuy;


/********************************************************
   Implementation of a file manager 
   This file manager accesses directly file 'solfile'
   in local memory block 
   Warning: concurrency not handled here!!!
 ********************************************************/

void* XPRD_CC my_open(void *ctx, char *filename, int, XPRDfct_data* fct_data, 
       XPRDfct_close* fct_close, XPRDfct_skip *fct_skip, char *msg, int msglen);
int XPRD_CC my_close(void *data);
int XPRD_CC my_read(void *data, char *buf, int size);
int XPRD_CC my_write(void *data, char *buf, int size);
int XPRD_CC outremote(void *data, char *buf, int size);

void* XPRD_CC my_open(void *ctx, char *filename, int mode, 
                      XPRDfct_data* fct_data, XPRDfct_close* fct_close, 
                      XPRDfct_skip *fct_skip, char *msg, int msglen)
{
 s_memfile *memfile;

 if(strcmp(filename,"outremote")==0)
 {
  if((mode&(XPRD_F_READ|XPRD_F_WRITE))!=XPRD_F_WRITE)
  {
   strncpy(msg, "'outremote' is write only.", msglen);
   return XPRD_FMGR_ERR;
  }
  else
  {
   *fct_data=outremote;
   *fct_close=NULL;
   return (void*)1;
  }
 }
 if(strcmp(filename,"solfile")==0)
 {
  if((memfile=malloc(sizeof(s_memfile)))==NULL)
  {
   strncpy(msg,"memory error",msglen);
   return XPRD_FMGR_ERR;
  }
  else
  {
   memfile->buffer=datafile;
   memfile->mode=mode&(XPRD_F_READ|XPRD_F_WRITE);      
   memfile->bufsize=(memfile->mode==XPRD_F_READ)?datafilesize:sizeof(datafile);
   memfile->curpos=0;
   *fct_data=(memfile->mode==XPRD_F_READ)?my_read:my_write;
   *fct_close=my_close;
   *fct_skip=NULL;
   return memfile;
  }
 }

 else
  return NULL;               /*  Use default behaviour (open local file) */
}

/**** Release resources used by a memory file ****/
int XPRD_CC my_close(void *data)
{
 s_memfile *memfile;

 memfile=data;
 /* save size of datafile */
 if((memfile->mode==XPRD_F_WRITE)&&(memfile->buffer==datafile))
  datafilesize=memfile->curpos;
 free(data);
 return 0;
}

/**** Send data from a block of memory ****/
int XPRD_CC my_read(void *data,char *buf,int size)
{
 s_memfile *memfile;
 int l;

 memfile=data;
 if(memfile->curpos>=memfile->bufsize)        /* end of file */
  return 0;
 else
 if((l=memfile->bufsize-memfile->curpos)<=size)  /* last block */
 {
  memcpy(buf,memfile->buffer+memfile->curpos,l);
  memfile->curpos=memfile->bufsize;
  return l;
 }
 else
 {
  memcpy(buf,memfile->buffer+memfile->curpos,size);
  memfile->curpos+=size;
  return size;
 }
}

/**** Reading function with signature as required by the bin driver ****/
size_t my_fread(void *buf,size_t l,size_t nm,void *fd)
{
 return (my_read(fd,buf,nm*l)==l*nm)?nm:0;
}

/**** Store data in a block of memory ****/
int XPRD_CC my_write(void *data,char *buf,int size)
{
 s_memfile *memfile;
 memfile=data;
 if(memfile->curpos+size>=memfile->bufsize)   /* buffer overflow */
  return -1;
 else
 {
  memcpy(memfile->buffer+memfile->curpos,buf,size);
  memfile->curpos+=size;
  return size;
 }
}

/**** Display received message with a prefix ****/
int XPRD_CC outremote(void *data,char *buf,int size)
{
 printf("REMOTE: %.*s",size,buf);
 return size;
}


/********************************************************/
/* Using bindrv 
   Decode the binary file and display its content       */
/********************************************************/
void show_solution()
{
 s_memfile *f;
 s_bindrvctx bdrv;
 union { int i; double r; char b; char *str; BINDRV_LONG l;} val;
 char *index;
 struct MySolArray *solfracf,*solfracl,*solfracn;
 struct MySolArray *solbuyf,*solbuyl,*solbuyn;
 XPRDfct_data fct_data; 
 XPRDfct_close fct_close;
 XPRDfct_skip fct_skip;


 f=my_open(NULL,"solfile",XPRD_F_READ,&fct_data,&fct_close,&fct_skip,NULL,0);
 bdrv=bindrv_newreader(my_fread,f);


  while(bindrv_nexttoken(bdrv)>=0)
  {
   bindrv_getctrl(bdrv,&(val.i));         /* 'label' */
   bindrv_getstring(bdrv,&(val.str));
   if(strcmp(val.str,"RETSOL")==0)
   {
    free(val.str);
    bindrv_getreal(bdrv,&(val.r));
    printf("Total return: %g\n", val.r);
   } 
   else
   if(strcmp(val.str,"NUMSHARES")==0)
   {
    free(val.str);
    bindrv_getint(bdrv,&(val.i));
    printf("Number of shares: %d\n", val.i);
   } 
   else
   if(strcmp(val.str,"SOLSTATUS")==0)
   {
    free(val.str);
    bindrv_getint(bdrv,&(val.i));
    printf("Solution status: %d\n", val.i);
   } 
   else
   if(strcmp(val.str,"BUY")==0)
   {
    free(val.str);
    bindrv_getctrl(bdrv,&(val.i));    /* [ */
    bindrv_getctrl(bdrv,&(val.i));    /* ( or ] at end of list */
    solbuyf=NULL;
    while(val.i==BINDRV_CTRL_OPENNDX)
    {
     bindrv_getstring(bdrv,&index);
     bindrv_getctrl(bdrv,&(val.i));   /* ) */
     bindrv_getreal(bdrv,&(val.r));
     solbuyn = (struct MySolArray *)malloc(sizeof(struct MySolArray));
     solbuyn->next=NULL;
     if(solbuyf==NULL)
      solbuyf=solbuyl=solbuyn;
     else
     {
      solbuyl->next=solbuyn;
      solbuyl=solbuyn;
     }
     solbuyn->ind=index;
     solbuyn->val=val.r;
     bindrv_getctrl(bdrv,&(val.i));   /* ( or ] at end of list */
    }
    solbuy=solbuyf;
   }
   else
   if(strcmp(val.str,"FRAC")==0)
   {
    free(val.str);
    bindrv_getctrl(bdrv,&(val.i));    /* [ */
    bindrv_getctrl(bdrv,&(val.i));    /* ( or ] at end of list */
    solfracf=NULL;
    while(val.i==BINDRV_CTRL_OPENNDX)
    {
     bindrv_getstring(bdrv,&index);
     bindrv_getctrl(bdrv,&(val.i));   /* ) */
     bindrv_getreal(bdrv,&(val.r));
     solfracn = (struct MySolArray *)malloc(sizeof(struct MySolArray));
     solfracn->next=NULL;
     if(solfracf==NULL)
      solfracf=solfracl=solfracn;
     else
     {
      solfracl->next=solfracn;
      solfracl=solfracn;
     }
     solfracn->ind=index;
     solfracn->val=val.r;
     bindrv_getctrl(bdrv,&(val.i));   /* ( or ] at end of list */
    }
    solfrac=solfracf;
   }
   else
   {
    printf("Unexpected label: %s\n", val.str);
    free(val.str);
    exit(1);
   }
  }

 bindrv_delete(bdrv);                 /* Release bin reader */
 my_close(f);

 /* Print the solution values */
  solfracn=solfrac;
  solbuyn=solbuy;
  while(solfracn!=NULL && solbuyn!=NULL)
  {           /* This assumes that array indices are in the same order */
   printf(" %s: %g%% (%g)\n",  solfracn->ind, solfracn->val*100, solbuyn->val);
   solfracn=solfracn->next;
   solbuyn=solbuyn->next;
  }

  /* Clean up */
  solfracn=solfrac;
  while (solfracn!=NULL)
  {
   solfracn=solfrac->next;
   solfrac->next=NULL;
   free(solfrac->ind);
   free(solfrac);
   solfrac=solfracn;
  }
  solbuyn=solbuy;
  while (solbuyn!=NULL)
  {
   solbuyn=solbuy->next;
   solbuy->next=NULL;
   free(solbuy->ind);
   free(solbuy);
   solbuy=solbuyn;
  }

}

/********************************************************/

int main()
{
 char msg[256],params[1000];
 XPRDcontext xprd;
 XPRDmosel mosel;
 XPRDmodel mod;
 double maxrisk = 1.0/3;          /* Model parameter settings */
 double minreg = 0.2;
 double maxreg = 0.5;
 double maxsec = 0.25;
 double maxval = 0.2;
 double minval = 0.1;
 int maxnum = 15;
 int i;

 sprintf(params, "MAXRISK=%g,MINREG=%g,MAXREG=%g,MAXSEC=%g,MAXVAL=%g,MINVAL=%g,MAXNUM=%d,DATAFILE='rmt:folio250.dat',OUTPUTFILE='bin:rmt:solfile'",
         maxrisk, minreg, maxreg, maxsec, maxval, minval, maxnum); 


 xprd=XPRDinit();                 /* Initialize XPRD */

          /* Create a new Mosel instance with a user-defined file manager */
 mosel=XPRDconnect(xprd, "", my_open, NULL, msg, sizeof(msg));
 if(mosel==NULL)
 {
   printf("Connection failed: %s\n",msg);
   return 1;
 }
 printf("Connected to:\n%s\n", XPRDbanner(mosel));
 printf("Host: %s\n", XPRDsysinfo(mosel,XPRD_SYS_NODE,msg,sizeof(msg)));

          /* Set error stream of the remote instance to a local file */
 if(XPRDsetdefstream(mosel, NULL, XPRD_F_ERROR, "rmt:err.txt")!=0)
  printf("Failed to change error stream.\n");

                                  /* Compile the model on the remote instance */
 if((i=XPRDcompmod(mosel,"","rmt:foliomemio.mos","tmp:foliomemio.bim",""))!=0)
 {
  printf("Compilation failed: Error %d\n",i);
  return 2;
 }
                                  /* Load the model */
 mod=XPRDloadmod(mosel, "tmp:foliomemio.bim");
 if(mod==NULL)
 {
  printf("Failed to load model\n");
  return 3;
 }

          /* Redirect output stream of the model to the 'outremote' callback */
 if(XPRDsetdefstream(NULL,mod,XPRD_F_OUTPUT|XPRD_F_LINBUF, "rmt:outremote")!=0)
  printf("Failed to change output stream\n");

 XPRDrunmod(mod,params);          /* Run the model */

 /* Wait for model termination */ 
 XPRDwaitevent(xprd, 0);   
 XPRDdropevent(xprd);

 if(XPRDgetstatus(mod) != XPRD_RT_OK){
   printf("Error during model execution: %d\n", XPRDgetstatus(mod));
   exit(4);
 }
 if(XPRDgetexitcode(mod) != 0){
   printf("Problem not optimal: %d\n", XPRDgetexitcode(mod));
   exit(5);
 }                                /* Stop if no solution available */

 XPRDdisconnect(mosel);           /* Disconnect remote instance */

 /* Decode & display solution data for last (optimal) solution */
 show_solution();
 
 XPRDfinish(xprd);                /* Release context */

 return 0;
}

runfoliodistr.java
/*******************************************************
   Mosel Example Problems
   ====================== 

   file runfoliodistr.java
   ```````````````````````
   Running a Mosel model from a Java application
   with data exchange between model and host application.
   (use Mosel running remotely controlled via XPRD)
   - Using the bindrv utility -
   
   (c) 2011 Fair Isaac Corporation
       author: Y.Colombani, July 2011
********************************************************/

import java.io.*;
import java.util.*;
import com.dashoptimization.*;

public class runfoliodistr
{
 static byte solbuf[]=null;

/**
  * An extension of 'ByteArrayOutputStream' for saving the array on closing.
  */
 static class myByteArrayOutputStream extends ByteArrayOutputStream
 {
  public void close()
  {
   solbuf=toByteArray();
  }
 }

/**
  * This file manager will directly access the file 'solfile'
  * to a local ArrayStream object.
  * Warning: concurrency not handled here!!!
  */
 static class FileManager implements XPRDFileManager
 {
  public OutputStream openForWriting(String fname,int mode) throws IOException
  {
   if(fname.equals("solfile"))
   {
    return new myByteArrayOutputStream();
   }
   else
    return null;    // Name not found: use default behaviour (open local file)
  }
  public InputStream openForReading(String fname,int mode) throws IOException
  {
   return null;     // Use default behaviour (open local file)
  }
 }
                    // Class to receive solution values of decision variables
 public static class MySolArray
 {
  public String ind;                // index name
  public double val;                // solution value
  MySolArray(String i,double v)
  {
   ind=i;
   val=v;
  }
 }

// Decode the binary file and display its content
 static void showSolution() throws Exception
 {
  ByteArrayInputStream inbuf=new ByteArrayInputStream(solbuf);
  BinDrvReader bdrv=new BinDrvReader(inbuf);
  String label;
  String index;
  ArrayList<MySolArray> solfrac=new ArrayList<MySolArray>();
  ArrayList<MySolArray> solbuy=new ArrayList<MySolArray>();

  while(bdrv.nextToken()>=0)
  {
   bdrv.getControl();     // 'label'
   label=bdrv.getString();
   if(label.equals("RETSOL"))
    System.out.println("Total return: " + bdrv.getReal());
   else
   if(label.equals("NUMSHARES"))
    System.out.println("Number of shares: " + bdrv.getInt());
   else
   if(label.equals("SOLSTATUS"))
    System.out.println("Solution status: " + bdrv.getInt());
   else
   if(label.equals("BUY"))
   {
    bdrv.getControl();    // [
    while(bdrv.getControl()==BinDrvReader.CTRL_OPENNDX) // ( or ] at end of list
    {
     index=bdrv.getString();
     bdrv.getControl();   // )
     solbuy.add(new MySolArray(index,bdrv.getReal()));
    }
   }
   else
   if(label.equals("FRAC"))
   {
    bdrv.getControl();    // [
    while(bdrv.getControl()==BinDrvReader.CTRL_OPENNDX) // ( or ] at end of list
    {
     index=bdrv.getString();
     bdrv.getControl();   // )
     solfrac.add(new MySolArray(index,bdrv.getReal()));
    }
   }
   else
   {
    System.out.println("Unexpected label: "+label);
    System.exit(0);
   }
  }

  Iterator<MySolArray> ibuy=solbuy.iterator();
  Iterator<MySolArray> ifrac=solfrac.iterator();

  while(ibuy.hasNext() && ifrac.hasNext())
  {
   MySolArray buy=ibuy.next();
   MySolArray frac=ifrac.next();
   System.out.println(frac.ind + ": " + frac.val*100 + "% (" + 
       buy.val + ")");
  }
 }

 public static void main(String[] args) throws Exception
 {
  XPRD xprd=new XPRD();
  XPRDFileManager fmgr=new FileManager();
  XPRDMosel mosel;
  XPRDModel mod;
                    // Model parameter settings
  double maxrisk = 1.0/3;
  double minreg = 0.2;
  double maxreg = 0.5;
  double maxsec = 0.25;
  double maxval = 0.2;
  double minval = 0.1;
  int maxnum = 15;
  int val;

  try{
   mosel = xprd.connect("",fmgr);     // Create a new Mosel instance
  }catch(IOException e){
                System.out.println("IO error" + e.getMessage());
                throw new java.lang.Exception("Failed to connect");
  }

  try{
   mosel.compile("","rmt:foliomemio.mos","tmp:foliomemio.bim");
                                      // Compile the model (only required
                                      // during development phase, deployed
				      // application would only use BIM)
  }catch(XPRDCompileException e){
   System.out.println(e.getMessage());
   System.exit(1);
  }
  
  mod = mosel.loadModel("tmp:foliomemio.bim");  // Load the model

                    // Pass model parameters through execution parameters
  mod.setExecParam("MAXRISK",maxrisk);
  mod.setExecParam("MINREG",minreg);
  mod.setExecParam("MAXREG",maxreg);
  mod.setExecParam("MAXSEC",maxsec);
  mod.setExecParam("MAXVAL",maxval);
  mod.setExecParam("MINVAL",minval);
  mod.setExecParam("MAXNUM",maxnum);
  mod.setExecParam("DATAFILE","rmt:folio10.dat");
  mod.setExecParam("OUTPUTFILE","bin:rmt:solfile");
  mod.run();                          // Run the model
  
  // Wait for model termination 
  xprd.waitForEvent();
  xprd.dropNextEvent();

  if(mod.getExecStatus() != XPRDModel.RT_OK){
   throw new java.lang.Exception("Error during model execution ");
  }
  if(mod.getResult() != 0){
   throw new java.lang.Exception("Problem not optimal");
  }                                  // Stop if no solution available

  mosel.disconnect();                // Disconnect instance

  // Decode & display solution data for last (optimal) solution 
  showSolution();

 }
}


foliomemio.mos
(!******************************************************
   Mosel Example Problems
   ======================

   file foliomemio.mos
   ```````````````````
   Modeling a MIP problem 
   to perform portfolio optimization.

   Same model as in foliomip3.mos with
   simplified data structures (replaced arrays of structured types).
   -- Data input/output in memory --
   
   Run modes for this model:
   1. Stand-alone: data I/O to text files
      (run this model from Workbench or from Mosel command line) 
   2. Submodel to another Mosel model: data exchange in memory
      (run model 'runfolio.mos' or 'runfoliopar.mos' to execute this model)
   3a. C: I/O to C program runfolio.c or runfoliod.c
      (compile and run C program 'runfolio.c' or 'runfoliod.c')
   3b. Java: I/O to Java program runfolio.java, runfoliob.java, or
      runfoliod.java
      (compile and run Java program 'runfolio.java', 'runfoliob.java',
      or 'runfoliod.java')
   3c. (Windows only) C#: I/O to C# program runfolio.cs or runfoliob.cs
      (compile and run C# program 'runfolio.cs' or 'runfoliob.cs')
   4. Remote execution from another Mosel model: 
      (run model 'runfoliodistr.mos' or 'runfoliopardistr.mos' to execute 
      this model)   
   5a. Remote execution from C: I/O to C program distfolio.c or distfoliopar.c
      (compile and run C program 'distfolio.c' or 'distfoliopar.c')
   5b. Remote execution from Java: I/O to Java program distfolio.java or
      distfoliopar.java
      (compile and run Java program 'distfolio.java' or 'distfoliopar.java')
   
  (c) 2009 Fair Isaac Corporation
      author: S.Heipcke, Jan. 2009, rev. Oct 2012
*******************************************************!)

model "Portfolio optimization with MIP"
 uses "mmxprs"

 parameters
  MAXRISK = 1/3                      ! Max. investment into high-risk values
  MINREG = 0.2                       ! Min. investment per geogr. region
  MAXREG = 0.5                       ! Max. investment per geogr. region
  MAXSEC = 0.25                      ! Max. investment per ind. sector
  MAXVAL = 0.2                       ! Max. investment per share
  MINVAL = 0.1                       ! Min. investment per share
  MAXNUM = 15                        ! Max. number of different assets

  DATAFILE = "folio10.dat"           ! File with problem data
  OUTPUTFILE = "sol10out.dat"        ! File for solution output
  RISKDATA = "RISK"                  ! Locations of input data
  RETDATA = "RET"
  LOCDATA = "LOCTAB"
  SECDATA = "SECTAB"
  FRACSOL = "FRAC"                   ! Locations for solution output
  BUYSOL = "BUY"
  NUMSHARES = "NUMSHARES"
  RETSOL = "RETSOL"
  SOLSTATUS = "SOLSTATUS"
 end-parameters

 declarations
  SHARES,S: set of string            ! Set of shares
  RISK: set of string                ! Set of high-risk values among shares
  REGIONS: set of string             ! Geographical regions
  TYPES: set of string               ! Share types (ind. sectors)
  LOCTAB: dynamic array(REGIONS,SHARES) of boolean ! Shares per geogr. region
  RET: array(SHARES) of real         ! Estimated return in investment
  SECTAB: dynamic array(TYPES,SHARES) of boolean ! Shares per industry sector
 end-declarations

 initializations from DATAFILE
  RISK as RISKDATA
  RET as RETDATA
  LOCTAB as LOCDATA
  SECTAB as SECDATA
 end-initializations

 declarations
  frac: array(SHARES) of mpvar      ! Fraction of capital used per share
  buy: array(SHARES) of mpvar       ! 1 if asset is in portfolio, 0 otherwise
 end-declarations

! Objective: total return
 Return:= sum(s in SHARES) RET(s)*frac(s) 

! Limit the percentage of high-risk values
 sum(s in RISK) frac(s) <= MAXRISK

! Limits on geographical distribution
 forall(r in REGIONS) do
  sum(s in SHARES | exists(LOCTAB(r,s))) frac(s) >= MINREG
  sum(s in SHARES | exists(LOCTAB(r,s))) frac(s) <= MAXREG
 end-do 

! Diversification across industry sectors
 forall(t in TYPES) sum(s in SHARES | exists(SECTAB(t,s))) frac(s) <= MAXSEC

! Spend all the capital
 sum(s in SHARES) frac(s) = 1
 
! Upper bounds on the investment per share
 forall(s in SHARES) frac(s) <= MAXVAL

! Limit the total number of assets
 sum(s in SHARES) buy(s) <= MAXNUM

 forall(s in SHARES) do
  buy(s) is_binary                  ! Turn variables into binaries
  frac(s) <= MAXVAL*buy(s)                 ! Linking the variables
  frac(s) >= MINVAL*buy(s)                 ! Linking the variables
 end-do


! Display Optimizer log
 setparam("XPRS_verbose", true)

! Solve the problem
 maximize(Return)


! Adapt Mosel comparison tolerance to Optimizer feasibility tolerance
 setparam("zerotol", getparam("XPRS_feastol")/10)

! Solution output
 function getvalues(v: array(SHARES) of mpvar): array(S) of real
  forall(s in SHARES | v(s).sol<>0) returned(s):= v(s).sol  
 end-function
 
 initializations to OUTPUTFILE
  evaluation of Return.sol as RETSOL
  evaluation of sum(s in SHARES | buy(s).sol<>0) 1 as NUMSHARES
  evaluation of getvalues(frac) as FRACSOL
  evaluation of getvalues(buy) as BUYSOL
  evaluation of getprobstat as SOLSTATUS
 end-initializations

end-model 

distfolio.c
/*******************************************************
   Mosel Example Problems 
   ======================

   file distfolio.c
   ````````````````
   Running a model on a remote machine,
   passing runtime parameters to the submodel.

   Before running this model, you need to set up the 
   NODENAME with a machine name/address of your local network.
   The node that is used needs to have the same version of
   Xpress installed and suitably licensed, and the server 
   "xprmsrv" must have been started on this machine.
       
   (c) 2012 Fair Isaac Corporation
       author: S. Heipcke, Oct 2012
*******************************************************/

#include <stdio.h>
#include <stdlib.h>
#include "xprd.h"
#include "bindrv.h"

/***************** Reading result data ******************/
struct MySolArray
{
 const char *ind;                 /*   index name */
 double val;                      /*   solution value */
};

struct MySolArray *solfrac;
struct MySolArray *solbuy;

 int getbdintval(s_bindrvctx bdrv)
 {
   union { int i; double r; char b; char *str; BINDRV_LONG l;} val;
   bindrv_getint(bdrv,&(val.i));
   return val.i;
 }
 
 double getbddblval(s_bindrvctx bdrv)
 {
   union { int i; double r; char b; char *str; BINDRV_LONG l;} val;
   bindrv_getreal(bdrv,&(val.r));
   return val.r;
 }

 /**** Reading a one-dim. array 'ar' of fixed max. size ****/
 static int assignFixedTableVal(s_bindrvctx bdrv, struct MySolArray *ar) 
 {
   int i,ct,ctrl,j2;
   union { int i; double r; char b; char *str; BINDRV_LONG l;} val;

   ct=0;
   bindrv_getctrl(bdrv,&(val.i));
   if (val.i==BINDRV_CTRL_OPENLST)
   {
     while(bindrv_nexttoken(bdrv)>=0) {
     bindrv_getctrl(bdrv,&(val.i));
     ctrl=val.i;
     if(ctrl==BINDRV_CTRL_CLOSELST) break;
     else
       if(ctrl==BINDRV_CTRL_OPENNDX)
       {
         bindrv_getstring(bdrv,&(val.str));
         ar[ct].ind=val.str;
	 bindrv_getctrl(bdrv,&(val.i));
         if(val.i==BINDRV_CTRL_CLOSENDX)
         {
           bindrv_getreal(bdrv,&(val.r));
           ar[ct].val=val.r;
	   ct++;
         }
         else
         {
           printf("Wrong file format. ')' expected.\n");
	   return 1;
         }
       }
       else
       {
         printf("Wrong file format. '(' expected.\n");
	 return 2;
       }
     }
   }
   else
   {
     printf("Wrong file format. '[' expected.\n");
     return 3;
   }  
   return 0;  
 }
 
 static int readSol(char *filename) 
 {
   s_bindrvctx bdrv;
   FILE *f;
   union { int i; double r; char b; char *str; BINDRV_LONG l;} val;
   int res=0,num=0,i;

   f=fopen(filename,"r");                        /* Use Mosel bin reader */
   bdrv=bindrv_newreader((size_t (*)(void *,size_t,size_t,void*))fread,f);

   while(bindrv_nexttoken(bdrv)>=0 && res==0) {
     bindrv_getctrl(bdrv,&(val.i));
     if(val.i==BINDRV_CTRL_LABEL)
     {
       bindrv_getstring(bdrv,&(val.str));
       if(strcmp(val.str,"RETSOL")==0)
        printf("Total return: %g\n", getbddblval(bdrv));
       else if(strcmp(val.str,"NUMSHARES")==0)
       {
        num = getbdintval(bdrv);
        printf("Number of shares: %d\n", num);
       }	
       else if(strcmp(val.str,"SOLCOUNT")==0)
        printf("Solution number: %d\n", getbdintval(bdrv));
       else if(strcmp(val.str,"SOLSTATUS")==0)
        printf("Solution status: %d\n", getbdintval(bdrv));
       else if (strcmp(val.str,"BUY")==0)
         res=assignFixedTableVal(bdrv, solbuy);
       else if (strcmp(val.str,"FRAC")==0)
         res=assignFixedTableVal(bdrv, solfrac);
       else printf("Unexpected label: %s", val.str);
     }
     else
     {
       printf("Wrong file format\n");
       res=4;
     }  
   }

   bindrv_delete(bdrv);
   fclose(f);

   for(i=0;i<num;i++)
    printf("%s: %g%% (%g)\n", 
           solfrac[i].ind, solfrac[i].val*100, solbuy[i].val); 

   return res;
 }
/***************** Main ******************/

int main(int argv,char *args[]) 
{
  XPRDcontext xprd;
  XPRDmosel mosel;
  XPRDmodel mod;
  char params[1000];
  double maxrisk = 1.0/3;          /* Model parameter settings */
  double minreg = 0.2;
  double maxreg = 0.5;
  double maxsec = 0.25;
  double maxval = 0.2;
  double minval = 0.1;
  int maxnum = 9;
       /* Use the name or IP address of a machine in
        * your local network, or "" for current node */
  char *NODENAME = "";

  solfrac = (struct MySolArray *)malloc(maxnum * sizeof(struct MySolArray));
  solbuy = (struct MySolArray *)malloc(maxnum * sizeof(struct MySolArray));

  xprd=XPRDinit();             /* Create an XPRD context */
                               /* Open connection to a remote node */
  mosel=XPRDconnect(xprd, NODENAME, NULL, NULL, NULL, 0);
                               /* Compile the model file */
  XPRDcompmod(mosel, "", "rmt:foliomemio.mos", "rmt:foliomemio.bim", "");
                               /* Load the bim file into the remote instance */
  mod=XPRDloadmod(mosel, "rmt:foliomemio.bim"); 
  remove("foliomemio.bim");    /* Cleaning up */
                               /* Run-time parameters */
  sprintf(params, "MAXRISK=%.16f,MINREG=%g,MAXREG=%g,MAXSEC=%g,MAXVAL=%g,MINVAL=%g,MAXNUM=%d,DATAFILE='rmt:folio250.dat',OUTPUTFILE='bin:rmt:solfile.dat'",
         maxrisk, minreg, maxreg, maxsec, maxval, minval, maxnum ); 
  XPRDrunmod(mod, params);     /* Run the model */
  XPRDwaitevent(xprd,-1);      /* Wait for model termination */
  XPRDdropevent(xprd);         /* Ignore termination event message */

  printf("Model returned: %d\n", XPRDgetexitcode(mod));
  readSol("solfile.dat");      /* Display the solution */
  remove("solfile.dat");

  XPRDunloadmod(mod);          /* Unload the model */
  XPRDdisconnect(mosel);       /* Disconnect remote instance */
  XPRDfinish(xprd);            /* Terminate XPRD */
  return 0;
} 

distfolio.java
/*******************************************************
   Mosel Example Problems 
   ======================

   file distfolio.java
   ```````````````````
   Running a model on a remote machine,
   passing runtime parameters to the submodel.

   Before running this model, you need to set up the 
   NODENAME with a machine name/address of your local network.
   The node that is used needs to have the same version of
   Xpress installed and suitably licensed, and the server 
   "xprmsrv" must have been started on this machine.
       
   (c) 2012 Fair Isaac Corporation
       author: S. Heipcke, Oct 2012
*******************************************************/

import com.dashoptimization.*;
import java.lang.*;
import java.io.*;
import java.util.*;

public class distfolio
{
                    // Class to receive solution values of decision variables
 public static class MySolArray
 {
  public String ind;                // index name
  public double val;                // solution value
  MySolArray(String i,double v)
  {
   ind=i;
   val=v;
  }
 }

/***************** Reading result data ******************/

 static void readSol(String filename) throws IOException
 {
   BinDrvReader bdrv;
   FileInputStream f;
   String label;
   String index;
   ArrayList<MySolArray> solfrac=new ArrayList<MySolArray>();
   ArrayList<MySolArray> solbuy=new ArrayList<MySolArray>();

   f=new FileInputStream(filename);
   bdrv=new BinDrvReader(f);              // Use Mosel bin reader

  while(bdrv.nextToken()>=0)
  {
   bdrv.getControl();     // 'label'
   label=bdrv.getString();
   if(label.equals("RETSOL"))
    System.out.println("Total return: " + bdrv.getReal());
   else
   if(label.equals("NUMSHARES"))
    System.out.println("Number of shares: " + bdrv.getInt());
   else
   if(label.equals("SOLCOUNT"))
    System.out.println("Solution number: " + bdrv.getInt());
   else
   if(label.equals("SOLSTATUS"))
    System.out.println("Solution status: " + bdrv.getInt());
   else
   if(label.equals("BUY"))
   {
    bdrv.getControl();    // [
    while(bdrv.getControl()==BinDrvReader.CTRL_OPENNDX) // ( or ] at end of list
    {
     index=bdrv.getString();
     bdrv.getControl();   // )
     solbuy.add(new MySolArray(index,bdrv.getReal()));
    }
   }
   else
   if(label.equals("FRAC"))
   {
    bdrv.getControl();    // [
    while(bdrv.getControl()==BinDrvReader.CTRL_OPENNDX) // ( or ] at end of list
    {
     index=bdrv.getString();
     bdrv.getControl();   // )
     solfrac.add(new MySolArray(index,bdrv.getReal()));
    }
   }
   else
   {
    System.out.println("Unexpected label: "+label);
    System.exit(0);
   }
  }

  Iterator<MySolArray> ibuy=solbuy.iterator();
  Iterator<MySolArray> ifrac=solfrac.iterator();

  while(ibuy.hasNext() && ifrac.hasNext())
  {
   MySolArray buy=ibuy.next();
   MySolArray frac=ifrac.next();
   System.out.println(frac.ind + ": " + frac.val*100 + "% (" + 
       buy.val + ")");
  }
 }

/***************** Main ******************/

 public static void main(String[] args) throws Exception
 {
  XPRD xprd=new XPRD();
  XPRDMosel mosel=null;
  XPRDModel mod=null;
                    // Model parameter settings
  double maxrisk = 1.0/3;
  double minreg = 0.2;
  double maxreg = 0.5;
  double maxsec = 0.25;
  double maxval = 0.2;
  double minval = 0.1;
  int maxnum = 9;

                       // Use the name or IP address of a machine in
                       // your local network, or "" for current node
  String NODENAME = "";
                       // Open connection to a remote node
  try{
   mosel = xprd.connect(NODENAME);    // Create a new Mosel instance
  }catch(IOException e){
                System.out.println("IO error" + e.getMessage());
                throw new java.lang.Exception("Failed to connect");
  }

  try{
   mosel.compile("","rmt:foliomemio.mos","rmt:foliomemio.bim");
                                      // Compile the model (only required
                                      // during development phase, deployed
				      // application would only use BIM)
  }catch(XPRDCompileException e){
   System.out.println(e.getMessage());
   System.exit(1);
  }
                       // Load the bim file into the remote instance 
  mod = mosel.loadModel("rmt:foliomemio.bim");
  new File("foliomemio.bim").delete();         // Cleaning up

                       // Pass model parameters through execution parameters
  mod.setExecParam("MAXRISK",maxrisk);
  mod.setExecParam("MINREG",minreg);
  mod.setExecParam("MAXREG",maxreg);
  mod.setExecParam("MAXSEC",maxsec);
  mod.setExecParam("MAXVAL",maxval);
  mod.setExecParam("MINVAL",minval);
  mod.setExecParam("MAXNUM",maxnum);
  mod.setExecParam("DATAFILE","rmt:folio250.dat");
  mod.setExecParam("OUTPUTFILE","bin:rmt:solfile.dat");
  System.out.println(mod.execParams);
  mod.run();                          // Run the model
  xprd.waitForEvent();                // Wait for model termination
  xprd.dropNextEvent();               // Ignore termination event message

  if(mod.getExecStatus() != XPRDModel.RT_OK){
   throw new java.lang.Exception("Error during model execution ");
  }
  if(mod.getResult() != 0){
   throw new java.lang.Exception("Problem not optimal");
  }                                  

  try {
   readSol("solfile.dat");      // Read+display result data
  } catch(IOException e) {
   System.out.println("Could not read result file");
   System.exit(1);
  }
  new File("solfile.dat").delete();

  mosel.disconnect();                 // Disconnect remote instance
 }
} 

distfoliopar.c
/*******************************************************
   Mosel Example Problems 
   ======================

   file distfoliopar.c
   ```````````````````
   Running several instances of a Mosel model
   in parallel using several (remote) Mosel instances.

   Before running this model, you need to set up the 
   NODENAME with a machine name/address of your local network.
   The node that is used needs to have the same version of
   Xpress installed and suitably licensed, and the server 
   "xprmsrv" must have been started on this machine.
       
   (c) 2012 Fair Isaac Corporation
       author: S. Heipcke, Oct 2012
*******************************************************/

#include <stdio.h>
#include <stdlib.h>
#include "xprd.h"
#include "bindrv.h"

#define NUMPAR 2               /* Number of model instances to run */

/***************** Reading result data ******************/
struct MySolArray
{
 const char *ind;                 /*   index name */
 double val;                      /*   solution value */
};

struct MySolArray *solfrac;
struct MySolArray *solbuy;

 int getbdintval(s_bindrvctx bdrv)
 {
   union { int i; double r; char b; char *str; BINDRV_LONG l;} val;
   bindrv_getint(bdrv,&(val.i));
   return val.i;
 }
 
 double getbddblval(s_bindrvctx bdrv)
 {
   union { int i; double r; char b; char *str; BINDRV_LONG l;} val;
   bindrv_getreal(bdrv,&(val.r));
   return val.r;
 }

 /**** Reading a one-dim. array 'ar' of fixed max. size ****/
 static int assignFixedTableVal(s_bindrvctx bdrv, struct MySolArray *ar) 
 {
   int i,ct,ctrl,j2;
   union { int i; double r; char b; char *str; BINDRV_LONG l;} val;

   ct=0;
   bindrv_getctrl(bdrv,&(val.i));
   if (val.i==BINDRV_CTRL_OPENLST)
   {
     while(bindrv_nexttoken(bdrv)>=0) {
     bindrv_getctrl(bdrv,&(val.i));
     ctrl=val.i;
     if(ctrl==BINDRV_CTRL_CLOSELST) break;
     else
       if(ctrl==BINDRV_CTRL_OPENNDX)
       {
         bindrv_getstring(bdrv,&(val.str));
         ar[ct].ind=val.str;
	 bindrv_getctrl(bdrv,&(val.i));
         if(val.i==BINDRV_CTRL_CLOSENDX)
         {
           bindrv_getreal(bdrv,&(val.r));
           ar[ct].val=val.r;
	   ct++;
         }
         else
         {
           printf("Wrong file format. ')' expected.\n");
	   return 1;
         }
       }
       else
       {
         printf("Wrong file format. '(' expected.\n");
	 return 2;
       }
     }
   }
   else
   {
     printf("Wrong file format. '[' expected.\n");
     return 3;
   }  
   return 0;  
 }
 
 static int readSol(char *filename) 
 {
   s_bindrvctx bdrv;
   FILE *f;
   union { int i; double r; char b; char *str; BINDRV_LONG l;} val;
   int res=0,num=0,i;

   printf("Solution file: %s\n", filename);
   f=fopen(filename,"r");                        /* Use Mosel bin reader */
   bdrv=bindrv_newreader((size_t (*)(void *,size_t,size_t,void*))fread,f);

   while(bindrv_nexttoken(bdrv)>=0 && res==0) {
     bindrv_getctrl(bdrv,&(val.i));
     if(val.i==BINDRV_CTRL_LABEL)
     {
       bindrv_getstring(bdrv,&(val.str));
       if(strcmp(val.str,"RETSOL")==0)
        printf("Total return: %g\n", getbddblval(bdrv));
       else if(strcmp(val.str,"NUMSHARES")==0)
       {
        num = getbdintval(bdrv);
        printf("Number of shares: %d\n", num);
       }	
       else if(strcmp(val.str,"SOLCOUNT")==0)
        printf("Solution number: %d\n", getbdintval(bdrv));
       else if(strcmp(val.str,"SOLSTATUS")==0)
        printf("Solution status: %d\n", getbdintval(bdrv));
       else if (strcmp(val.str,"BUY")==0)
         res=assignFixedTableVal(bdrv, solbuy);
       else if (strcmp(val.str,"FRAC")==0)
         res=assignFixedTableVal(bdrv, solfrac);
       else printf("Unexpected label: %s", val.str);
     }
     else
     {
       printf("Wrong file format\n");
       res=4;
     }  
   }

   bindrv_delete(bdrv);
   fclose(f);

   for(i=0;i<num;i++)
    printf("%s: %g%% (%g)\n", 
           solfrac[i].ind, solfrac[i].val*100, solbuy[i].val); 
   printf("\n");

   return res;
 }
/***************** Main ******************/

int main(int argv,char *args[]) 
{
  XPRDcontext xprd;
  XPRDmosel mosel[NUMPAR];
  XPRDmodel mod[NUMPAR];
  char params[1000];
  double maxrisk = 1.0/3;          /* Model parameter settings */
  double minreg = 0.2;
  double maxreg = 0.5;
  double maxsec = 0.25;
  double maxval = 0.2;
  double minval = 0.1;
  int maxnum = 9;
  char *NODENAME[NUMPAR];
  char bufd[200],bufn[200];
  int j;

         /* Use the name or IP address of a machine in
          * your local network, or "" for current node */
  for(j=0;j<NUMPAR;j++) NODENAME[j] = "localhost";

  solfrac = (struct MySolArray *)malloc(maxnum * sizeof(struct MySolArray));
  solbuy = (struct MySolArray *)malloc(maxnum * sizeof(struct MySolArray));

  xprd=XPRDinit();             /* Create an XPRD context */
                               /* Open connection to remote nodes */
  for(j=0;j<NUMPAR;j++)
  {
   mosel[j]=XPRDconnect(xprd, NODENAME[j], NULL, NULL, NULL, 0);
   if (mosel[j]==NULL)
   {
     printf("Connection to %s failed\n", NODENAME[j]);
     return 1;
   }
  } 

  for(j=0;j<NUMPAR;j++)
  {
    XPRDsysinfo(mosel[j], XPRD_SYS_NODE, bufd, sizeof(bufd));
    XPRDsysinfo(mosel[j], XPRD_SYS_NAME, bufn, sizeof(bufn));
    printf("Submodel node: %s on %s\n", bufd, bufn);
  }

                               /* Compile the model file on one instance */
  XPRDcompmod(mosel[0], "", "rmt:foliomemio.mos", "rmt:foliomemio.bim", "");
                               /* Load the bim file into remote instances */
  for(j=0;j<NUMPAR;j++)
   mod[j]=XPRDloadmod(mosel[j], "rmt:foliomemio.bim"); 
  remove("foliomemio.bim");    /* Cleaning up */

  for(j=0;j<NUMPAR;j++)
  {
                              /* Run-time parameters */
   sprintf(params, "MAXRISK=%.16f,MINREG=%g,MAXREG=%g,MAXSEC=%g,MAXVAL=%g,MINVAL=%g,MAXNUM=%d,DATAFILE='rmt:folio250.dat',OUTPUTFILE='bin:rmt:solfile%d.dat'",
         maxrisk, minreg, maxreg, maxsec, maxval, minval, maxnum-j, j); 

   XPRDrunmod(mod[j], params);     /* Run the model */
  }
  for(j=0;j<NUMPAR;j++)
  {
   XPRDwaitevent(xprd,-1);     /* Wait for model termination */
   XPRDdropevent(xprd);        /* Ignore termination event message */
   printf("Model returned: %d\n", XPRDgetexitcode(mod[j]));
  }


  for(j=0;j<NUMPAR;j++)
  {
   sprintf(params, "solfile%d.dat", j);
   readSol(params);            /* Display the solution */
   XPRDunloadmod(mod[j]);      /* Unload the model */
   remove(params);
  }

  for(j=0;j<NUMPAR;j++)
   XPRDdisconnect(mosel[j]);   /* Disconnect remote instances */
  XPRDfinish(xprd);            /* Terminate XPRD */
 
  return 0;
} 

distfoliopar.java
/*******************************************************
   Mosel Example Problems 
   ======================

   file distfoliopar.java
   ``````````````````````
   Running several instances of a Mosel model
   in parallel using several (remote) Mosel instances.

   Before running this model, you need to set up the 
   NODENAME with a machine name/address of your local network.
   The node that is used needs to have the same version of
   Xpress installed and suitably licensed, and the server 
   "xprmsrv" must have been started on this machine.
       
   (c) 2012 Fair Isaac Corporation
       author: S. Heipcke, Oct 2012
*******************************************************/

import com.dashoptimization.*;
import java.lang.*;
import java.io.*;
import java.util.*;

public class distfoliopar
{
 static final int numpar = 2;      // Number of model instances to run

                    // Class to receive solution values of decision variables
 public static class MySolArray
 {
  public String ind;                // index name
  public double val;                // solution value
  MySolArray(String i,double v)
  {
   ind=i;
   val=v;
  }
 }

/***************** Reading result data ******************/

 static void readSol(String filename) throws IOException
 {
  BinDrvReader bdrv;
  FileInputStream f;
  String label;
  String index;
  ArrayList<MySolArray> solfrac=new ArrayList<MySolArray>();
  ArrayList<MySolArray> solbuy=new ArrayList<MySolArray>();

  f=new FileInputStream(filename);
  bdrv=new BinDrvReader(f);              // Use Mosel bin reader

  System.out.println("Solution file: " + filename);

  while(bdrv.nextToken()>=0)
  {
   bdrv.getControl();     // 'label'
   label=bdrv.getString();
   if(label.equals("RETSOL"))
    System.out.println("Total return: " + bdrv.getReal());
   else
   if(label.equals("NUMSHARES"))
    System.out.println("Number of shares: " + bdrv.getInt());
   else
   if(label.equals("SOLCOUNT"))
    System.out.println("Solution number: " + bdrv.getInt());
   else
   if(label.equals("SOLSTATUS"))
    System.out.println("Solution status: " + bdrv.getInt());
   else
   if(label.equals("BUY"))
   {
    bdrv.getControl();    // [
    while(bdrv.getControl()==BinDrvReader.CTRL_OPENNDX) // ( or ] at end of list
    {
     index=bdrv.getString();
     bdrv.getControl();   // )
     solbuy.add(new MySolArray(index,bdrv.getReal()));
    }
   }
   else
   if(label.equals("FRAC"))
   {
    bdrv.getControl();    // [
    while(bdrv.getControl()==BinDrvReader.CTRL_OPENNDX) // ( or ] at end of list
    {
     index=bdrv.getString();
     bdrv.getControl();   // )
     solfrac.add(new MySolArray(index,bdrv.getReal()));
    }
   }
   else
   {
    System.out.println("Unexpected label: "+label);
    System.exit(0);
   }
  }

  Iterator<MySolArray> ibuy=solbuy.iterator();
  Iterator<MySolArray> ifrac=solfrac.iterator();

  while(ibuy.hasNext() && ifrac.hasNext())
  {
   MySolArray buy=ibuy.next();
   MySolArray frac=ifrac.next();
   System.out.println(frac.ind + ": " + frac.val*100 + "% (" + 
       buy.val + ")");
  }
  System.out.println();
 }

/***************** Main ******************/

 public static void main(String[] args) throws Exception
 {
  XPRD xprd=new XPRD();
  XPRDMosel[] mosel=new XPRDMosel[numpar];
  XPRDModel[] mod=new XPRDModel[numpar];
  String[] NODENAMES=new String[numpar];
  int j;

                       // Model parameter settings
  double maxrisk = 1.0/3;
  double minreg = 0.2;
  double maxreg = 0.5;
  double maxsec = 0.25;
  double maxval = 0.2;
  double minval = 0.1;
  int maxnum = 9;

                       // Use the name or IP address of a machine in
                       // your local network, or "" for current node
  for(j=0;j<numpar;j++) NODENAMES[j] = "localhost";

                       // Open connection to remote nodes
  for(j=0;j<numpar;j++)
   try{
    mosel[j] = xprd.connect(NODENAMES[j]);    // Create a new Mosel instance
   }catch(IOException e){
                System.out.println("IO error" + e.getMessage());
                throw new java.lang.Exception("Failed to connect");
   }

  for(j=0;j<numpar;j++)
    System.out.println("Submodel node: " + 
      mosel[j].getSystemInformation(XPRDMosel.SYS_NODE) + " on " +
      mosel[j].getSystemInformation(XPRDMosel.SYS_NAME));

                       // Compile the model file on one instance
  try{
   mosel[0].compile("","rmt:foliomemio.mos","rmt:foliomemio.bim");
  }catch(XPRDCompileException e){
   System.out.println(e.getMessage());
   System.exit(1);
  }
                       // Load the bim file into remote instances 
  for(j=0;j<numpar;j++)
   mod[j] = mosel[j].loadModel("rmt:foliomemio.bim");
  new File("foliomemio.bim").delete();         // Cleaning up

                       // Pass model parameters through execution parameters
  for(j=0;j<numpar;j++)
  {
   mod[j].setExecParam("MAXRISK",maxrisk);
   mod[j].setExecParam("MINREG",minreg);
   mod[j].setExecParam("MAXREG",maxreg);
   mod[j].setExecParam("MAXSEC",maxsec);
   mod[j].setExecParam("MAXVAL",maxval);
   mod[j].setExecParam("MINVAL",minval);
   mod[j].setExecParam("MAXNUM",maxnum-j);
   mod[j].setExecParam("DATAFILE","rmt:folio250.dat");
   mod[j].setExecParam("OUTPUTFILE","bin:rmt:solfile"+j+".dat");
   mod[j].run();                       // Run the model
  }

  for(j=0;j<numpar;j++)
  {  
   xprd.waitForEvent();                // Wait for model termination
   xprd.dropNextEvent();               // Ignore termination event message
  }

     
  for(j=0;j<numpar;j++)
  {
   try {
    readSol("solfile"+j+".dat");      // Read+display result data
   } catch(IOException e) {
    System.out.println("Could not read file "+j);
    System.exit(1);
   }
   new File("solfile"+j+".dat").delete();
  }

  for(j=0;j<numpar;j++)
   mosel[j].disconnect();              // Disconnect remote instance
 }
} 

distfoliocbioev.c
/*******************************************************
   Mosel Example Problems
   ====================== 

   file distfoliocbioev.c
   ``````````````````````
   Running a Mosel model from a C application
   with data exchange between model and host application.
   (Use Mosel running remotely controlled via XPRD)
   - Using the bindrv utility -
   
   (c) 2011 Fair Isaac Corporation
       author: S. Heipcke, Oct. 2011, rev. Apr 2012
********************************************************/

/*
cc -I$MOSEL/include -L$MOSEL/lib distfoliocbioev.c -o distfoliocbioev -lpthread -lxprd -lbindrv -lxprnls
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xprd.h"
#include "bindrv.h"

#define NEWSOL 2
#define SOLREAD 3

static char datafile[10*1024];	 /* Memory block to store the output data */
                                 /* (using static size for simplicity's sake) */
static int datafilesize;

typedef struct
	{
	 char *buffer;
	 int mode;
	 int bufsize;
	 int curpos;
	} s_memfile;

          /* Array to receive solution values */
struct MySolArray
{
 char *ind;                       /*   index name */
 double val;                      /*   solution value */
 struct MySolArray *next;
};

struct MySolArray *solfrac;
struct MySolArray *solbuy;


/********************************************************
   Implementation of a file manager 
   This file manager accesses directly file 'solfile'
   in local memory block 
   Warning: concurrency not handled here!!!
 ********************************************************/

void* XPRD_CC my_open(void *ctx, char *filename, int, XPRDfct_data* fct_data, 
       XPRDfct_close* fct_close, XPRDfct_skip *fct_skip, char *msg, int msglen);
int XPRD_CC my_close(void *data);
int XPRD_CC my_read(void *data, char *buf, int size);
int XPRD_CC my_write(void *data, char *buf, int size);
int XPRD_CC outremote(void *data, char *buf, int size);

void* XPRD_CC my_open(void *ctx, char *filename, int mode, 
                      XPRDfct_data* fct_data, XPRDfct_close* fct_close, 
                      XPRDfct_skip *fct_skip, char *msg, int msglen)
{
 s_memfile *memfile;

 if(strcmp(filename,"outremote")==0)
 {
  if((mode&(XPRD_F_READ|XPRD_F_WRITE))!=XPRD_F_WRITE)
  {
   strncpy(msg, "'outremote' is write only.", msglen);
   return XPRD_FMGR_ERR;
  }
  else
  {
   *fct_data=outremote;
   *fct_close=NULL;
   return (void*)1;
  }
 }
 if(strcmp(filename,"solfile")==0)
 {
  if((memfile=malloc(sizeof(s_memfile)))==NULL)
  {
   strncpy(msg,"memory error",msglen);
   return XPRD_FMGR_ERR;
  }
  else
  {
   memfile->buffer=datafile;
   memfile->mode=mode&(XPRD_F_READ|XPRD_F_WRITE);      
   memfile->bufsize=(memfile->mode==XPRD_F_READ)?datafilesize:sizeof(datafile);
   memfile->curpos=0;
   *fct_data=(memfile->mode==XPRD_F_READ)?my_read:my_write;
   *fct_close=my_close;
   return memfile;
  }
 }

 else
  return NULL;               /*  Use default behaviour (open local file) */
}

/**** Release resources used by a memory file ****/
int XPRD_CC my_close(void *data)
{
 s_memfile *memfile;

 memfile=data;
 /* save size of datafile */
 if((memfile->mode==XPRD_F_WRITE)&&(memfile->buffer==datafile))
  datafilesize=memfile->curpos;
 free(data);
 return 0;
}

/**** Send data from a block of memory ****/
int XPRD_CC my_read(void *data,char *buf,int size)
{
 s_memfile *memfile;
 int l;

 memfile=data;
 if(memfile->curpos>=memfile->bufsize)        /* end of file */
  return 0;
 else
 if((l=memfile->bufsize-memfile->curpos)<=size)  /* last block */
 {
  memcpy(buf,memfile->buffer+memfile->curpos,l);
  memfile->curpos=memfile->bufsize;
  return l;
 }
 else
 {
  memcpy(buf,memfile->buffer+memfile->curpos,size);
  memfile->curpos+=size;
  return size;
 }
}

/**** Reading function with signature as required by the bin driver ****/
size_t my_fread(void *buf,size_t l,size_t nm,void *fd)
{
 return (my_read(fd,buf,nm*l)==l*nm)?nm:0;
}

/**** Store data in a block of memory ****/
int XPRD_CC my_write(void *data,char *buf,int size)
{
 s_memfile *memfile;
 memfile=data;
 if(memfile->curpos+size>=memfile->bufsize)   /* buffer overflow */
  return -1;
 else
 {
  memcpy(memfile->buffer+memfile->curpos,buf,size);
  memfile->curpos+=size;
  return size;
 }
}

/**** Display received message with a prefix ****/
int XPRD_CC outremote(void *data,char *buf,int size)
{
 printf("REMOTE: %.*s",size,buf);
 return size;
}


/********************************************************/
/* Using bindrv 
   Decode the binary file and display its content       */
/********************************************************/
void show_solution()
{
 s_memfile *f;
 s_bindrvctx bdrv;
 union { int i; double r; char b; char *str; BINDRV_LONG l;} val;
 char *index;
 struct MySolArray *solfracf,*solfracl,*solfracn;
 struct MySolArray *solbuyf,*solbuyl,*solbuyn;
 XPRDfct_data fct_data; 
 XPRDfct_close fct_close;
 XPRDfct_skip fct_skip;


 f=my_open(NULL,"solfile",XPRD_F_READ,&fct_data,&fct_close,&fct_skip,NULL,0);
 bdrv=bindrv_newreader(my_fread,f);


  while(bindrv_nexttoken(bdrv)>=0)
  {
   bindrv_getctrl(bdrv,&(val.i));         /* 'label' */
   bindrv_getstring(bdrv,&(val.str));
   if(strcmp(val.str,"RETSOL")==0)
   {
    free(val.str);
    bindrv_getreal(bdrv,&(val.r));
    printf("Total return: %g\n", val.r);
   } 
   else
   if(strcmp(val.str,"NUMSHARES")==0)
   {
    free(val.str);
    bindrv_getint(bdrv,&(val.i));
    printf("Number of shares: %d\n", val.i);
   } 
   else
   if(strcmp(val.str,"SOLCOUNT")==0)
   {
    free(val.str);
    bindrv_getint(bdrv,&(val.i));
    printf("Solution number: %d\n", val.i);
   } 
   else
   if(strcmp(val.str,"BUY")==0)
   {
    free(val.str);
    bindrv_getctrl(bdrv,&(val.i));    /* [ */
    bindrv_getctrl(bdrv,&(val.i));    /* ( or ] at end of list */
    solbuyf=NULL;
    while(val.i==BINDRV_CTRL_OPENNDX)
    {
     bindrv_getstring(bdrv,&index);
     bindrv_getctrl(bdrv,&(val.i));   /* ) */
     bindrv_getreal(bdrv,&(val.r));
     solbuyn = (struct MySolArray *)malloc(sizeof(struct MySolArray));
     solbuyn->next=NULL;
     if(solbuyf==NULL)
      solbuyf=solbuyl=solbuyn;
     else
     {
      solbuyl->next=solbuyn;
      solbuyl=solbuyn;
     }
     solbuyn->ind=index;
     solbuyn->val=val.r;
     bindrv_getctrl(bdrv,&(val.i));   /* ( or ] at end of list */
    }
    solbuy=solbuyf;
   }
   else
   if(strcmp(val.str,"FRAC")==0)
   {
    free(val.str);
    bindrv_getctrl(bdrv,&(val.i));    /* [ */
    bindrv_getctrl(bdrv,&(val.i));    /* ( or ] at end of list */
    solfracf=NULL;
    while(val.i==BINDRV_CTRL_OPENNDX)
    {
     bindrv_getstring(bdrv,&index);
     bindrv_getctrl(bdrv,&(val.i));   /* ) */
     bindrv_getreal(bdrv,&(val.r));
     solfracn = (struct MySolArray *)malloc(sizeof(struct MySolArray));
     solfracn->next=NULL;
     if(solfracf==NULL)
      solfracf=solfracl=solfracn;
     else
     {
      solfracl->next=solfracn;
      solfracl=solfracn;
     }
     solfracn->ind=index;
     solfracn->val=val.r;
     bindrv_getctrl(bdrv,&(val.i));   /* ( or ] at end of list */
    }
    solfrac=solfracf;
   }
   else
   {
    printf("Unexpected label: %s\n", val.str);
    free(val.str);
    exit(1);
   }
  }

 bindrv_delete(bdrv);                 /* Release bin reader */
 my_close(f);

 /* Print the solution values */
  solfracn=solfrac;
  solbuyn=solbuy;
  while(solfracn!=NULL && solbuyn!=NULL)
  {           /* This assumes that array indices are in the same order */
   printf(" %s: %g%% (%g)\n",  solfracn->ind, solfracn->val*100, solbuyn->val);
   solfracn=solfracn->next;
   solbuyn=solbuyn->next;
  }

  /* Clean up */
  solfracn=solfrac;
  while (solfracn!=NULL)
  {
   solfracn=solfrac->next;
   solfrac->next=NULL;
   free(solfrac->ind);
   free(solfrac);
   solfrac=solfracn;
  }
  solbuyn=solbuy;
  while (solbuyn!=NULL)
  {
   solbuyn=solbuy->next;
   solbuy->next=NULL;
   free(solbuy->ind);
   free(solbuy);
   solbuy=solbuyn;
  }

}

/********************************************************/

int main()
{
 char msg[256],params[1000];
 XPRDcontext xprd;
 XPRDmosel mosel;
 XPRDmodel mod,evmod;
 double maxrisk = 1.0/3;          /* Model parameter settings */
 double minreg = 0.2;
 double maxreg = 0.5;
 double maxsec = 0.25;
 double maxval = 0.2;
 double minval = 0.1;
 int maxnum = 15;
 double val;
 int i,evclass;

 sprintf(params, "MAXRISK=%g,MINREG=%g,MAXREG=%g,MAXSEC=%g,MAXVAL=%g,MINVAL=%g,MAXNUM=%d,DATAFILE='rmt:folio250.dat',OUTPUTFILE='bin:rmt:solfile'",
         maxrisk, minreg, maxreg, maxsec, maxval, minval, maxnum); 


 xprd=XPRDinit();                 /* Initialize XPRD */

          /* Create a new Mosel instance with a user-defined file manager */
 mosel=XPRDconnect(xprd, "", my_open, NULL, msg, sizeof(msg));
 if(mosel==NULL)
 {
   printf("Connection failed: %s\n",msg);
   return 1;
 }
 printf("Connected to:\n%s\n", XPRDbanner(mosel));
 printf("Host: %s\n", XPRDsysinfo(mosel,XPRD_SYS_NODE,msg,sizeof(msg)));

          /* Set error stream of the remote instance to a local file */
 if(XPRDsetdefstream(mosel, NULL, XPRD_F_ERROR, "rmt:err.txt")!=0)
  printf("Failed to change error stream.\n");

                                  /* Compile the model on the remote instance */
 if((i=XPRDcompmod(mosel,"","rmt:foliocbioev.mos","tmp:foliocbioev.bim",""))!=0)
 {
  printf("Compilation failed: Error %d\n",i);
  return 2;
 }
                                  /* Load the model */
 mod=XPRDloadmod(mosel, "tmp:foliocbioev.bim");
 if(mod==NULL)
 {
  printf("Failed to load model\n");
  return 3;
 }

          /* Redirect output stream of the model to the 'outremote' callback */
 if(XPRDsetdefstream(NULL,mod,XPRD_F_OUTPUT|XPRD_F_LINBUF, "rmt:outremote")!=0)
  printf("Failed to change output stream\n");

 XPRDrunmod(mod,params);          /* Run the model */
 do
 {
  XPRDwaitevent(xprd, 0);         /* Wait for an event */
  XPRDgetevent(xprd,&evmod,&evclass,&val);
   if (evclass==NEWSOL)
   {
     show_solution();             /* Decode & display solution data */
     XPRDsendevent(mod, SOLREAD, 0);
   }
 } while(evclass==NEWSOL);        /* Only other event sent by model is "END" */

  if(XPRDgetstatus(mod) != XPRD_RT_OK){
   printf("Error during model execution: %d\n", XPRDgetstatus(mod));
   return 4;
  }
  if(XPRDgetexitcode(mod) != 0){
   printf("Problem not optimal: %d\n", XPRDgetexitcode(mod));
   return 5;
  }                               /* Stop if no solution available */

 XPRDdisconnect(mosel);           /* Disconnect remote instance */
 
 XPRDfinish(xprd);                /* Release context */

 return 0;
}

distfoliocbioev.java
/*******************************************************
   Mosel Example Problems
   ====================== 

   file distfoliocbioev.java
   `````````````````````````
   Running a Mosel model from a Java application
   with data exchange between model and host application.
   (use Mosel running remotely controlled via XPRD)
   -- Coordination via Mosel events exchanged 
      between Mosel model and Java program    --
   
   (c) 2011 Fair Isaac Corporation
       author: Y.Colombani, July 2011
********************************************************/

import java.io.*;
import java.util.*;
import com.dashoptimization.*;

public class distfoliocbioev
{
 static byte solbuf[]=null;
 static final int NEWSOL=2;
 static final int SOLREAD=3;

/**
  * An extension of 'ByteArrayOutputStream' for saving the array on closing.
  */
 static class myByteArrayOutputStream extends ByteArrayOutputStream
 {
  public void close()
  {
   solbuf=toByteArray();
  }
 }

/**
  * This file manager will directly access the file 'solfile'
  * to a local ArrayStream object.
  * Warning: concurrency not handled here!!!
  */
 static class FileManager implements XPRDFileManager
 {
  public OutputStream openForWriting(String fname,int mode) throws IOException
  {
   if(fname.equals("solfile"))
   {
    return new myByteArrayOutputStream();
   }
   else
    return null;    // Name not found: use default behaviour (open local file)
  }
  public InputStream openForReading(String fname,int mode) throws IOException
  {
   return null;     // Use default behaviour (open local file)
  }
 }
                    // Class to receive solution values of decision variables
 public static class MySolArray
 {
  public String ind;                // index name
  public double val;                // solution value
  MySolArray(String i,double v)
  {
   ind=i;
   val=v;
  }
 }

// Decode the binary file and display its content
 static void showSolution() throws Exception
 {
  ByteArrayInputStream inbuf=new ByteArrayInputStream(solbuf);
  BinDrvReader bdrv=new BinDrvReader(inbuf);
  String label;
  String index;
  ArrayList<MySolArray> solfrac=new ArrayList<MySolArray>();
  ArrayList<MySolArray> solbuy=new ArrayList<MySolArray>();

  while(bdrv.nextToken()>=0)
  {
   bdrv.getControl();     // 'label'
   label=bdrv.getString();
   if(label.equals("RETSOL"))
    System.out.println("Total return: " + bdrv.getReal());
   else
   if(label.equals("NUMSHARES"))
    System.out.println("Number of shares: " + bdrv.getInt());
   else
   if(label.equals("SOLCOUNT"))
    System.out.println("Solution number: " + bdrv.getInt());
   else
   if(label.equals("BUY"))
   {
    bdrv.getControl();    // [
    while(bdrv.getControl()==BinDrvReader.CTRL_OPENNDX) // ( or ] at end of list
    {
     index=bdrv.getString();
     bdrv.getControl();   // )
     solbuy.add(new MySolArray(index,bdrv.getReal()));
    }
   }
   else
   if(label.equals("FRAC"))
   {
    bdrv.getControl();    // [
    while(bdrv.getControl()==BinDrvReader.CTRL_OPENNDX) // ( or ] at end of list
    {
     index=bdrv.getString();
     bdrv.getControl();   // )
     solfrac.add(new MySolArray(index,bdrv.getReal()));
    }
   }
   else
   {
    System.out.println("Unexpected label: "+label);
    System.exit(0);
   }
  }

  Iterator<MySolArray> ibuy=solbuy.iterator();
  Iterator<MySolArray> ifrac=solfrac.iterator();

  while(ibuy.hasNext() && ifrac.hasNext())
  {
   MySolArray buy=ibuy.next();
   MySolArray frac=ifrac.next();
   System.out.println(frac.ind + ": " + frac.val*100 + "% (" + 
       buy.val + ")");
  }
 }

 public static void main(String[] args) throws Exception
 {
  XPRD xprd=new XPRD();
  XPRDFileManager fmgr=new FileManager();
  XPRDMosel mosel;
  XPRDModel mod;
                    // Model parameter settings
  double maxrisk = 1.0/3;
  double minreg = 0.2;
  double maxreg = 0.5;
  double maxsec = 0.25;
  double maxval = 0.2;
  double minval = 0.1;
  int maxnum = 15;
  int val;

  try{
   mosel = xprd.connect("",fmgr);     // Create a new Mosel instance
  }catch(IOException e){
                System.out.println("IO error" + e.getMessage());
                throw new java.lang.Exception("Failed to connect");
  }

  try{
   mosel.compile("","rmt:foliocbioev.mos","tmp:foliocbioev.bim");
                                      // Compile the model (only required
                                      // during development phase, deployed
				      // application would only use BIM)
  }catch(XPRDCompileException e){
   System.out.println(e.getMessage());
   System.exit(1);
  }
  
  mod = mosel.loadModel("tmp:foliocbioev.bim");  // Load the model

                    // Pass model parameters through execution parameters
  mod.setExecParam("MAXRISK",maxrisk);
  mod.setExecParam("MINREG",minreg);
  mod.setExecParam("MAXREG",maxreg);
  mod.setExecParam("MAXSEC",maxsec);
  mod.setExecParam("MAXVAL",maxval);
  mod.setExecParam("MINVAL",minval);
  mod.setExecParam("MAXNUM",maxnum);
  mod.setExecParam("DATAFILE","rmt:folio250.dat");
  mod.setExecParam("OUTPUTFILE","bin:rmt:solfile");
  mod.run();                          // Run the model
  do
  {
   xprd.waitForEvent();               // Wait for event sent by model
   val=xprd.getNextEvent().eventClass;
   if (val==NEWSOL)
   {
     showSolution();                  // Decode & display solution data
     mod.sendEvent(SOLREAD,0);
   }
  } while (val==NEWSOL);
  

  if(mod.getExecStatus() != XPRDModel.RT_OK){
   throw new java.lang.Exception("Error during model execution ");
  }
  if(mod.getResult() != 0){
   throw new java.lang.Exception("Problem not optimal");
  }                                  // Stop if no solution available

  mosel.disconnect();                // Disconnect instance

 }
}


foliocbioev.mos
(!******************************************************
   Mosel Example Problems
   ======================

   file foliocbio.mos
   ``````````````````
   Modeling a MIP problem 
   to perform portfolio optimization.

   Same model as in foliomip3.mos.
   -- Defining an integer solution callback 
      to write out solution information to external program --
   -- Using events to coordinate solution writing/reading --
   
  (c) 2011 Fair Isaac Corporation
      author: S.Heipcke, July 2011, rev. Oct. 2012
*******************************************************!)

model "Portfolio optimization with MIP"
 uses "mmxprs"
 uses "mmjobs"

 parameters
  MAXRISK = 1/3                     ! Max. investment into high-risk values
  MINREG = 0.2                      ! Min. investment per geogr. region
  MAXREG = 0.5                      ! Max. investment per geogr. region
  MAXSEC = 0.25                     ! Max. investment per ind. sector
  MAXVAL = 0.2                      ! Max. investment per share
  MINVAL = 0.1                      ! Min. investment per share
  MAXNUM = 15                       ! Max. number of different assets
  DATAFILE = "folio250.dat"         ! File with problem data
  OUTPUTFILE = "sol10out.dat"       ! File for solution output
  FRACSOL = "FRAC"                  ! Locations for solution output
  BUYSOL = "BUY"
  NUMSHARES = "NUMSHARES"
  RETSOL = "RETSOL"
  SOLCOUNT = "SOLCOUNT"
 end-parameters

 forward public procedure printsol

 declarations
  SHARES,S: set of string            ! Set of shares
  RISK: set of string                ! Set of high-risk values among shares
  REGIONS: set of string             ! Geographical regions
  TYPES: set of string               ! Share types (ind. sectors)
  LOC: array(REGIONS) of set of string ! Sets of shares per geogr. region
  RET: array(SHARES) of real         ! Estimated return in investment
  SEC: array(TYPES) of set of string ! Sets of shares per industry sector
  NEWSOL = 2                         ! Code for "new solution" event 
 end-declarations

 initializations from DATAFILE
  RISK RET LOC SEC
 end-initializations

 declarations
  frac: array(SHARES) of mpvar      ! Fraction of capital used per share
  buy: array(SHARES) of mpvar       ! 1 if asset is in portfolio, 0 otherwise
 end-declarations

! Objective: total return
 Return:= sum(s in SHARES) RET(s)*frac(s) 

! Limit the percentage of high-risk values
 sum(s in RISK) frac(s) <= MAXRISK

! Limits on geographical distribution
 forall(r in REGIONS) do
  sum(s in LOC(r)) frac(s) >= MINREG
  sum(s in LOC(r)) frac(s) <= MAXREG
 end-do 

! Diversification across industry sectors
 forall(t in TYPES) sum(s in SEC(t)) frac(s) <= MAXSEC

! Spend all the capital
 sum(s in SHARES) frac(s) = 1
 
! Upper bounds on the investment per share
 forall(s in SHARES) frac(s) <= MAXVAL

! Limit the total number of assets
 sum(s in SHARES) buy(s) <= MAXNUM

 forall(s in SHARES) do
  buy(s) is_binary                  ! Turn variables into binaries
  frac(s) <= MAXVAL*buy(s)                 ! Linking the variables
  frac(s) >= MINVAL*buy(s)                 ! Linking the variables
 end-do


! Display Optimizer log
 setparam("XPRS_verbose", true)

! Adapt Mosel comparison tolerance to Optimizer feasibility tolerance
 setparam("zerotol", getparam("XPRS_feastol")/10)

! Set a MIP solution callback
 setcallback(XPRS_CB_INTSOL, "printsol")

! Solve the problem
 maximize(Return)

 if getprobstat <> XPRS_OPT then exit(1); end-if 
 
! printsol

! Solution output
 function getvalues(v: array(SHARES) of mpvar): array(S) of real
  forall(s in SHARES | v(s).sol<>0) returned(s):= v(s).sol  
 end-function

 public procedure printsol
  initializations to OUTPUTFILE
   evaluation of getparam("XPRS_MIPSOLS") as SOLCOUNT
   evaluation of sum(s in SHARES | buy(s).sol<>0) 1 as NUMSHARES
   evaluation of getsol(Return) as RETSOL
   evaluation of getvalues(frac) as FRACSOL
   evaluation of getvalues(buy) as BUYSOL
  end-initializations
  send(NEWSOL,0)   ! The solution is now ready to be read
  wait           ! Wait while master reads the solution to avoid overwriting
  dropnextevent  ! The master has finished reading the solution
 end-procedure

end-model 

© 2001-2019 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.