Esempio n. 1
0
static bool process_inactive (lpprob_struct *orig_lp, int oxkndx)

/*
  This routine handles the data structure updates for an inactive variable
  x<k>.  We need to have a look at the bounds l<k> and u<k>, and perhaps
  update the status kept in dy_origvars. We need to add the contribution
  c<k>l<k> or c<k>u<k> to the objective function. Finally, if we've reloaded
  b & blow due to a bound or rhs change, we need to walk the column a<k>
  and adjust b<i> (and perhaps blow<i>) for each nonzero a<ik> in the active
  system.

  Parameters:
    orig_lp:	the original lp problem
    oxkndx:	index of x<k> in orig_sys
  
  Returns: TRUE if the update is made without incident, FALSE otherwise.
*/

{ int oaindx,aindx,ndx ;
  double xk,lk,uk,ck ;
  pkvec_struct *ak ;
  pkcoeff_struct *aik ;
  consys_struct *orig_sys ;
  flags xkstatus ;
  const char *rtnnme = "process_inactive" ;

  orig_sys = orig_lp->consys ;

  xkstatus = getflg(orig_lp->status[oxkndx],vstatSTATUS) ;

# ifdef DYLP_PARANOIA
/*
  Any inactive variable should be nonbasic, and the paranoid check is looking
  to make sure of this.
*/
  if (!VALID_STATUS(xkstatus))
  { errmsg(300,rtnnme,(int) xkstatus,
	   consys_nme(orig_sys,'v',oxkndx,FALSE,NULL),oxkndx) ;
    return (FALSE) ; }
  if (flgoff(xkstatus,vstatNONBASIC|vstatNBFR))
  { errmsg(433,rtnnme,
	   dy_sys->nme,dy_prtlpphase(dy_lp->phase,TRUE),dy_lp->tot.iters,
	   "inactive",consys_nme(orig_sys,'v',oxkndx,TRUE,NULL),oxkndx,
	   dy_prtvstat(xkstatus)) ;
    return (FALSE) ; }
# endif
/*
  The bounds can change arbitrarily, and the client may not be maintaining
  the status vector, but we're limited in what we can do --- bounds and status
  are our only clues to the value of an inactive variable. (Contrast with the
  equivalent section in process_active.)
*/
  lk = orig_sys->vlb[oxkndx] ;
  uk = orig_sys->vub[oxkndx] ;
  ck = orig_sys->obj[oxkndx] ;
/*
  Start with the case that both bounds are finite. Use a previous status of
  NBLB or NBUB. Otherwise, guess from the sign of the objective coefficient.
  `Dirty' fixed variables are marked as unloadable.
*/
  if (lk > -dy_tols->inf && uk < dy_tols->inf)
  { if (atbnd(lk,uk) && lk != uk)
    { if (flgon(xkstatus,vstatNBLB|vstatNBUB))
      { setflg(xkstatus,vstatNOLOAD) ; }
      else
      { if (ck < 0)
	{ xkstatus = vstatNBUB|vstatNOLOAD ; }
	else
	{ xkstatus = vstatNBLB|vstatNOLOAD ; } }
#     ifndef DYLP_NDEBUG
      if (dy_opts->print.setup >= 3)
      { dyio_outfmt(dy_logchn,dy_gtxecho,"\n\tDirty fixed variable %s (%d)",
		    consys_nme(orig_sys,'v',oxkndx,0,0),oxkndx) ;
	dyio_outfmt(dy_logchn,dy_gtxecho,
		    " assigned status %s.",dy_prtvstat(xkstatus)) ;
	dyio_outfmt(dy_logchn,dy_gtxecho,
		    "\n\t  original lb = %g, ub = %g, diff = %g, tol = %g",
		    lk,uk,uk-lk,dy_tols->pfeas) ; }
#     endif
    }
    else
    if (lk == uk)
    { xkstatus = vstatNBFX|vstatNOLOAD ; }
    else
    if (flgon(xkstatus,vstatNBLB|vstatNBUB))
    { xkstatus = orig_lp->status[oxkndx] ; }
    else
    { if (ck < 0)
      { xkstatus = vstatNBUB ; }
      else
      { xkstatus = vstatNBLB ; } } }
/*
  Variables with one bound, or no bounds. No choices here.
*/
  else
  if (lk > -dy_tols->inf)
  { xkstatus = vstatNBLB ; }
  else
  if (uk < dy_tols->inf)
  { xkstatus = vstatNBUB ; }
  else
  { xkstatus = vstatNBFR ; }
/*
  Determine the variable's value and set up the status entries.

  The default case in the switch below should never execute, but it serves
  for paranoia and lets gcc conclude xk will always have a value.

  Consider whether it's really a good idea to change orig_lp->status.
*/
  switch (getflg(xkstatus,vstatSTATUS))
  { case vstatNBLB:
    case vstatNBFX:
    { xk = lk ;
      break ; }
    case vstatNBUB:
    { xk = uk ;
      break ; }
    case vstatNBFR:
    { xk = 0 ;
      break ; }
    default:
    { xk = 0 ;
      errmsg(1,rtnnme,__LINE__) ;
      return (FALSE) ; } }
  orig_lp->status[oxkndx] = xkstatus ;
  dy_origvars[oxkndx] = -((int) xkstatus) ;
/*
  Note any contribution to the objective and constraint rhs & rhslow values.
*/
  dy_lp->inactzcorr += xk*orig_sys->obj[oxkndx] ;
  if (flgon(orig_lp->ctlopts,lpctlRHSCHG|lpctlLBNDCHG|lpctlUBNDCHG))
  { ak = NULL ;
    if (consys_getcol_pk(orig_sys,oxkndx,&ak) == FALSE)
    { errmsg(122,rtnnme,orig_sys->nme,"variable",
	     consys_nme(orig_sys,'v',oxkndx,TRUE,NULL),oxkndx) ;
      if (ak != NULL) pkvec_free(ak) ;
      return (FALSE) ; }
    for (ndx = 0, aik = &ak->coeffs[0] ; ndx < ak->cnt ; ndx++, aik++)
    { oaindx = aik->ndx ;
      if (ACTIVE_CON(oaindx))
      { aindx = dy_origcons[oaindx] ;
        dy_sys->rhs[aindx] -= aik->val*xk ;
	if (dy_sys->ctyp[aindx] == contypRNG)
	  dy_sys->rhslow[aindx] -= aik->val*xk ; } }
    pkvec_free(ak) ; }
/*
  And we're done. Print some information and return.
*/

# ifndef DYLP_NDEBUG
  if (dy_opts->print.crash >= 4)
  { dyio_outfmt(dy_logchn,dy_gtxecho,"\n\t  %s (%d) %s inactive with value ",
	        consys_nme(orig_sys,'v',oxkndx,FALSE,NULL),oxkndx,
	        dy_prtvstat(xkstatus)) ;
    switch (getflg(xkstatus,vstatSTATUS))
    { case vstatNBFX:
      case vstatNBLB:
      case vstatNBUB:
      case vstatNBFR:
      { dyio_outfmt(dy_logchn,dy_gtxecho,"%g.",xk) ;
	break ; }
      default:
      { dyio_outfmt(dy_logchn,dy_gtxecho,"??.") ;
	break ; } } }
# endif

return (TRUE) ; }
Esempio n. 2
0
dyret_enum dy_factor (flags *calcflgs)

