Switch to side-by-side view

--- a
+++ b/feasible_joint_stiffness/lrslib-062/lrsnashlib.c
@@ -0,0 +1,1122 @@
+/*******************************************************/
+/* lrsnashlib is a library of routines for computing   */
+/* computing all nash equilibria for two person games  */
+/* given by mxn payoff matrices A,B                    */
+/*                                                     */
+/*                                                     */
+/* Main user callable function is                      */
+/*         lrs_solve_nash(game *g)                     */
+/*                                                     */
+/* Requires lrsnashlib.h lrslib.h lrslib.c             */
+/*                                                     */
+/* Sample driver: lrsnash.c                            */
+/* Derived from nash.c in lrslib-060                   */
+/* by Terje Lensberg, October 26, 2015:                */
+/*******************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include "lrslib.h"
+#include "lrsnashlib.h"
+
+
+//========================================================================
+// Standard solver. Modified version of main() from lrsNash
+//========================================================================
+int lrs_solve_nash(game * g)
+{
+  lrs_dic *P1, *P2;             /* structure for holding current dictionary and indices */
+  lrs_dat *Q1, *Q2;             /* structure for holding static problem data            */
+
+  lrs_mp_vector output1;        /* holds one line of output; ray,vertex,facet,linearity */
+  lrs_mp_vector output2;        /* holds one line of output; ray,vertex,facet,linearity */
+  lrs_mp_matrix Lin;            /* holds input linearities if any are found             */
+  lrs_mp_matrix A2orig;
+  lrs_dic *P2orig;              /* we will save player 2's dictionary in getabasis      */
+
+  long *linindex;               /* for faster restart of player 2                       */
+
+  long col;                     /* output column index for dictionary                   */
+  long startcol = 0;
+  long prune = FALSE;           /* if TRUE, getnextbasis will prune tree and backtrack  */
+  long numequilib = 0;          /* number of nash equilibria found                      */
+  long oldnum = 0;
+
+/* global variables lrs_ifp and lrs_ofp are file pointers for input and output   */
+/* they default to stdin and stdout, but may be overidden by command line parms. */
+
+/*********************************************************************************/
+/* Step 1: Allocate lrs_dat, lrs_dic and set up the problem                      */
+/*********************************************************************************/
+  FirstTime=TRUE;                       /* This is done for each new game */
+
+  Q1 = lrs_alloc_dat("LRS globals");    /* allocate and init structure for static problem data */
+  if (Q1 == NULL) {
+    return;
+  }
+
+  Q1->nash = TRUE;
+  Q1->n = g->nstrats[ROW] + 2;
+  Q1->m = g->nstrats[ROW] + g->nstrats[COL] + 1;
+
+  Q1->debug = Debug_flag;
+  Q1->verbose = Verbose_flag;
+
+  P1 = lrs_alloc_dic(Q1);       /* allocate and initialize lrs_dic */
+  if (P1 == NULL) {
+    return;
+  }
+
+  BuildRep(P1, Q1, g, 1, 0);
+
+  output1 = lrs_alloc_mp_vector(Q1->n + Q1->m); /* output holds one line of output from dictionary     */
+
+  /* allocate and init structure for player 2's problem data */
+  Q2 = lrs_alloc_dat("LRS globals");
+  if (Q2 == NULL) {
+    return;
+  }
+
+  Q2->debug = Debug_flag;
+  Q2->verbose = Verbose_flag;
+
+  Q2->nash = TRUE;
+  Q2->n = g->nstrats[COL] + 2;
+  Q2->m = g->nstrats[ROW] + g->nstrats[COL] + 1;
+
+  P2orig = lrs_alloc_dic(Q2);   /* allocate and initialize lrs_dic */
+  if (P2orig == NULL) {
+    return;
+  }
+  BuildRep(P2orig, Q2, g, 0, 1);
+  A2orig = P2orig->A;
+
+  output2 = lrs_alloc_mp_vector(Q1->n + Q1->m); /* output holds one line of output from dictionary     */
+
+  linindex = calloc((P2orig->m + P2orig->d + 2), sizeof(long)); /* for next time */
+
+  fprintf(lrs_ofp, "\n");
+//  fprintf (lrs_ofp, "***** %ld %ld rational\n", Q1->n, Q2->n);
+
+/*********************************************************************************/
+/* Step 2: Find a starting cobasis from default of specified order               */
+/*         P1 is created to hold  active dictionary data and may be cached       */
+/*         Lin is created if necessary to hold linearity space                   */
+/*         Print linearity space if any, and retrieve output from first dict.    */
+/*********************************************************************************/
+
+  if (!lrs_getfirstbasis(&P1, Q1, &Lin, TRUE))
+    return 1;
+
+  if (Q1->dualdeg) {
+    printf("\n*Warning! Dual degenerate, ouput may be incomplete");
+    printf("\n*Recommendation: Add dualperturb option before maximize in first input file\n");
+  }
+
+  if (Q1->unbounded) {
+    printf("\n*Warning! Unbounded starting dictionary for p1, output may be incomplete");
+    printf("\n*Recommendation: Change/remove maximize option, or include bounds \n");
+  }
+
+  /* Pivot to a starting dictionary                      */
+  /* There may have been column redundancy               */
+  /* If so the linearity space is obtained and redundant */
+  /* columns are removed. User can access linearity space */
+  /* from lrs_mp_matrix Lin dimensions nredundcol x d+1  */
+
+  if (Q1->homogeneous && Q1->hull)
+    startcol++;                 /* col zero not treated as redundant   */
+
+  for (col = startcol; col < Q1->nredundcol; col++)     /* print linearity space               */
+    lrs_printoutput(Q1, Lin[col]);      /* Array Lin[][] holds the coeffs.     */
+
+/*********************************************************************************/
+/* Step 3: Terminate if lponly option set, otherwise initiate a reverse          */
+/*         search from the starting dictionary. Get output for each new dict.    */
+/*********************************************************************************/
+
+  /* We initiate reverse search from this dictionary       */
+  /* getting new dictionaries until the search is complete */
+  /* User can access each output line from output which is */
+  /* vertex/ray/facet from the lrs_mp_vector output         */
+  /* prune is TRUE if tree should be pruned at current node */
+  do {
+    prune = lrs_checkbound(P1, Q1);
+    if (!prune && lrs_getsolution(P1, Q1, output1, col)) {
+      oldnum = numequilib;
+      nash2_main(P1, Q1, P2orig, Q2, &numequilib, output2, linindex);
+      if (numequilib > oldnum || Q1->verbose) {
+        if (Q1->verbose)
+          prat(" \np2's obj value: ", P1->objnum, P1->objden);
+        lrs_nashoutput(Q1, output1, 1L);
+        fprintf(lrs_ofp, "\n");
+      }
+    }
+  }
+  while (lrs_getnextbasis(&P1, Q1, prune));
+
+  fprintf(lrs_ofp, "*Number of equilibria found: %ld", numequilib);
+  fprintf(lrs_ofp, "\n*Player 1: vertices=%ld bases=%ld pivots=%ld", Q1->count[1], Q1->count[2], Q1->count[3]);
+  fprintf(lrs_ofp, "\n*Player 2: vertices=%ld bases=%ld pivots=%ld", Q2->count[1], Q2->count[2], Q2->count[3]);
+
+  lrs_clear_mp_vector(output1, Q1->m + Q1->n);
+  lrs_clear_mp_vector(output2, Q1->m + Q1->n);
+
+  lrs_free_dic(P1, Q1);         /* deallocate lrs_dic */
+  lrs_free_dat(Q1);             /* deallocate lrs_dat */
+
+/* 2015.10.10  new code to clear P2orig */
+  Q2->Qhead = P2orig;           /* reset this or you crash free_dic */
+  P2orig->A = A2orig;           /* reset this or you crash free_dic */
+
+  lrs_free_dic(P2orig, Q2);     /* deallocate lrs_dic */
+  lrs_free_dat(Q2);             /* deallocate lrs_dat */
+
+  free(linindex);
+
+//  lrs_close("nash:");
+	fprintf(lrs_ofp, "\n");
+  return 0;
+}
+
+/*********************************************/
+/* end of nash driver                        */
+/*********************************************/
+
+/**********************************************************/
+/* nash2_main is a second driver used in computing nash   */
+/* equilibria on a second polytope interleaved with first */
+/**********************************************************/
+
+long nash2_main(lrs_dic * P1, lrs_dat * Q1, lrs_dic * P2orig,
+                lrs_dat * Q2, long *numequilib, lrs_mp_vector output, long linindex[])
+{
+
+  lrs_dic *P2;                  /* This can get resized, cached etc. Loaded from P2orig */
+  lrs_mp_matrix Lin;            /* holds input linearities if any are found             */
+  long col;                     /* output column index for dictionary                   */
+  long startcol = 0;
+  long prune = FALSE;           /* if TRUE, getnextbasis will prune tree and backtrack  */
+  long nlinearity;
+  long *linearity;
+  static long firstwarning = TRUE;      /* FALSE if dual deg warning for Q2 already given     */
+  static long firstunbounded = TRUE;    /* FALSE if dual deg warning for Q2 already given     */
+
+  long i, j;
+
+/* global variables lrs_ifp and lrs_ofp are file pointers for input and output   */
+/* they default to stdin and stdout, but may be overidden by command line parms. */
+
+/*********************************************************************************/
+/* Step 1: Allocate lrs_dat, lrs_dic and set up the problem                      */
+/*********************************************************************************/
+
+  P2 = lrs_getdic(Q2);
+  copy_dict(Q2, P2, P2orig);
+
+/* Here we take the linearities generated by the current vertex of player 1*/
+/* and append them to the linearity in player 2's input matrix             */
+/* next is the key magic linking player 1 and 2 */
+/* be careful if you mess with this!            */
+
+  linearity = Q2->linearity;
+  nlinearity = 0;
+  for (i = Q1->lastdv + 1; i <= P1->m; i++) {
+    if (!zero(P1->A[P1->Row[i]][0])) {
+      j = Q1->inequality[P1->B[i] - Q1->lastdv];
+      if (Q1->nlinearity == 0 || j < Q1->linearity[0])
+        linearity[nlinearity++] = j;
+    }
+  }
+/* add back in the linearity for probs summing to one */
+  if (Q1->nlinearity > 0)
+    linearity[nlinearity++] = Q1->linearity[0];
+
+/*sort linearities */
+  for (i = 1; i < nlinearity; i++)
+    reorder(linearity, nlinearity);
+
+  if (Q2->verbose) {
+    fprintf(lrs_ofp, "\np2: linearities %ld", nlinearity);
+    for (i = 0; i < nlinearity; i++)
+      fprintf(lrs_ofp, " %ld", linearity[i]);
+  }
+
+  Q2->nlinearity = nlinearity;
+  Q2->polytope = FALSE;
+
+/*********************************************************************************/
+/* Step 2: Find a starting cobasis from default of specified order               */
+/*         P2 is created to hold  active dictionary data and may be cached        */
+/*         Lin is created if necessary to hold linearity space                   */
+/*         Print linearity space if any, and retrieve output from first dict.    */
+/*********************************************************************************/
+
+  if (!lrs_getfirstbasis2(&P2, Q2, P2orig, &Lin, TRUE, linindex))
+    goto sayonara;
+  if (firstwarning && Q2->dualdeg) {
+    firstwarning = FALSE;
+    printf("\n*Warning! Dual degenerate, ouput may be incomplete");
+    printf("\n*Recommendation: Add dualperturb option before maximize in second input file\n");
+  }
+  if (firstunbounded && Q2->unbounded) {
+    firstunbounded = FALSE;
+    printf("\n*Warning! Unbounded starting dictionary for p2, output may be incomplete");
+    printf("\n*Recommendation: Change/remove maximize option, or include bounds \n");
+  }
+
+  /* Pivot to a starting dictionary                      */
+  /* There may have been column redundancy               */
+  /* If so the linearity space is obtained and redundant */
+  /* columns are removed. User can access linearity space */
+  /* from lrs_mp_matrix Lin dimensions nredundcol x d+1  */
+
+  if (Q2->homogeneous && Q2->hull)
+    startcol++;                 /* col zero not treated as redundant   */
+
+  /* for (col = startcol; col < Q2->nredundcol; col++) *//* print linearity space               */
+  /*lrs_printoutput (Q2, Lin[col]); *//* Array Lin[][] holds the coeffs.     */
+
+/*********************************************************************************/
+/* Step 3: Terminate if lponly option set, otherwise initiate a reverse          */
+/*         search from the starting dictionary. Get output for each new dict.    */
+/*********************************************************************************/
+
+  /* We initiate reverse search from this dictionary       */
+  /* getting new dictionaries until the search is complete */
+  /* User can access each output line from output which is */
+  /* vertex/ray/facet from the lrs_mp_vector output         */
+  /* prune is TRUE if tree should be pruned at current node */
+  do {
+    prune = lrs_checkbound(P2, Q2);
+    col = 0;
+    if (!prune && lrs_getsolution(P2, Q2, output, col)) {
+      if (Q2->verbose)
+        prat(" \np1's obj value: ", P2->objnum, P2->objden);
+      if (lrs_nashoutput(Q2, output, 2L))
+        (*numequilib)++;
+    }
+  }
+  while (lrs_getnextbasis(&P2, Q2, prune));
+
+sayonara:
+  lrs_free_dic(P2, Q2);
+  return 0;
+
+}
+
+/*********************************************/
+/* end of nash2_main                          */
+/*********************************************/
+
+/* In lrs_getfirstbasis and lrs_getnextbasis we use D instead of P */
+/* since the dictionary P may change, ie. &P in calling routine    */
+
+#define D (*D_p)
+
+long
+lrs_getfirstbasis2(lrs_dic ** D_p, lrs_dat * Q, lrs_dic * P2orig, lrs_mp_matrix * Lin, long no_output, long linindex[])
+/* gets first basis, FALSE if none              */
+/* P may get changed if lin. space Lin found    */
+/* no_output is TRUE supresses output headers   */
+{
+  long i, j, k;
+
+/* assign local variables to structures */
+
+  lrs_mp_matrix A;
+  long *B, *C, *Row, *Col;
+  long *inequality;
+  long *linearity;
+  long hull = Q->hull;
+  long m, d, lastdv, nlinearity, nredundcol;
+
+  static long ocount = 0;
+
+  m = D->m;
+  d = D->d;
+  lastdv = Q->lastdv;
+
+  nredundcol = 0L;              /* will be set after getabasis        */
+  nlinearity = Q->nlinearity;   /* may be reset if new linearity read */
+  linearity = Q->linearity;
+
+  A = D->A;
+  B = D->B;
+  C = D->C;
+  Row = D->Row;
+  Col = D->Col;
+  inequality = Q->inequality;
+
+/* default is to look for starting cobasis using linearies first, then     */
+/* filling in from last rows of input as necessary                         */
+/* linearity array is assumed sorted here                                  */
+/* note if restart/given start inequality indices already in place         */
+/* from nlinearity..d-1                                                    */
+
+  for (i = 0; i < nlinearity; i++)      /* put linearities first in the order */
+    inequality[i] = linearity[i];
+
+  k = 0;                        /* index for linearity array   */
+
+  if (Q->givenstart)
+    k = d;
+  else
+    k = nlinearity;
+  for (i = m; i >= 1; i--) {
+    j = 0;
+    while (j < k && inequality[j] != i)
+      j++;                      /* see if i is in inequality  */
+    if (j == k)
+      inequality[k++] = i;
+  }
+  if (Q->debug) {
+    fprintf(lrs_ofp, "\n*Starting cobasis uses input row order");
+    for (i = 0; i < m; i++)
+      fprintf(lrs_ofp, " %ld", inequality[i]);
+  }
+
+  if (!Q->maximize && !Q->minimize)
+    for (j = 0; j <= d; j++)
+      itomp(ZERO, A[0][j]);
+
+/* Now we pivot to standard form, and then find a primal feasible basis       */
+/* Note these steps MUST be done, even if restarting, in order to get         */
+/* the same index/inequality correspondance we had for the original prob.     */
+/* The inequality array is used to give the insertion order                   */
+/* and is defaulted to the last d rows when givenstart=FALSE                  */
+
+  if (!getabasis2(D, Q, P2orig, inequality, linindex)) {
+    return FALSE;
+  }
+
+  if (Q->debug) {
+    fprintf(lrs_ofp, "\nafter getabasis2");
+    printA(D, Q);
+  }
+  nredundcol = Q->nredundcol;
+  lastdv = Q->lastdv;
+  d = D->d;
+
+/********************************************************************/
+/* now we start printing the output file  unless no output requested */
+/********************************************************************/
+  if (!no_output || Q->debug) {
+    fprintf(lrs_ofp, "\nV-representation");
+
+/* Print linearity space                 */
+/* Don't print linearity if first column zero in hull computation */
+
+    k = 0;
+
+    if (nredundcol > k) {
+      fprintf(lrs_ofp, "\nlinearity %ld ", nredundcol - k);     /*adjust nredundcol for homog. */
+      for (i = 1; i <= nredundcol - k; i++)
+        fprintf(lrs_ofp, " %ld", i);
+    }                           /* end print of linearity space */
+
+    fprintf(lrs_ofp, "\nbegin");
+    fprintf(lrs_ofp, "\n***** %ld rational", Q->n);
+
+  }                             /* end of if !no_output .......   */
+
+/* Reset up the inequality array to remember which index is which input inequality */
+/* inequality[B[i]-lastdv] is row number of the inequality with index B[i]              */
+/* inequality[C[i]-lastdv] is row number of the inequality with index C[i]              */
+
+  for (i = 1; i <= m; i++)
+    inequality[i] = i;
+  if (nlinearity > 0) {         /* some cobasic indices will be removed */
+    for (i = 0; i < nlinearity; i++)    /* remove input linearity indices */
+      inequality[linearity[i]] = 0;
+    k = 1;                      /* counter for linearities         */
+    for (i = 1; i <= m - nlinearity; i++) {
+      while (k <= m && inequality[k] == 0)
+        k++;                    /* skip zeroes in corr. to linearity */
+      inequality[i] = inequality[k++];
+    }
+  }                             /* end if linearity */
+  if (Q->debug) {
+    fprintf(lrs_ofp, "\ninequality array initialization:");
+    for (i = 1; i <= m - nlinearity; i++)
+      fprintf(lrs_ofp, " %ld", inequality[i]);
+  }
+  if (nredundcol > 0) {
+    const unsigned int Qn = Q->n;
+    *Lin = lrs_alloc_mp_matrix(nredundcol, Qn);
+
+    for (i = 0; i < nredundcol; i++) {
+      if (!(Q->homogeneous && Q->hull && i == 0)) {     /* skip redund col 1 for homog. hull */
+        lrs_getray(D, Q, Col[0], D->C[0] + i - hull, (*Lin)[i]);        /* adjust index for deletions */
+      }
+
+      if (!removecobasicindex(D, Q, 0L)) {
+        lrs_clear_mp_matrix(*Lin, nredundcol, Qn);
+        return FALSE;
+      }
+    }
+  }                             /* end if nredundcol > 0 */
+
+  if (Q->verbose) {
+    fprintf(lrs_ofp, "\nNumber of pivots for starting dictionary: %ld", Q->count[3]);
+    ocount = Q->count[3];
+  }
+
+/* Do dual pivots to get primal feasibility */
+  if (!primalfeasible(D, Q)) {
+    if (Q->verbose) {
+      fprintf(lrs_ofp, "\nNumber of pivots for feasible solution: %ld", Q->count[3]);
+      fprintf(lrs_ofp, " - No feasible solution");
+      ocount = Q->count[3];
+    }
+    return FALSE;
+  }
+
+  if (Q->verbose) {
+    fprintf(lrs_ofp, "\nNumber of pivots for feasible solution: %ld", Q->count[3]);
+    ocount = Q->count[3];
+  }
+
+/* Now solve LP if objective function was given */
+  if (Q->maximize || Q->minimize) {
+    Q->unbounded = !lrs_solvelp(D, Q, Q->maximize);
+
+    /* check to see if objective is dual degenerate */
+    j = 1;
+    while (j <= d && !zero(A[0][j]))
+      j++;
+    if (j <= d)
+      Q->dualdeg = TRUE;
+  }
+  else
+/* re-initialize cost row to -det */
+  {
+    for (j = 1; j <= d; j++) {
+      copy(A[0][j], D->det);
+      storesign(A[0][j], NEG);
+    }
+
+    itomp(ZERO, A[0][0]);       /* zero optimum objective value */
+  }
+
+/* reindex basis to 0..m if necessary */
+/* we use the fact that cobases are sorted by index value */
+  if (Q->debug)
+    printA(D, Q);
+  while (C[0] <= m) {
+    i = C[0];
+    //j = inequality[B[i] - lastdv];
+    //inequality[B[i] - lastdv] = inequality[C[0] - lastdv];
+    //inequality[C[0] - lastdv] = j;
+    C[0] = B[i];
+    B[i] = i;
+    reorder1(C, Col, ZERO, d);
+  }
+
+  if (Q->debug) {
+    fprintf(lrs_ofp, "\n*Inequality numbers for indices %ld .. %ld : ", lastdv + 1, m + d);
+    for (i = 1; i <= m - nlinearity; i++)
+      fprintf(lrs_ofp, " %ld ", inequality[i]);
+    printA(D, Q);
+  }
+
+  if (Q->restart) {
+    if (Q->debug)
+      fprintf(lrs_ofp, "\nPivoting to restart co-basis");
+    if (!restartpivots(D, Q))
+      return FALSE;
+    D->lexflag = lexmin(D, Q, ZERO);    /* see if lexmin basis */
+    if (Q->debug)
+      printA(D, Q);
+  }
+/* Check to see if necessary to resize */
+  if (Q->inputd > D->d)
+    *D_p = resize(D, Q);
+
+  return TRUE;
+}
+
+/********* end of lrs_getfirstbasis  ***************/
+long getabasis2(lrs_dic * P, lrs_dat * Q, lrs_dic * P2orig, long order[], long linindex[])
+
+/* Pivot Ax<=b to standard form */
+/*Try to find a starting basis by pivoting in the variables x[1]..x[d]        */
+/*If there are any input linearities, these appear first in order[]           */
+/* Steps: (a) Try to pivot out basic variables using order                    */
+/*            Stop if some linearity cannot be made to leave basis            */
+/*        (b) Permanently remove the cobasic indices of linearities           */
+/*        (c) If some decision variable cobasic, it is a linearity,           */
+/*            and will be removed.                                            */
+{
+/* 2015.10.10 linindex now preallocated and received as parameter so we can free it */
+
+//  static long firsttime = TRUE; /* stays true until first valid dictionary built */
+
+  long i, j, k;
+/* assign local variables to structures */
+  lrs_mp_matrix A = P->A;
+  long *B = P->B;
+  long *C = P->C;
+  long *Row = P->Row;
+  long *Col = P->Col;
+  long *linearity = Q->linearity;
+  long *redundcol = Q->redundcol;
+  long m, d, nlinearity;
+  long nredundcol = 0L;         /* will be calculated here */
+
+  m = P->m;
+  d = P->d;
+  nlinearity = Q->nlinearity;
+//2015.9.15
+  /* after first time we update the change in linearities from the last time, saving many pivots */
+  if (!FirstTime) {
+    for (i = 1; i <= m + d; i++)
+      linindex[i] = FALSE;
+    if (Q->debug)
+      fprintf(lrs_ofp, "\nlindex =");
+    for (i = 0; i < nlinearity; i++) {
+      linindex[d + linearity[i]] = TRUE;
+      if (Q->debug)
+        fprintf(lrs_ofp, "  %ld", d + linearity[i]);
+    }
+
+    for (i = 1; i <= m; i++) {
+      if (linindex[B[i]]) {     /* pivot out unwanted linearities */
+        k = 0;
+        while (k < d && (linindex[C[k]] || zero(A[Row[i]][Col[k]])))
+          k++;
+
+        if (k < d) {
+          j = i;                /* note this index changes in update, cannot use i!) */
+
+          if (C[k] > B[j])      /* decrease i or we may skip a linearity */
+            i--;
+          pivot(P, Q, j, k);
+          update(P, Q, &j, &k);
+        }
+        else {
+          /* this is not necessarily an error, eg. two identical rows/cols in payoff matrix */
+          if (!zero(A[Row[i]][0])) {    /* error condition */
+            if (Q->debug || Q->verbose) {
+              fprintf(lrs_ofp, "\n*Infeasible linearity i=%ld B[i]=%ld", i, B[i]);
+              if (Q->debug)
+                printA(P, Q);
+            }
+            return (FALSE);
+          }
+          if (Q->debug || Q->verbose) {
+            fprintf(lrs_ofp, "\n*Couldn't remove linearity i=%ld B[i]=%ld", i, B[i]);
+          }
+        }
+
+      }                         /* if linindex */
+    }                           /* for i   .. */
+  }
+  else {                        /* we have not had a successful dictionary built from the given linearities */
+
+/* standard lrs processing is done on only the first call to getabasis2 */
+
+    if (Q->debug) {
+      fprintf(lrs_ofp, "\ngetabasis from inequalities given in order");
+      for (i = 0; i < m; i++)
+        fprintf(lrs_ofp, " %ld", order[i]);
+    }
+    for (j = 0; j < m; j++) {
+      i = 0;
+      while (i <= m && B[i] != d + order[j])
+        i++;                    /* find leaving basis index i */
+      if (j < nlinearity && i > m) {    /* cannot pivot linearity to cobasis */
+        if (Q->debug)
+          printA(P, Q);
+#ifndef LRS_QUIET
+        fprintf(lrs_ofp, "\nCannot find linearity in the basis");
+#endif
+        return FALSE;
+      }
+      if (i <= m) {             /* try to do a pivot */
+        k = 0;
+        while (C[k] <= d && zero(A[Row[i]][Col[k]]))
+          k++;
+
+        if (C[k] <= d) {
+          pivot(P, Q, i, k);
+          update(P, Q, &i, &k);
+        }
+        else if (j < nlinearity) {      /* cannot pivot linearity to cobasis */
+          if (zero(A[Row[i]][0])) {
+#ifndef LRS_QUIET
+            fprintf(lrs_ofp, "\n*Input linearity in row %ld is redundant--skipped", order[j]);
+#endif
+            linearity[j] = 0;
+          }
+          else {
+            if (Q->debug)
+              printA(P, Q);
+            if (Q->debug || Q->verbose)
+              fprintf(lrs_ofp, "\nInconsistent linearities");
+            return FALSE;
+          }
+        }                       /* end if j < nlinearity */
+
+      }                         /* end of if i <= m .... */
+    }                           /* end of for   */
+
+/* update linearity array to get rid of redundancies */
+    i = 0;
+    k = 0;                      /* counters for linearities         */
+    while (k < nlinearity) {
+      while (k < nlinearity && linearity[k] == 0)
+        k++;
+      if (k < nlinearity)
+        linearity[i++] = linearity[k++];
+    }
+
+    nlinearity = i;
+/* lrs bug fix, 2009.6.27, nash 2015.9.16 */
+    Q->nlinearity = i;
+
+/* column dependencies now can be recorded  */
+/* redundcol contains input column number 0..n-1 where redundancy is */
+    k = 0;
+    while (k < d && C[k] <= d) {
+      if (C[k] <= d)            /* decision variable still in cobasis */
+        redundcol[nredundcol++] = C[k] - Q->hull;       /* adjust for hull indices */
+      k++;
+    }
+
+/* now we know how many decision variables remain in problem */
+    Q->nredundcol = nredundcol;
+    Q->lastdv = d - nredundcol;
+/* 2015.9.15 bug fix : we needed first *successful* time */
+    FirstTime = FALSE;
+  }                             /* else firsttime ... we have built a dictionary from the given linearities */
+
+  /* we continue from here after loading dictionary */
+
+  if (Q->debug) {
+    fprintf(lrs_ofp, "\nend of first phase of getabasis2: ");
+    fprintf(lrs_ofp, "lastdv=%ld nredundcol=%ld", Q->lastdv, Q->nredundcol);
+    fprintf(lrs_ofp, "\nredundant cobases:");
+    for (i = 0; i < nredundcol; i++)
+      fprintf(lrs_ofp, " %ld", redundcol[i]);
+    printA(P, Q);
+  }
+
+/* here we save dictionary for use next time, *before* we resize */
+
+  copy_dict(Q, P2orig, P);
+
+/* Remove linearities from cobasis for rest of computation */
+/* This is done in order so indexing is not screwed up */
+
+  for (i = 0; i < nlinearity; i++) {    /* find cobasic index */
+    k = 0;
+    while (k < d && C[k] != linearity[i] + d)
+      k++;
+    if (k >= d) {
+      if (Q->debug || Q->verbose) {
+        fprintf(lrs_ofp, "\nCould not remove cobasic index");
+      }
+      /* not neccesarily an error as eg., could be repeated row/col in payoff */
+    }
+    else {
+      removecobasicindex(P, Q, k);
+      d = P->d;
+    }
+  }
+  if (Q->debug && nlinearity > 0)
+    printA(P, Q);
+/* set index value for first slack variable */
+
+/* Check feasability */
+  if (Q->givenstart) {
+    i = Q->lastdv + 1;
+    while (i <= m && !negative(A[Row[i]][0]))
+      i++;
+    if (i <= m)
+      fprintf(lrs_ofp, "\n*Infeasible startingcobasis - will be modified");
+  }
+  return TRUE;
+}                               /*  end of getabasis2 */
+
+long lrs_nashoutput(lrs_dat * Q, lrs_mp_vector output, long player)
+{
+  long i;
+  long origin = TRUE;
+
+/* do not print the origin for either player */
+  for (i = 1; i < Q->n; i++)
+    if (!zero(output[i]))
+      origin = FALSE;
+
+  if (origin)
+    return FALSE;
+
+  fprintf(lrs_ofp, "%ld ", player);
+  for (i = 1; i < Q->n; i++)
+    prat("", output[i], output[0]);
+  fprintf(lrs_ofp, "\n");
+  fflush(lrs_ofp);
+  return TRUE;
+}                               /* end lrs_nashoutput */
+
+
+
+//========================================================================
+// Old style solver. Included for backward compatibility
+//========================================================================
+int lrs_solve_nash_legacy (int argc, char *argv[])
+// Handles legacy input files
+{
+  lrs_dic *P1,*P2;		/* structure for holding current dictionary and indices */
+  lrs_dat *Q1,*Q2;		/* structure for holding static problem data            */
+
+  lrs_mp_vector output1;	/* holds one line of output; ray,vertex,facet,linearity */
+  lrs_mp_vector output2;	/* holds one line of output; ray,vertex,facet,linearity */
+  lrs_mp_matrix Lin;		/* holds input linearities if any are found             */
+  lrs_mp_matrix A2orig;
+  lrs_dic *P2orig;              /* we will save player 2's dictionary in getabasis      */
+
+  long *linindex;               /* for faster restart of player 2                       */
+
+  long col;			/* output column index for dictionary                   */
+  long startcol = 0;
+  long prune = FALSE;		/* if TRUE, getnextbasis will prune tree and backtrack  */
+  long numequilib=0;            /* number of nash equilibria found                      */
+  long oldnum=0;                                                                            
+
+
+/* global variables lrs_ifp and lrs_ofp are file pointers for input and output   */
+/* they default to stdin and stdout, but may be overidden by command line parms. */
+
+  if(argc <= 2 )
+  { printf("Usage: %s input1 input2 [outputfile]     \n", argv[0]);
+	  return 1;
+  }
+
+/***************************************************
+ Step 0: 
+  Do some global initialization that should only be done once,
+  no matter how many lrs_dat records are allocated. db
+
+***************************************************/
+
+  if ( !lrs_init ("\n*nash:"))
+    return 1;
+  printf("\n");
+  printf(AUTHOR);
+
+/*********************************************************************************/
+/* Step 1: Allocate lrs_dat, lrs_dic and set up the problem                      */
+/*********************************************************************************/
+
+
+  Q1 = lrs_alloc_dat ("LRS globals");	/* allocate and init structure for static problem data */
+
+  if (Q1 == NULL)
+    return 1;
+  Q1->nash=TRUE;
+
+  if (!lrs_read_dat (Q1, argc, argv))	/* read first part of problem data to get dimensions   */
+    return 1;                   	/* and problem type: H- or V- input representation     */
+
+  P1 = lrs_alloc_dic (Q1);	/* allocate and initialize lrs_dic                     */
+  if (P1 == NULL)
+    return 1;
+
+  if (!lrs_read_dic (P1, Q1))	/* read remainder of input to setup P1 and Q1           */
+    return 1;
+
+  output1 = lrs_alloc_mp_vector (Q1->n + Q1->m);   /* output holds one line of output from dictionary     */
+
+  fclose(lrs_ifp);
+
+/* allocate and init structure for player 2's problem data                                   */
+
+  printf ("\n*Second input taken from file %s\n", argv[2]);
+  Q2 = lrs_alloc_dat ("LRS globals"); 
+  if (Q2 == NULL)
+          return 1;
+
+  Q2->nash=TRUE;
+
+  if (!lrs_read_dat (Q2, 2, argv))	/* read first part of problem data to get dimensions   */
+    return 1;                   	/* and problem type: H- or V- input representation     */
+
+  if (Q2->nlinearity > 0)
+      free(Q2->linearity);               /* we will start again */
+  Q2->linearity  = CALLOC ((Q2->m + 2), sizeof (long));
+
+  P2orig = lrs_alloc_dic (Q2);	     /* allocate and initialize lrs_dic                     */
+  if (P2orig == NULL)
+         return 1;
+  if (!lrs_read_dic (P2orig, Q2))        /* read remainder of input to setup P2 and Q2          */
+    return 1;
+  A2orig = P2orig->A;
+
+  output2 = lrs_alloc_mp_vector (Q1->n + Q1->m);     /* output holds one line of output from dictionary     */
+
+  linindex = calloc ((P2orig->m + P2orig->d + 2), sizeof (long)); /* for next time*/
+
+  fprintf (lrs_ofp, "\n***** %ld %ld rational\n", Q1->n, Q2->n);
+
+
+/*********************************************************************************/
+/* Step 2: Find a starting cobasis from default of specified order               */
+/*         P1 is created to hold  active dictionary data and may be cached       */
+/*         Lin is created if necessary to hold linearity space                   */
+/*         Print linearity space if any, and retrieve output from first dict.    */
+/*********************************************************************************/
+
+  if (!lrs_getfirstbasis (&P1, Q1, &Lin, TRUE))
+    return 1;
+
+  if (Q1->dualdeg)
+     {
+      printf("\n*Warning! Dual degenerate, ouput may be incomplete");
+      printf("\n*Recommendation: Add dualperturb option before maximize in first input file\n");
+     }
+
+  if (Q1->unbounded)
+     {
+      printf("\n*Warning! Unbounded starting dictionary for p1, output may be incomplete");
+      printf("\n*Recommendation: Change/remove maximize option, or include bounds \n");
+     }
+
+  /* Pivot to a starting dictionary                      */
+  /* There may have been column redundancy               */
+  /* If so the linearity space is obtained and redundant */
+  /* columns are removed. User can access linearity space */
+  /* from lrs_mp_matrix Lin dimensions nredundcol x d+1  */
+
+
+
+  if (Q1->homogeneous && Q1->hull)
+    startcol++;			/* col zero not treated as redundant   */
+
+  for (col = startcol; col < Q1->nredundcol; col++)	/* print linearity space               */
+    lrs_printoutput (Q1, Lin[col]);	/* Array Lin[][] holds the coeffs.     */
+
+/*********************************************************************************/
+/* Step 3: Terminate if lponly option set, otherwise initiate a reverse          */
+/*         search from the starting dictionary. Get output for each new dict.    */
+/*********************************************************************************/
+
+  /* We initiate reverse search from this dictionary       */
+  /* getting new dictionaries until the search is complete */
+  /* User can access each output line from output which is */
+  /* vertex/ray/facet from the lrs_mp_vector output         */
+  /* prune is TRUE if tree should be pruned at current node */
+
+
+  do
+    {
+      prune=lrs_checkbound(P1,Q1);
+      if (!prune && lrs_getsolution (P1, Q1, output1, col))
+	{ 
+           oldnum=numequilib;
+           nash2_main(P1,Q1,P2orig,Q2,&numequilib,output2,linindex);
+	   if (numequilib > oldnum || Q1->verbose)
+	      {
+                if(Q1->verbose)
+                  prat(" \np2's obj value: ",P1->objnum,P1->objden);
+                lrs_nashoutput (Q1, output1, 1L);
+       	        fprintf (lrs_ofp, "\n");
+	      }
+	}
+    }
+  while (lrs_getnextbasis (&P1, Q1, prune));
+
+  fprintf(lrs_ofp,"\n*Number of equilibria found: %ld",numequilib);
+  fprintf (lrs_ofp,"\n*Player 1: vertices=%ld bases=%ld pivots=%ld", Q1->count[1],  Q1->count[2],Q1->count[3]);
+  fprintf (lrs_ofp,"\n*Player 2: vertices=%ld bases=%ld pivots=%ld", Q2->count[1],  Q2->count[2],Q2->count[3]);
+
+  lrs_clear_mp_vector(output1, Q1->m + Q1->n);
+  lrs_clear_mp_vector(output2, Q1->m + Q1->n);
+
+  lrs_free_dic (P1,Q1);          /* deallocate lrs_dic */
+  lrs_free_dat (Q1);             /* deallocate lrs_dat */
+
+/* 2015.10.10  new code to clear P2orig */
+  Q2->Qhead = P2orig;                 /* reset this or you crash free_dic */
+  P2orig->A=A2orig;                   /* reset this or you crash free_dic */
+
+  lrs_free_dic (P2orig,Q2);     /* deallocate lrs_dic */
+  lrs_free_dat (Q2);            /* deallocate lrs_dat */
+
+  free (linindex);
+
+  lrs_close ("nash:");
+
+  return 0;
+}
+
+/*********************************************/
+/* end of nash driver                        */
+/*********************************************/
+
+
+
+//==========================================================================
+//   Building the problem representations (adapted from Gambit-enummixed)
+//==========================================================================
+
+//
+// These two functions are based upon the program setupnash.c from the
+// lrslib distribution, and the user's guide documentation.
+// There are two separate functions, one for each player's problem.
+// According to the user's guide, the ordering of the constraint rows
+// is significant, and differs between the players; for player 1's problem
+// the nonnegativity constraints come first, whereas for player 2's problem
+// they appear later.  Experiments suggest this is in fact true, and
+// reversing them breaks something.
+//
+
+//----------------------------------------------------------------------------------------//
+void FillNonnegativityRows(lrs_dic * P, lrs_dat * Q, int firstRow, int lastRow, int n)
+{
+  const int MAXCOL = 1000;      /* maximum number of columns */
+  long num[MAXCOL], den[MAXCOL];
+  long row, col;
+
+  for (row = firstRow; row <= lastRow; row++) {
+    num[0] = 0;
+    den[0] = 1;
+
+    for (col = 1; col < n; col++) {
+      num[col] = (row - firstRow + 1 == col) ? 1 : 0;
+      den[col] = 1;
+    }
+    lrs_set_row(P, Q, row, num, den, GE);
+  }
+}
+
+//----------------------------------------------------------------------------------------//
+void FillConstraintRows(lrs_dic * P, lrs_dat * Q, const game * g, int p1, int p2, int firstRow)
+{
+  const int MAXCOL = 1000;      /* maximum number of columns */
+  long num[MAXCOL], den[MAXCOL];
+  ratnum x;
+  int row, s, t;
+
+  for (row = firstRow; row < firstRow + g->nstrats[p1]; row++) {
+    num[0] = 0;
+    den[0] = 1;
+    s = row - firstRow;
+    for (t = 0; t < g->nstrats[p2]; t++) {
+      x = p1 == ROW ? g->payoff[s][t][p1] : g->payoff[t][s][p1];
+      num[t + 1] = -x.num;
+      den[t + 1] =  x.den;
+    }
+    num[g->nstrats[p2] + 1] = 1;
+    den[g->nstrats[p2] + 1] = 1;
+    lrs_set_row(P, Q, row, num, den, GE);
+  }
+}
+
+//----------------------------------------------------------------------------------------//
+void FillLinearityRow(lrs_dic * P, lrs_dat * Q, int m, int n)
+{
+  const int MAXCOL = 1000;      /* maximum number of columns */
+  long num[MAXCOL], den[MAXCOL];
+  int i;
+
+  num[0] = -1;
+  den[0] = 1;
+
+  for (i = 1; i < n - 1; i++) {
+    num[i] = 1;
+    den[i] = 1;
+  }
+
+  num[n - 1] = 0;
+  den[n - 1] = 1;
+
+  lrs_set_row(P, Q, m, num, den, EQ);
+}
+
+//
+// TL added this to get first row of ones. Don't know if it's needed
+//----------------------------------------------------------------------------------------//
+void FillFirstRow(lrs_dic * P, lrs_dat * Q, int n)
+{
+  const int MAXCOL = 1000;      /* maximum number of columns */
+  long num[MAXCOL], den[MAXCOL];
+  int i;
+
+  for (i = 0; i < n; i++) {
+    num[i] = 1;
+    den[i] = 1;
+  }
+  lrs_set_row(P, Q, 0, num, den, GE);
+}
+
+//
+// Build the H-representation for player p1
+//----------------------------------------------------------------------------------------//
+void BuildRep(lrs_dic * P, lrs_dat * Q, const game * g, int p1, int p2)
+{
+  long m = Q->m;                /* number of inequalities      */
+  long n = Q->n;
+
+  if (p1 == 0) {
+    FillConstraintRows(P, Q, g, p1, p2, 1);
+    FillNonnegativityRows(P, Q, g->nstrats[p1] + 1, g->nstrats[ROW] + g->nstrats[COL], n);
+  }
+  else {
+    FillNonnegativityRows(P, Q, 1, g->nstrats[p2], n);
+    FillConstraintRows(P, Q, g, p1, p2, g->nstrats[p2] + 1);    // 1 here
+  }
+  FillLinearityRow(P, Q, m, n);
+
+// TL added this to get first row of ones. (Is this necessary?)
+  FillFirstRow(P, Q, n);
+}
+
+//----------------------------------------------------------------------------------------//
+void printGame(game * g)
+{
+  int s, t;
+        char out[2][MAXINPUT];
+  fprintf(lrs_ofp, "\n--------------------------------------------------------------------------------\n");
+  fprintf(lrs_ofp, "%s payoff matrix:\n", ((gInfo *)g->aux)->name);
+  for (s = 0; s < g->nstrats[ROW]; s++) {
+    for (t = 0; t < g->nstrats[COL]; t++) {
+                        if(g->payoff[s][t][ROW].den == 1)
+                                sprintf(out[ROW], "%ld,", g->payoff[s][t][ROW].num);
+                        else
+                                sprintf(out[ROW], "%ld/%ld,", g->payoff[s][t][ROW].num, g->payoff[s][t][ROW].den);
+                        if(g->payoff[s][t][COL].den == 1)
+                                sprintf(out[COL], "%ld", g->payoff[s][t][COL].num);
+                        else
+                                sprintf(out[COL], "%ld/%ld", g->payoff[s][t][COL].num, g->payoff[s][t][COL].den);
+                        fprintf(lrs_ofp, "%*s%-*s  ", ((gInfo *)g->aux)->fwidth[t][ROW]+1, out[ROW], ((gInfo *)g->aux)->fwidth[t][COL], out[COL]);
+    }
+    fprintf(lrs_ofp, "\n");
+  }
+  fprintf(lrs_ofp, "\nNash equilibria:\n");
+  fflush(lrs_ofp);
+}
+
+// Functions to set field widths for pretty printing of payoff matrices
+void setFwidth(game *g, int len) {
+        int pos, t;
+  for (t = 0; t < g->nstrats[COL]; t++)
+        for (pos = 0; pos < 2; pos++)
+                        ((gInfo *)g->aux)->fwidth[t][pos] = len;
+}
+
+void initFwidth(game *g) {
+        int pos, t;
+  for (t = 0; t < g->nstrats[COL]; t++)
+        for (pos = 0; pos < 2; pos++)
+                        ((gInfo *)g->aux)->fwidth[t][pos] = 0;
+}
+
+void updateFwidth(game *g, int col, int pos, char *str) {
+        int len = strlen(str);
+        if(len > ((gInfo *)g->aux)->fwidth[col][pos])
+                ((gInfo *)g->aux)->fwidth[col][pos] = len;
+}
+
+/******************** end of lrsnashlib.c ***************************/