/*
  This routine orchestrates the LU factorisation of the basis. The glpk
  routines do the grunt work. This routine provides the intelligence.

  If inv_decomp aborts the attempt to factor due to numerical instability, we
  tighten the pivot selection parameters one notch and try again, giving up
  only when no further increase is possible.  The sequence of values for the
  pivot selection parameters are defined in a table at the top of this file.

  If inv_decomp aborts the attempt to factor because the basis is singular,
  we correct the basis with adjust_basis and take another run at factoring.
  In the event that the basis is successfully patched, we have serious work
  to do.  See the comments with adjust_therest for further information. If
  the user has for some reason disabled basis patching, we return
  dyrSINGULAR.

  inv_decomp (actually, luf_decomp) is self-expanding --- if more space is
  needed to hold the factorization, the expansion is handled internally.
  dylp uses ladEXPAND to force basis expansion after a pivot fails due to lack
  of space. In glpk, inv_update will set instructions in the basis structure
  and luf_decomp will handle the expansion, so ladEXPAND is redundant. No
  action need be taken in this routine. It's also not possible to tell if the
  basis has been expanded, so ladEXPAND is not set on output.


  Parameters:
    calcflgs:   (i) ladPRIMALS indicates the primal variables should be
		    recalculated after factoring the basis.
		    ladDUALS indicates the dual variables should be
		    recalculated after factoring the basis.
		    ladEXPAND indicates that the basis should be expanded prior
		    to refactoring.
		(o) flags are set to indicate if the corresponding variables
		    have been recalculated.

  Returns: dyrOK if the basis is factored without incident
	   dyrPATCHED if the basis was singular and has been repaired
	   dyrSINGULAR if the basis was singular and has not been repaired
	   dyrNUMERIC if factoring failed for the strictest pivoting regimen
	   dyrFATAL for other fatal errors

  NOTE: glpinv/glpluf will crash and burn if they encounter what they consider
	to be a fatal error, rather than returning a fatal error code. This
	needs to be addressed at some point. In particular, failure to expand
	the basis, failure to load the basis from the constraint system, and
	various parameter errors fall into this category.
*/

{ int retval,patchcnt ;
  bool try_again,patched ;
  dyret_enum retcode ;
  patch_struct *patches ;

  const char *rtnnme = "dy_factor" ;

#ifdef DYLP_PARANOIA
  if (dy_sys == NULL)
  { errmsg(2,rtnnme,"dy_sys") ;
    return (dyrFATAL) ; }
  if (dy_basis == NULL)
  { errmsg(2,rtnnme,"basis") ;
    return (dyrFATAL) ; }
#endif

# ifdef DYLP_STATISTICS
  if (dy_stats != NULL)
  { int pivcnt ;
    pivcnt = dy_lp->tot.pivs-dy_stats->factor.prevpiv ;
    dy_stats->factor.avgpivs = dy_stats->factor.avgpivs*dy_stats->factor.cnt ;
    dy_stats->factor.avgpivs += pivcnt ;
    dy_stats->factor.cnt++ ;
    dy_stats->factor.avgpivs /= dy_stats->factor.cnt ;
    if (pivcnt > dy_stats->factor.maxpivs) dy_stats->factor.maxpivs = pivcnt ;
    dy_stats->factor.prevpiv = dy_lp->tot.pivs ; }
# endif

  retcode = dyrINV ;
  patchcnt = 0 ;
  patches = NULL ;

/*
  Call luf_adjustsize to set the actual size of the basis. If the allocated
  capacity is too small, it will be expanded.
*/
  luf_adjustsize() ;
/*
  Open a loop for factorisation attempts. We'll persist in the face of
  numerical stability problems as long as there's room to tighten the pivot
  selection.

  At present, glpinv/glpluf will crash and burn if they encounter fatal
  problems. The basis load is implicit --- the routine factor_loadcol is
  called from luf_decomp to load up the coefficients.
*/
  try_again = TRUE ;
  patched = FALSE ;
  while (try_again)
  { retval = inv_decomp(luf_basis,dy_sys,factor_loadcol) ;
#   ifndef DYLP_NDEBUG
    if ((retval == 0 && dy_opts->print.basis >= 4) ||
	(retval > 0 && dy_opts->print.basis >= 2))
    { dyio_outfmt(dy_logchn,dy_gtxecho,
		  "\n    (%s)%d: factored with %s, basis stability %g.",
		  dy_prtlpphase(dy_lp->phase,TRUE),dy_lp->tot.iters,
		  dy_prtpivparms(-1),luf_basis->min_vrratio) ; }
#   endif
/*
  Deal with the result. A return code of 0 means there were no difficulties;
  1 says the basis was singular and had to be patched before the
  factorisation could be completed. Either is success, and we're done.
*/
    switch (retval)
    { case 0:
      { try_again = FALSE ;
	retcode = dyrOK ;
	break ; }
/*
  Alas, the failures.

  If the problem is a singular basis (retval = 1), fix up the basis structures
  as indicated in the luf_basis structure and try again to factor the basis,
  unless the user has forbidden it.

  If the problem is numerical instability (retval = 2) try to make the pivot
  selection more stringent, and keep trying until we can try no more, at
  which point we'll return numeric instability to the caller.

  What's left is fatal confusion; pass the buck back to the caller.
*/
      case 1:
      { if (dy_opts->patch == FALSE)
	{ errmsg(308,rtnnme,dy_sys->nme,dy_prtlpphase(dy_lp->phase,TRUE),
		 dy_lp->tot.iters,dy_prtdyret(dyrSINGULAR)) ;
	  clrflg(*calcflgs,ladPRIMALS|ladDUALS) ;
	  return (dyrSINGULAR) ; }
#	ifndef DYLP_NDEBUG
	if (dy_opts->print.basis >= 2)
	{ dyio_outfmt(dy_logchn,dy_gtxecho,
		      "\n    (%s)%d: attempting to patch singular basis.",
		      dy_prtlpphase(dy_lp->phase,TRUE),dy_lp->tot.iters) ; }
#	endif
	adjust_basis(&patchcnt,&patches) ;
	patched = TRUE ;
	break ; }
      case 2:
      { retcode = dyrNUMERIC ;
#	ifndef DYLP_NDEBUG
	if (dy_opts->print.basis >= 2)
	{ dyio_outfmt(dy_logchn,dy_gtxecho,
		  "\n    (%s)%d: factor failed at %s, numerical instability,",
		  dy_prtlpphase(dy_lp->phase,TRUE),dy_lp->tot.iters,
		  dy_prtpivparms(-1)) ;
	  dyio_outfmt(dy_logchn,dy_gtxecho," max = %g, gro = %g.",
		      luf_basis->luf->big_v,luf_basis->luf->max_gro) ; }
# 	endif
	if (dy_setpivparms(+1,0) == FALSE)
	{ errmsg(307,rtnnme,dy_sys->nme,dy_prtlpphase(dy_lp->phase,TRUE),
		 dy_lp->tot.iters,dy_prtpivparms(-1)) ;
	  return (retcode) ; }
#	ifndef DYLP_NDEBUG
	if (dy_opts->print.basis >= 2)
	{ dyio_outfmt(dy_logchn,dy_gtxecho,"\n\ttrying again with %s.",
		      dy_prtpivparms(-1)) ; }
#	endif
	break ; }
      default:
      { errmsg(7,rtnnme,__LINE__,"inv_decomp return code",retval) ;
	return (dyrFATAL) ; } }
  }
/*
  If we reach here, we managed to factor the basis.  Reset the count of
  pivots since the last refactor.  If the basis was patched, we have some
  serious cleanup to do, so call adjust_therest to deal with the details.
  Otherwise, turn to the requests to calculate values for the primal and/or
  dual variables.
*/
  dy_lp->basis.etas = 0 ;
  if (patched == TRUE)
  { retcode = adjust_therest(patchcnt,patches) ;
    FREE(patches) ;
    if (retcode == dyrFATAL)
    { errmsg(306,rtnnme,dy_sys->nme,dy_prtlpphase(dy_lp->phase,TRUE),
	     dy_lp->tot.iters) ;
      return (dyrFATAL) ; }
#   ifndef DYLP_NDEBUG
    if (dy_opts->print.basis >= 1)
    { dyio_outfmt(dy_logchn,dy_gtxecho,
		  "\n\t[%s]: compensated for basis correction.",
		  dy_sys->nme) ; }
#   endif
    if (!(dy_lp->phase == dyINIT))
    { setflg(*calcflgs,ladPRIMALS|ladDUALS) ;
      if (retcode == dyrLOSTDFEAS) setflg(*calcflgs,ladDUALFEAS) ; }
    retcode = dyrPATCHED ; }
  else
  { if (flgon(*calcflgs,ladPRIMALS))
    { if (dy_calcprimals() == FALSE)
      { clrflg(*calcflgs,ladPRIMALS) ;
	return (dyrFATAL) ; } }
    if (flgon(*calcflgs,ladDUALS)) dy_calcduals() ; }

  return (retcode) ; }
Esempio n. 3
0
int main (int argc, char **argv)

{ bool errecho = TRUE ;

  ioid ttyin,ttyout,outchn ;
  const char *errmsgpath = DYLP_ERRMSGPATH ;
  char *errlogpath = NULL ;

/*
  These need to be globals to keep cmdint.c::process_cmds happy.

  lpopts_struct *main_lpopts ;
  lptols_struct *main_lptols ;
*/
  consys_struct *main_sys ;
  lpprob_struct *main_lp ;
  lpret_enum lpretval ;

  double z ;
  int errcnt,cnt ;

/*
  Set this to TRUE if you want to see the solutions for the test lp problems.
*/
  bool dumpsoln = TRUE ;

  char *rtnnme = argv[0] ;

  /* dy_basis.c */

  extern void dy_initbasis(int concnt, int factor_freq, double zero_tol),
	      dy_freebasis(void) ;

  /* dytest_problems.c */

  extern consys_struct *dytest_exmip1sys(lptols_struct *tols) ;
  extern consys_struct *dytest_exprimalraysys(lptols_struct *tols) ;
  extern consys_struct *dytest_exdualraysys(lptols_struct *tols) ;
  extern consys_struct *dytest_galenetbndssys(lptols_struct *tols) ;
  extern consys_struct *dytest_galenetleqsys(lptols_struct *tols) ;
  extern consys_struct *dytest_galenetmixedsys(lptols_struct *tols) ;
  extern consys_struct *dytest_galenetsys(lptols_struct *tols) ;

  extern consys_struct *dytest_afirosys(lptols_struct *tols) ;
  extern consys_struct *dytest_boeing2sys(lptols_struct *tols) ;

  /* dytest_tableau.c */

  extern int dytest_betaj(lpprob_struct *lp,
			  lptols_struct *lptols,lpopts_struct *lpopts) ;
  extern int dytest_betai(lpprob_struct *lp,
			  lptols_struct *lptols,lpopts_struct *lpopts) ;
  extern int dytest_abarj(lpprob_struct *lp,
			  lptols_struct *lptols,lpopts_struct *lpopts) ;
  extern int dytest_abari(lpprob_struct *lp,
			  lptols_struct *lptols,lpopts_struct *lpopts) ;

  /* dytest_solutions.c */

  extern int dytest_rowDuals(lpprob_struct *lp,
			     lptols_struct *lptols,lpopts_struct *lpopts) ;
  extern int dytest_allDuals(lpprob_struct *lp,
			      lptols_struct *lptols,lpopts_struct *lpopts) ;
  extern int dytest_colDuals(lpprob_struct *lp,
			     lptols_struct *lptols,lpopts_struct *lpopts) ;
  extern int dytest_colPrimals(lpprob_struct *lp,
			       lptols_struct *lptols,lpopts_struct *lpopts) ;
  extern int dytest_rowPrimals(lpprob_struct *lp,
			       lptols_struct *lptols,lpopts_struct *lpopts) ;

  /* dytest_rays.c */

  extern int dytest_primalRays(int *p_numRays,lpprob_struct *lp,
			       lptols_struct *lptols,lpopts_struct *lpopts) ;
  extern int dytest_dualRays(int *p_numRays,lpprob_struct *lp,
			     lptols_struct *lptols,lpopts_struct *lpopts) ;

  outchn = IOID_INV ;
/*
  Execute initialization routines for the i/o and error reporting packages.
*/
  errinit(errmsgpath,errlogpath,errecho) ;
  if (dyio_ioinit() != TRUE)
  { errmsg(1,rtnnme,__LINE__) ;
    exit (2) ; }
/*
  Connect ttyout to the standard output. Initialize ttyin, setting the mode to
  line-oriented. Serious internal confusion if we can't manage these. Set the
  initial command input channel to stdin.
*/
  ttyout = dyio_openfile("stdout","w") ;
  if (ttyout == IOID_INV)
  { errmsg(1,rtnnme,__LINE__) ;
    exit(3) ; }
  ttyin = dyio_openfile("stdin","r") ;
  if (ttyin == IOID_INV)
  { errmsg(1,rtnnme,__LINE__) ;
    exit(4) ; }
  (void) dyio_setmode(ttyin,'l') ;
  dy_cmdchn = ttyin ;
  dy_logchn = IOID_NOSTRM ;
  dy_cmdecho = TRUE ;
  dy_gtxecho = TRUE ;
/*
  Announce we're running.
*/
  dyio_outfmt(ttyout,dy_gtxecho,"Dylp v%s unit test start.\n",DYLP_VERSION) ;
  dyio_flushio(ttyout,dy_gtxecho) ;
  errcnt = 0 ;
/*
  Acquire default option and tolerance structures. Allocate an
  lpprob_struct to be our top-level handle.
*/
  main_lpopts = NULL ;
  main_lptols = NULL ;
  dy_defaults(&main_lpopts,&main_lptols) ;
  main_lp = (lpprob_struct *) CALLOC(1,sizeof(lpprob_struct)) ;
/*
  Initialise the basis factorisation package with a data structure capable of
  50 constraints.  The second parameter controls how many basis updates the
  basis can hold before it requires refactoring.  Adding 5 to dylp's refactor
  interval should give a safety margin.
*/
  dy_initbasis(50,main_lpopts->factor+5,0.0) ;

#if RUN_EXMIP1 > 0
/*
  Load the exmip1 example and see if we can solve it.
*/
  dyio_outfmt(ttyout,dy_gtxecho,
	      "\n\nLoading exmip1 example from static data.\n") ;
  main_sys = dytest_exmip1sys(main_lptols) ;
  if (main_sys == NULL)
  { dyio_outfmt(ttyout,dy_gtxecho,
		"Failed to load exmip1 constraint system.\n") ;
    errcnt++ ; }
/*
  Check over the option settings, now that we know how big the constraint
  system will be.
*/
  else
  { dy_checkdefaults(main_sys,main_lpopts,main_lptols) ;
/*
  Initialise the main_lp structure to pass the problem in to dylp.
    * We need to retain the data structures (NOFREE) so that we can
      consult them when dylp returns.
    * The phase needs to be dyINV at the start.
    * We need to specify the constraint system, and its size.
    * Let dylp work with a partial system and purge at the end. This stresses
      the routines we're testing; they need to synthesize parts of the values
      they return.
    * The remaining options specify an all-logical basis, allow scaling, and
      force a cold start.
*/
    setflg(main_lp->ctlopts,lpctlNOFREE) ;
    main_lp->phase = dyINV ;
    main_lp->consys = main_sys ;
    main_lp->rowsze = main_sys->rowsze ;
    main_lp->colsze = main_sys->colsze ;
    main_lpopts->forcecold = TRUE ;
    main_lpopts->fullsys = FALSE ;
    main_lpopts->finpurge.vars = TRUE ;
    main_lpopts->finpurge.cons = TRUE ;
    main_lpopts->coldbasis = ibLOGICAL ;
    main_lpopts->scaling = 0 ;
    main_lpopts->forcecold = TRUE ;
/*
    main_lpopts->print.major = 1 ;
    main_lpopts->print.scaling = 1 ;
    main_lpopts->print.setup = 6 ;
    main_lpopts->print.crash = 3 ;
    main_lpopts->print.conmgmt = 3 ;
    main_lpopts->print.varmgmt = 3 ;
    main_lpopts->print.soln = 3 ;
*/
/*
  Solve.
*/
    dyio_outfmt(ttyout,dy_gtxecho,"Solving exmip1 ... ") ;
    lpretval = do_lp(main_lp,main_lptols,main_lpopts,1) ;
/*
  And the result is ...
*/
    dyio_outfmt(ttyout,dy_gtxecho,"\n  %s, z = %.12f.\n",
		dy_prtlpret(lpretval),main_lp->obj) ;
    z = 3.236842105263 ;
    if (!(fabs(main_lp->obj-z) <= main_lptols->cost))
    { errcnt++ ;
      dyio_outfmt(ttyout,dy_gtxecho,
		  "  ERROR: z = %g, expected %g, error %g, tol %g.\n",
		  main_lp->obj,z,fabs(main_lp->obj-z),main_lptols->cost) ; }
    if (dumpsoln == TRUE)
    { dy_dumpcompact(dy_logchn,dy_gtxecho,main_lp,FALSE) ; }
/*
  Test the tableau, solution, and ray routines. The tests are predominantly
  mathematical identities, with a bit of data structure consistency thrown in
  for good measure. Completely problem-independent.
*/
    errcnt += dytest_betaj(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_abarj(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_betai(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_abari(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_rowDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_colDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_allDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_colPrimals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_rowPrimals(main_lp,main_lptols,main_lpopts) ;
/*
  Call dylp to free internal structures, then free main_sys.
*/
    comflg(main_lp->ctlopts,lpctlONLYFREE|lpctlNOFREE) ;
    dylp(main_lp,main_lpopts,main_lptols,NULL) ;
    consys_free(main_sys) ;
    main_sys = NULL ;
    main_lp->consys = NULL ;
    dy_freesoln(main_lp) ; }
#endif

#if RUN_AFIRO > 0
/*
  Let's try another. Load and solve afiro.
*/
  dyio_outfmt(ttyout,dy_gtxecho,
	      "\n\nLoading afiro example from static data.\n") ;
  main_sys = dytest_afirosys(main_lptols) ;
  if (main_sys == NULL)
  { dyio_outfmt(ttyout,dy_gtxecho,
		"Failed to load afiro constraint system.\n") ;
    errcnt++ ; }
  else
  { dy_checkdefaults(main_sys,main_lpopts,main_lptols) ;
    comflg(main_lp->ctlopts,lpctlONLYFREE|lpctlNOFREE) ;
    main_lp->phase = dyINV ;
    main_lp->consys = main_sys ;
    main_lp->rowsze = main_sys->rowsze ;
    main_lp->colsze = main_sys->colsze ;
    main_lpopts->forcecold = TRUE ;
    main_lpopts->fullsys = FALSE ;
    main_lpopts->finpurge.vars = TRUE ;
    main_lpopts->finpurge.cons = TRUE ;
    main_lpopts->coldbasis = ibLOGICAL ;
    main_lpopts->scaling = 2 ;

    dyio_outfmt(ttyout,dy_gtxecho,"Solving afiro ... ") ;
    lpretval = do_lp(main_lp,main_lptols,main_lpopts,1) ;
    dyio_outfmt(ttyout,dy_gtxecho,"\n  %s, z = %.12f.\n",
		dy_prtlpret(lpretval),main_lp->obj) ;
    z = -464.753142857143 ;
    if (!(fabs(main_lp->obj-z) <= main_lptols->cost))
    { errcnt++ ;
      dyio_outfmt(ttyout,dy_gtxecho,
		  "  ERROR: z = %g, expected %g, error %g, tol %g.\n",
		  main_lp->obj,z,fabs(main_lp->obj-z),main_lptols->cost) ; }
    if (dumpsoln == TRUE)
    { dy_dumpcompact(dy_logchn,dy_gtxecho,main_lp,FALSE) ; }

    errcnt += dytest_betaj(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_abarj(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_betai(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_abari(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_rowDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_colDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_allDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_colPrimals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_rowPrimals(main_lp,main_lptols,main_lpopts) ;

    comflg(main_lp->ctlopts,lpctlONLYFREE|lpctlNOFREE) ;
    dylp(main_lp,main_lpopts,main_lptols,NULL) ;
    consys_free(main_sys) ;
    main_sys = NULL ;
    main_lp->consys = NULL ;
    dy_freesoln(main_lp) ; }
#endif

#if RUN_BOEING2 > 0
/*
  Let's try another. Load and solve boeing2.
*/
  dyio_outfmt(ttyout,dy_gtxecho,
	      "\n\nLoading boeing2 example from static data.\n") ;
  main_sys = dytest_boeing2sys(main_lptols) ;
  if (main_sys == NULL)
  { dyio_outfmt(ttyout,dy_gtxecho,
		"Failed to load boeing2 constraint system.\n") ;
    errcnt++ ; }
  else
  { dy_checkdefaults(main_sys,main_lpopts,main_lptols) ;
    comflg(main_lp->ctlopts,lpctlONLYFREE|lpctlNOFREE) ;
    main_lp->phase = dyINV ;
    main_lp->consys = main_sys ;
    main_lp->rowsze = main_sys->rowsze ;
    main_lp->colsze = main_sys->colsze ;
    main_lpopts->forcecold = TRUE ;
    main_lpopts->fullsys = FALSE ;
    main_lpopts->finpurge.vars = TRUE ;
    main_lpopts->finpurge.cons = TRUE ;
    main_lpopts->coldbasis = ibLOGICAL ;
    main_lpopts->scaling = 2 ;

    main_lpopts->print.phase2 = 0 ;
/*
    main_lpopts->print.major = 1 ;
    main_lpopts->print.phase1 = 4 ;
    main_lpopts->print.dual = 4 ;
    main_lpopts->print.tableau = 4 ;
    main_lpopts->print.soln = 3 ;
    main_lpopts->print.rays = 5 ;
*/

    dyio_outfmt(ttyout,dy_gtxecho,"Solving boeing2 ... ") ;
    lpretval = do_lp(main_lp,main_lptols,main_lpopts,1) ;
    dyio_outfmt(ttyout,dy_gtxecho,"\n  %s, z = %.12f.\n",
		dy_prtlpret(lpretval),main_lp->obj) ;
    z = -315.0187280152 ;
    if (!(fabs(main_lp->obj-z) <= main_lptols->cost))
    { errcnt++ ;
      dyio_outfmt(ttyout,dy_gtxecho,
		  "  ERROR: z = %g, expected %g, error %g, tol %g.\n",
		  main_lp->obj,z,fabs(main_lp->obj-z),main_lptols->cost) ; }
    if (dumpsoln == TRUE)
    { dy_dumpcompact(dy_logchn,dy_gtxecho,main_lp,FALSE) ; }

    errcnt += dytest_betaj(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_abarj(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_betai(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_abari(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_rowDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_colDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_allDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_colPrimals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_rowPrimals(main_lp,main_lptols,main_lpopts) ;

    comflg(main_lp->ctlopts,lpctlONLYFREE|lpctlNOFREE) ;
    dylp(main_lp,main_lpopts,main_lptols,NULL) ;
    consys_free(main_sys) ;
    main_sys = NULL ;
    main_lp->consys = NULL ;
    dy_freesoln(main_lp) ; }
#endif

#if RUN_EXPRIMALRAY > 0
/*
  Let's try another. Load and solve exprimalray.  The polyhedron for
  exprimalray is carefully crafted to provide an initial bounded optimum
  point with two rays that are exposed by the proper change in objective.
  Force dylp to use the full system for this test and do not allow final
  purging, lest we miss the point and rays we're aiming for.
*/
  dyio_outfmt(ttyout,dy_gtxecho,
	      "\n\nLoading exprimalray example from static data.\n") ;
  main_sys = dytest_exprimalraysys(main_lptols) ;
  if (main_sys == NULL)
  { dyio_outfmt(ttyout,dy_gtxecho,
		"Failed to load exprimalray constraint system.\n") ;
    errcnt++ ; }
  else
  { dy_checkdefaults(main_sys,main_lpopts,main_lptols) ;
    comflg(main_lp->ctlopts,lpctlONLYFREE|lpctlNOFREE) ;
    main_lp->phase = dyINV ;
    main_lp->consys = main_sys ;
    main_lp->rowsze = main_sys->rowsze ;
    main_lp->colsze = main_sys->colsze ;
    main_lpopts->forcecold = TRUE ;
    main_lpopts->fullsys = TRUE ;
    main_lpopts->finpurge.vars = FALSE ;
    main_lpopts->finpurge.cons = FALSE ;
    main_lpopts->coldbasis = ibLOGICAL ;
    main_lpopts->scaling = 2 ;

    dyio_outfmt(ttyout,dy_gtxecho,"Solving exprimalray ... ") ;

    lpretval = do_lp(main_lp,main_lptols,main_lpopts,1) ;
    dyio_outfmt(ttyout,dy_gtxecho,"\n  %s, z = %.12f.\n",
		dy_prtlpret(lpretval),main_lp->obj) ;
    z = -21 ;
    if (!(fabs(main_lp->obj-z) <= main_lptols->cost))
    { errcnt++ ;
      dyio_outfmt(ttyout,dy_gtxecho,
		  "  ERROR: z = %g, expected %g, error %g, tol %g.\n",
		  main_lp->obj,z,fabs(main_lp->obj-z),main_lptols->cost) ; }
    if (dumpsoln == TRUE)
    { dy_dumpcompact(dy_logchn,dy_gtxecho,main_lp,FALSE) ; }
/*
  Now tweak the objective to 3x1+x2+x3, giving us two rays. Solve, then test
  that we have valid primal rays. First ask for just one, then ask for five,
  expecting two.
*/
    main_sys->obj[1] = -1.0 ;
    main_sys->obj[2] = -4.0 ;
    setflg(main_lp->ctlopts,lpctlOBJCHG) ;
    main_lpopts->forcecold = FALSE ;

    dyio_outfmt(dy_logchn,dy_gtxecho,"Resolving exprimalray ...") ;
    lpretval = do_lp(main_lp,main_lptols,main_lpopts,1) ;
    dyio_outfmt(ttyout,dy_gtxecho,"\n  %s, z = %.12f.\n",
		dy_prtlpret(lpretval),main_lp->obj) ;
    if (dumpsoln == TRUE)
    { dy_dumpcompact(dy_logchn,dy_gtxecho,main_lp,FALSE) ; }

    cnt = 1 ;
    errcnt += dytest_primalRays(&cnt,main_lp,main_lptols,main_lpopts) ;
    if (cnt != 1)
    { errcnt++ ;
      dyio_outfmt(ttyout,dy_gtxecho,
		  "  ERROR: %d primal rays returned, expected %d.\n",
		  cnt,1) ; }
    cnt = 5 ;
    errcnt += dytest_primalRays(&cnt,main_lp,main_lptols,main_lpopts) ;
    if (cnt != 2)
    { errcnt++ ;
      dyio_outfmt(ttyout,dy_gtxecho,
		  "  ERROR: %d primal rays returned, expected %d.\n",
		  cnt,2) ; }
/*
  Run the remainder of the tests, to make sure they run without error when
  dylp finishes unbounded.
*/
    errcnt += dytest_betaj(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_abarj(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_betai(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_abari(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_rowDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_colDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_allDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_colPrimals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_rowPrimals(main_lp,main_lptols,main_lpopts) ;

    comflg(main_lp->ctlopts,lpctlONLYFREE|lpctlNOFREE) ;
    dylp(main_lp,main_lpopts,main_lptols,NULL) ;
    consys_free(main_sys) ;
    main_sys = NULL ;
    main_lp->consys = NULL ;
    dy_freesoln(main_lp) ; }
#endif

#if RUN_EXDUALRAY > 0
/*
  Let's try another. Load and solve exdualray. Exdualray takes advantage of
  duality: The dual polyhedron is exactly the primal polyhedron of the
  previous problem.  The symmetry should be clear from the output (objective,
  dual, and primal values are negated, but otherwise identical)
*/
  dyio_outfmt(ttyout,dy_gtxecho,
	      "\n\nLoading exdualray example from static data.\n") ;
  main_sys = dytest_exdualraysys(main_lptols) ;
  if (main_sys == NULL)
  { dyio_outfmt(ttyout,dy_gtxecho,
		"Failed to load exdualray constraint system.\n") ;
    errcnt++ ; }
  else
  { dy_checkdefaults(main_sys,main_lpopts,main_lptols) ;
    comflg(main_lp->ctlopts,lpctlONLYFREE|lpctlNOFREE) ;
    main_lp->phase = dyINV ;
    main_lp->consys = main_sys ;
    main_lp->rowsze = main_sys->rowsze ;
    main_lp->colsze = main_sys->colsze ;
    main_lpopts->forcecold = TRUE ;
    main_lpopts->fullsys = TRUE ;
    main_lpopts->finpurge.vars = FALSE ;
    main_lpopts->finpurge.cons = FALSE ;
    main_lpopts->coldbasis = ibLOGICAL ;
    main_lpopts->scaling = 2 ;
/*
    main_lpopts->print.major = 1 ;
    main_lpopts->print.phase1 = 4 ;
    main_lpopts->print.phase2 = 4 ;
    main_lpopts->print.dual = 4 ;
    main_lpopts->print.tableau = 4 ;
    main_lpopts->print.soln = 3 ;
    main_lpopts->print.rays = 5 ;
*/

    dyio_outfmt(ttyout,dy_gtxecho,"Solving exdualray ... ") ;
    lpretval = do_lp(main_lp,main_lptols,main_lpopts,1) ;
    dyio_outfmt(ttyout,dy_gtxecho,"\n  %s, z = %.12f.\n",
		dy_prtlpret(lpretval),main_lp->obj) ;
    z = 21 ;
    if (!(fabs(main_lp->obj-z) <= main_lptols->cost))
    { errcnt++ ;
      dyio_outfmt(ttyout,dy_gtxecho,
		  "  ERROR: z = %g, expected %g, error %g, tol %g.\n",
		  main_lp->obj,z,fabs(main_lp->obj-z),main_lptols->cost) ; }
    if (dumpsoln == TRUE)
    { dy_dumpcompact(dy_logchn,dy_gtxecho,main_lp,FALSE) ; }
/*
  Tweak the rhs to (-1)*(-1 -4 1) to produce a pair of rays in the dual.
*/
    main_sys->rhs[2] =  4.0 ;
    setflg(main_lp->ctlopts,lpctlRHSCHG) ;
    main_lpopts->forcecold = FALSE ;
    main_lpopts->print.force = 1 ;
    dyio_outfmt(dy_logchn,dy_gtxecho,"Resolving exdualray ...") ;
    lpretval = do_lp(main_lp,main_lptols,main_lpopts,1) ;
    dyio_outfmt(ttyout,dy_gtxecho,"\n  %s, z = %.12f.\n",
		dy_prtlpret(lpretval),main_lp->obj) ;
    if (dumpsoln == TRUE)
    { dy_dumpcompact(dy_logchn,dy_gtxecho,main_lp,FALSE) ; }
/*
  Test that we have valid dual rays. First ask for just one, then ask for
  five, expecting two.
*/
    errcnt += dytest_rowDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_colDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_allDuals(main_lp,main_lptols,main_lpopts) ;
    cnt = 1 ;
    errcnt += dytest_dualRays(&cnt,main_lp,main_lptols,main_lpopts) ;
    if (cnt != 1)
    { errcnt++ ;
      dyio_outfmt(ttyout,dy_gtxecho,
		  "  ERROR: %d dual rays returned, expected %d.\n",
		  cnt,1) ; }
    cnt = 5 ;
    errcnt += dytest_dualRays(&cnt,main_lp,main_lptols,main_lpopts) ;
    if (cnt != 2)
    { errcnt++ ;
      dyio_outfmt(ttyout,dy_gtxecho,
		  "  ERROR: %d dual rays returned, expected %d.\n",
		  cnt,2) ; }
/*
  Run the remainder of the tests, to make sure they run without error when
  dylp finishes infeasible.
*/
    errcnt += dytest_betaj(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_abarj(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_betai(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_abari(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_colPrimals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_rowPrimals(main_lp,main_lptols,main_lpopts) ;

    comflg(main_lp->ctlopts,lpctlONLYFREE|lpctlNOFREE) ;
    dylp(main_lp,main_lpopts,main_lptols,NULL) ;
    consys_free(main_sys) ;
    main_sys = NULL ;
    main_lp->consys = NULL ;
    dy_freesoln(main_lp) ; }
#endif

#if RUN_GALENETBNDS > 0
/*
  Now a sequence of three problems based on galenet that really exercise the
  dual ray code. Galenet is a straightforward primal infeasible / dual
  unbounded problem. The objective is identically zero, so it's a pure
  feasibility problem. The objective returned from dylp will be z = 48, the
  amount of primal infeasibility.

  The first version is galenetbnds. All equalities from galenet are converted
  to inequalities, all implicit bounds are converted to explicit bound
  constraints, and then all >= constraints are converted to <= constraints.
  This is the simplest possible case for returning dual rays.
*/
  dyio_outfmt(ttyout,dy_gtxecho,
	      "\n\nLoading galenetbnds example from static data.\n") ;
  main_sys = dytest_galenetbndssys(main_lptols) ;
  if (main_sys == NULL)
  { dyio_outfmt(ttyout,dy_gtxecho,
		"Failed to load galenetbnds constraint system.\n") ;
    errcnt++ ; }
  else
  { dy_checkdefaults(main_sys,main_lpopts,main_lptols) ;
    comflg(main_lp->ctlopts,lpctlONLYFREE|lpctlNOFREE) ;
    main_lp->phase = dyINV ;
    main_lp->consys = main_sys ;
    main_lp->rowsze = main_sys->rowsze ;
    main_lp->colsze = main_sys->colsze ;
    main_lpopts->forcecold = TRUE ;
    main_lpopts->fullsys = TRUE ;
    main_lpopts->finpurge.vars = FALSE ;
    main_lpopts->finpurge.cons = FALSE ;
    main_lpopts->coldbasis = ibLOGICAL ;
    main_lpopts->scaling = 2 ;
/*
    main_lpopts->print.major = 1 ;
    main_lpopts->print.phase1 = 4 ;
    main_lpopts->print.phase2 = 4 ;
    main_lpopts->print.dual = 4 ;
    main_lpopts->print.tableau = 4 ;
    main_lpopts->print.soln = 3 ;
    main_lpopts->print.rays = 5 ;
*/

    dyio_outfmt(ttyout,dy_gtxecho,"Solving galenetbnds ... ") ;
    lpretval = do_lp(main_lp,main_lptols,main_lpopts,1) ;
    dyio_outfmt(ttyout,dy_gtxecho,"\n  %s, z = %.12f.\n",
		dy_prtlpret(lpretval),main_lp->obj) ;
    z = 48.0 ;
    if (!(fabs(main_lp->obj-z) <= main_lptols->cost))
    { errcnt++ ;
      dyio_outfmt(ttyout,dy_gtxecho,
		  "  ERROR: z = %g, expected %g, error %g, tol %g.\n",
		  main_lp->obj,z,fabs(main_lp->obj-z),main_lptols->cost) ; }
    dumpsoln = TRUE ;
    if (dumpsoln == TRUE)
    { dy_dumpcompact(dy_logchn,dy_gtxecho,main_lp,FALSE) ; }
/*
  Test that we have valid dual rays. First ask for just one, then ask for
  five, expecting three.
*/
    cnt = 1 ;
    errcnt += dytest_dualRays(&cnt,main_lp,main_lptols,main_lpopts) ;
    if (cnt != 1)
    { errcnt++ ;
      dyio_outfmt(ttyout,dy_gtxecho,
		  "  ERROR: %d dual rays returned, expected %d.\n",
		  cnt,1) ; }
    cnt = 5 ;
    errcnt += dytest_dualRays(&cnt,main_lp,main_lptols,main_lpopts) ;
    if (cnt != 3)
    { errcnt++ ;
      dyio_outfmt(ttyout,dy_gtxecho,
		  "  ERROR: %d dual rays returned, expected %d.\n",
		  cnt,2) ; }
/*
  Run the remainder of the tests, to make sure they run without error when
  dylp finishes infeasible.
*/
    errcnt += dytest_betaj(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_abarj(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_betai(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_abari(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_rowDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_colDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_allDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_colPrimals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_rowPrimals(main_lp,main_lptols,main_lpopts) ;

    comflg(main_lp->ctlopts,lpctlONLYFREE|lpctlNOFREE) ;
    dylp(main_lp,main_lpopts,main_lptols,NULL) ;
    consys_free(main_sys) ;
    main_sys = NULL ;
    main_lp->consys = NULL ;
    dy_freesoln(main_lp) ; }
#endif

#if RUN_GALENETLEQ > 0
/*
  Now load and solve galenetleq --- galenetbnds, but the
  bound constraints on variables are now handled in the usual manner, as
  implicit bounds. We'll need the full ray (explicit duals y = c<B>inv(B)
  as well as duals associated with nonbasic bounded variables) in order to pass
  the mathematical tests rb < 0, rA > 0.
*/
  dyio_outfmt(ttyout,dy_gtxecho,
	      "\n\nLoading galenetleq example from static data.\n") ;
  main_sys = dytest_galenetleqsys(main_lptols) ;
  if (main_sys == NULL)
  { dyio_outfmt(ttyout,dy_gtxecho,
		"Failed to load galenetleq constraint system.\n") ;
    errcnt++ ; }
  else
  { dy_checkdefaults(main_sys,main_lpopts,main_lptols) ;
    comflg(main_lp->ctlopts,lpctlONLYFREE|lpctlNOFREE) ;
    main_lp->phase = dyINV ;
    main_lp->consys = main_sys ;
    main_lp->rowsze = main_sys->rowsze ;
    main_lp->colsze = main_sys->colsze ;
    main_lpopts->forcecold = TRUE ;
    main_lpopts->fullsys = TRUE ;
    main_lpopts->finpurge.vars = FALSE ;
    main_lpopts->finpurge.cons = FALSE ;
    main_lpopts->coldbasis = ibLOGICAL ;
    main_lpopts->scaling = 2 ;
/*
    main_lpopts->print.major = 1 ;
    main_lpopts->print.phase1 = 4 ;
    main_lpopts->print.phase2 = 4 ;
    main_lpopts->print.dual = 4 ;
    main_lpopts->print.tableau = 4 ;
    main_lpopts->print.soln = 3 ;
    main_lpopts->print.rays = 5 ;
*/

    dyio_outfmt(ttyout,dy_gtxecho,"Solving galenetleq ... ") ;
    lpretval = do_lp(main_lp,main_lptols,main_lpopts,1) ;
    dyio_outfmt(ttyout,dy_gtxecho,"\n  %s, z = %.12f.\n",
		dy_prtlpret(lpretval),main_lp->obj) ;
    z = 48.0 ;
    if (!(fabs(main_lp->obj-z) <= main_lptols->cost))
    { errcnt++ ;
      dyio_outfmt(ttyout,dy_gtxecho,
		  "  ERROR: z = %g, expected %g, error %g, tol %g.\n",
		  main_lp->obj,z,fabs(main_lp->obj-z),main_lptols->cost) ; }
    dumpsoln = TRUE ;
    if (dumpsoln == TRUE)
    { dy_dumpcompact(dy_logchn,dy_gtxecho,main_lp,FALSE) ; }
/*
  Test that we have valid dual rays. First ask for just one, then ask for
  five, expecting three.
*/
    cnt = 1 ;
    errcnt += dytest_dualRays(&cnt,main_lp,main_lptols,main_lpopts) ;
    if (cnt != 1)
    { errcnt++ ;
      dyio_outfmt(ttyout,dy_gtxecho,
		  "  ERROR: %d dual rays returned, expected %d.\n",
		  cnt,1) ; }
    cnt = 5 ;
    errcnt += dytest_dualRays(&cnt,main_lp,main_lptols,main_lpopts) ;
    if (cnt != 3)
    { errcnt++ ;
      dyio_outfmt(ttyout,dy_gtxecho,
		  "  ERROR: %d dual rays returned, expected %d.\n",
		  cnt,2) ; }
/*
  Run the remainder of the tests, to make sure they run without error when
  dylp finishes infeasible.
*/
    errcnt += dytest_betaj(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_abarj(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_betai(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_abari(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_rowDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_colDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_allDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_colPrimals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_rowPrimals(main_lp,main_lptols,main_lpopts) ;

    comflg(main_lp->ctlopts,lpctlONLYFREE|lpctlNOFREE) ;
    dylp(main_lp,main_lpopts,main_lptols,NULL) ;
    consys_free(main_sys) ;
    main_sys = NULL ;
    main_lp->consys = NULL ;
    dy_freesoln(main_lp) ; }
#endif

#if RUN_GALENETMIXED > 0
/*
  Now load and solve galenetmixed --- bound constraints on variables are
  handled implicitly, and the constraint system is a mix of <= and >=
  constraints (the equalities are handled as a pair of inequalities).  As
  with galenetleq, we'll need the full ray (explicit duals y = c<B>inv(B) as
  well as duals associated with nonbasic bounded variables) in order to pass
  the mathematical tests rb < 0, rA > 0.
*/
  dyio_outfmt(ttyout,dy_gtxecho,
	      "\n\nLoading galenetmixed example from static data.\n") ;
  main_sys = dytest_galenetmixedsys(main_lptols) ;
  if (main_sys == NULL)
  { dyio_outfmt(ttyout,dy_gtxecho,
		"Failed to load galenetmixed constraint system.\n") ;
    errcnt++ ; }
  else
  { dy_checkdefaults(main_sys,main_lpopts,main_lptols) ;
    comflg(main_lp->ctlopts,lpctlONLYFREE|lpctlNOFREE) ;
    main_lp->phase = dyINV ;
    main_lp->consys = main_sys ;
    main_lp->rowsze = main_sys->rowsze ;
    main_lp->colsze = main_sys->colsze ;
    main_lpopts->forcecold = TRUE ;
    main_lpopts->fullsys = TRUE ;
    main_lpopts->finpurge.vars = FALSE ;
    main_lpopts->finpurge.cons = FALSE ;
    main_lpopts->coldbasis = ibLOGICAL ;
    main_lpopts->scaling = 2 ;
/*
    main_lpopts->print.major = 1 ;
    main_lpopts->print.phase1 = 4 ;
    main_lpopts->print.phase2 = 4 ;
    main_lpopts->print.dual = 4 ;
    main_lpopts->print.tableau = 4 ;
    main_lpopts->print.soln = 3 ;
    main_lpopts->print.rays = 5 ;
*/

    dyio_outfmt(ttyout,dy_gtxecho,"Solving galenetmixed ... ") ;
    lpretval = do_lp(main_lp,main_lptols,main_lpopts,1) ;
    dyio_outfmt(ttyout,dy_gtxecho,"\n  %s, z = %.12f.\n",
		dy_prtlpret(lpretval),main_lp->obj) ;
    z = 48.0 ;
    if (!(fabs(main_lp->obj-z) <= main_lptols->cost))
    { errcnt++ ;
      dyio_outfmt(ttyout,dy_gtxecho,
		  "  ERROR: z = %g, expected %g, error %g, tol %g.\n",
		  main_lp->obj,z,fabs(main_lp->obj-z),main_lptols->cost) ; }
    dumpsoln = TRUE ;
    if (dumpsoln == TRUE)
    { dy_dumpcompact(dy_logchn,dy_gtxecho,main_lp,FALSE) ; }
/*
  Test that we have valid dual rays. First ask for just one, then ask for
  five, expecting three.
*/
    cnt = 1 ;
    errcnt += dytest_dualRays(&cnt,main_lp,main_lptols,main_lpopts) ;
    if (cnt != 1)
    { errcnt++ ;
      dyio_outfmt(ttyout,dy_gtxecho,
		  "  ERROR: %d dual rays returned, expected %d.\n",
		  cnt,1) ; }
    cnt = 5 ;
    errcnt += dytest_dualRays(&cnt,main_lp,main_lptols,main_lpopts) ;
    if (cnt != 3)
    { errcnt++ ;
      dyio_outfmt(ttyout,dy_gtxecho,
		  "  ERROR: %d dual rays returned, expected %d.\n",
		  cnt,2) ; }
/*
  Run the remainder of the tests, to make sure they run without error when
  dylp finishes infeasible.
*/
    errcnt += dytest_betaj(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_abarj(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_betai(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_abari(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_rowDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_colDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_allDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_colPrimals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_rowPrimals(main_lp,main_lptols,main_lpopts) ;

    comflg(main_lp->ctlopts,lpctlONLYFREE|lpctlNOFREE) ;
    dylp(main_lp,main_lpopts,main_lptols,NULL) ;
    consys_free(main_sys) ;
    main_sys = NULL ;
    main_lp->consys = NULL ;
    dy_freesoln(main_lp) ; }
#endif

#if RUN_GALENET > 0
/*
  Now load and solve the original galenet --- bound constraints on variables
  are handled implicitly, and the constraint system is a mix of <=, =, and >=
  constraints.  As with galenetleq, we'll need the full ray (explicit duals y
  = c<B>inv(B) as well as duals associated with nonbasic bounded variables)
  in order to pass the mathematical tests rb < 0, rA > 0.
*/
  dyio_outfmt(ttyout,dy_gtxecho,
	      "\n\nLoading galenet example from static data.\n") ;
  main_sys = dytest_galenetsys(main_lptols) ;
  if (main_sys == NULL)
  { dyio_outfmt(ttyout,dy_gtxecho,
		"Failed to load galenet constraint system.\n") ;
    errcnt++ ; }
  else
  { dy_checkdefaults(main_sys,main_lpopts,main_lptols) ;
    comflg(main_lp->ctlopts,lpctlONLYFREE|lpctlNOFREE) ;
    main_lp->phase = dyINV ;
    main_lp->consys = main_sys ;
    main_lp->rowsze = main_sys->rowsze ;
    main_lp->colsze = main_sys->colsze ;
    main_lpopts->forcecold = TRUE ;
    main_lpopts->fullsys = TRUE ;
    main_lpopts->finpurge.vars = FALSE ;
    main_lpopts->finpurge.cons = FALSE ;
    main_lpopts->coldbasis = ibLOGICAL ;
    main_lpopts->scaling = 2 ;
/*
    main_lpopts->print.major = 1 ;
    main_lpopts->print.phase1 = 4 ;
    main_lpopts->print.phase2 = 4 ;
    main_lpopts->print.dual = 4 ;
    main_lpopts->print.tableau = 4 ;
    main_lpopts->print.soln = 3 ;
    main_lpopts->print.rays = 5 ;
*/

    dyio_outfmt(ttyout,dy_gtxecho,"Solving galenet ... ") ;
    lpretval = do_lp(main_lp,main_lptols,main_lpopts,1) ;
    dyio_outfmt(ttyout,dy_gtxecho,"\n  %s, z = %.12f.\n",
		dy_prtlpret(lpretval),main_lp->obj) ;
    z = 46.0 ;
    if (!(fabs(main_lp->obj-z) <= main_lptols->cost))
    { errcnt++ ;
      dyio_outfmt(ttyout,dy_gtxecho,
		  "  ERROR: z = %g, expected %g, error %g, tol %g.\n",
		  main_lp->obj,z,fabs(main_lp->obj-z),main_lptols->cost) ; }
    dumpsoln = TRUE ;
    if (dumpsoln == TRUE)
    { dy_dumpcompact(dy_logchn,dy_gtxecho,main_lp,FALSE) ; }
/*
  Test that we have valid dual rays. First ask for just one, then ask for
  five, expecting two. Note that we end up at a different vertex than the
  previous expanded versions of galenet.
*/
    cnt = 1 ;
    errcnt += dytest_dualRays(&cnt,main_lp,main_lptols,main_lpopts) ;
    if (cnt != 1)
    { errcnt++ ;
      dyio_outfmt(ttyout,dy_gtxecho,
		  "  ERROR: %d dual rays returned, expected %d.\n",
		  cnt,1) ; }
    cnt = 5 ;
    errcnt += dytest_dualRays(&cnt,main_lp,main_lptols,main_lpopts) ;
    if (cnt != 2)
    { errcnt++ ;
      dyio_outfmt(ttyout,dy_gtxecho,
		  "  ERROR: %d dual rays returned, expected %d.\n",
		  cnt,2) ; }
/*
  Run the remainder of the tests, to make sure they run without error when
  dylp finishes infeasible.
*/
    errcnt += dytest_betaj(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_abarj(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_betai(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_abari(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_rowDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_colDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_allDuals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_colPrimals(main_lp,main_lptols,main_lpopts) ;
    errcnt += dytest_rowPrimals(main_lp,main_lptols,main_lpopts) ;

    comflg(main_lp->ctlopts,lpctlONLYFREE|lpctlNOFREE) ;
    dylp(main_lp,main_lpopts,main_lptols,NULL) ;
    consys_free(main_sys) ;
    main_sys = NULL ;
    main_lp->consys = NULL ;
    dy_freesoln(main_lp) ; }
#endif

/*
  Report the result before we shut down.
*/
  if (errcnt > 0)
  { dyio_outfmt(ttyout,dy_gtxecho,
		"\n  ERROR: %d total errors for all tests.\n\n", errcnt) ; }
  else
  { dyio_outfmt(ttyout,dy_gtxecho,
		"\n  All tests completed successfully.\n\n") ; }
  dy_freebasis() ;

/*
  Final cleanup. Free space used by the remaining main_* structures and close
  down any i/o.
*/
  if (main_lp != NULL)
  { dy_freesoln(main_lp) ;
    if (main_lp->consys != NULL) consys_free(main_lp->consys) ;
    FREE(main_lp) ; }
  if (main_lpopts != NULL) FREE(main_lpopts) ;
  if (main_lptols != NULL) FREE(main_lptols) ;

  if (outchn != IOID_INV && outchn != ttyout)
  { (void) dyio_closefile(outchn) ; }

  if (dy_logchn != IOID_INV && dy_logchn != IOID_NOSTRM)
  { (void) dyio_closefile(dy_logchn) ; }
  dyio_ioterm() ;
  errterm() ;

  return (errcnt) ; }
Esempio n. 4
0
dyret_enum dy_addtopivrej (int j, dyret_enum why,
			   double abarij, double maxabarij)

/*
  This routine adds x<j> to the rejected pivot list by adding an entry to
  pivrejlst and adding the NOPIVOT qualifier to x<j>'s status.
  If necessary, it expands the size of the list.

  Parameter:
    j:		the variable x<j> 
    why:	the reason it's going on the pivot reject list; one of
		dyrSINGULAR or dyrMADPIV
    abarij:	(why == dyrMADPIV) the pivot element
    maxabarij:	(why == dyrMADPIV) the maximum pivot element in the pivot
		column (primal) or row (dual).
  
  Returns: dyrOK if the entry is added without error, dyrFATAL if we can't
	   get more space, or if a paranoid check fails.
*/

{ int n,ndx,newsze ;
  double ratio ;
  const char *rtnnme = "dy_addtopivrej" ;

# ifndef DYLP_NDEBUG
  int saveprint ;

  saveprint = dy_opts->print.pivoting ;
  dy_opts->print.pivoting = 0 ;
# endif

/*
  We don't actually need the pivot ratio until further down, but it's handy
  to do it here where we can easily suppress the internal print, then restore
  the print level.
*/
  ratio = dy_chkpiv(abarij,maxabarij) ;
  n = dy_sys->varcnt ;

# ifndef DYLP_NDEBUG
  dy_opts->print.pivoting = saveprint ;
# endif
# ifdef DYLP_PARANOIA
  if (j < 1 || j > n)
  { errmsg(102,rtnnme,dy_sys->nme,"variable",j,1,n) ;
    return (dyrFATAL) ; }
  if (!(why == dyrSINGULAR || why == dyrMADPIV))
  { errmsg(1,rtnnme,__LINE__) ;
    return (dyrFATAL) ; }
# endif
# ifndef DYLP_NDEBUG
/*
  The default case in this switch is needed to suppress GCC warnings --- it
  doesn't grok the paranoid check.
*/
  if (dy_opts->print.pivreject >= 2)
  { dyio_outfmt(dy_logchn,dy_gtxecho,
	        "\n  marking %s (%d) ineligible for pivoting ",
	        consys_nme(dy_sys,'v',j,TRUE,NULL),j) ;
    switch (why)
    { case dyrSINGULAR:
      { dyio_outfmt(dy_logchn,dy_gtxecho,"(%s).",dy_prtdyret(why)) ;
	break ; }
      case dyrMADPIV:
      { dyio_outfmt(dy_logchn,dy_gtxecho,"(%s = %g).",dy_prtdyret(why),ratio) ;
	break ; }
      default:
      { errmsg(1,rtnnme,__LINE__) ;
	return (dyrFATAL) ; } } }
# endif

/*
  Flag the culprit --- the extent of externally visible activity.  Then make
  the entry in the pivot reject list. Check for adequate list length and
  expand if necessary.
*/
  setflg(dy_status[j],vstatNOPIVOT) ;
  ndx = pivrej_ctl.cnt++ ;
  if (ndx >= pivrej_ctl.sze)
  { newsze = minn(2*pivrej_ctl.sze,n+1) ;
#   ifndef DYLP_NDEBUG
    if (dy_opts->print.pivreject >= 3)
    { dyio_outfmt(dy_logchn,dy_gtxecho,
		  "\n%s: expanding pivot reject list from %d to %d entries.",
		  rtnnme,pivrej_ctl.sze,newsze) ; }
#   endif
    pivrejlst =
      (pivrej_struct *) REALLOC(pivrejlst,newsze*sizeof(pivrej_struct)) ;
    if (pivrejlst == NULL)
    { errmsg(337,rtnnme,dy_sys->nme,pivrej_ctl.sze,newsze) ;
      return (dyrFATAL) ; }
    pivrej_ctl.sze = newsze ; }
  pivrejlst[ndx].ndx = j ;
  pivrejlst[ndx].iter = dy_lp->basis.pivs ;
  pivrejlst[ndx].why = why ;
  switch (why)
  { case dyrSINGULAR:
    { pivrej_ctl.sing++ ;
      break ; }
    case dyrMADPIV:
    { pivrej_ctl.mad++ ;
      ratio = dy_chkpiv(abarij,maxabarij) ;
      pivrejlst[ndx].ratio = ratio*dy_tols->pivot ;
      break ; }
    default:
    { errmsg(1,rtnnme,__LINE__) ;
      return (dyrFATAL) ; } }

# ifdef DYLP_STATISTICS
  if (dy_stats != NULL)
  { switch (why)
    { case dyrSINGULAR:
      { dy_stats->pivrej.sing++ ;
	break ; }
      case dyrMADPIV:
      { dy_stats->pivrej.mad++ ;
	break ; }
      default:
      { errmsg(1,rtnnme,__LINE__) ;
	return (dyrFATAL) ; } }
    if (pivrej_ctl.cnt > dy_stats->pivrej.max)
    { dy_stats->pivrej.max = pivrej_ctl.cnt ; } }
# endif

  return (dyrOK) ; }