source: branches/pre/Test/ClpMain.cpp @ 221

Last change on this file since 221 was 221, checked in by forrest, 17 years ago

Still trying to go faster

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 68.0 KB
Line 
1// Copyright (C) 2002, International Business Machines
2// Corporation and others.  All Rights Reserved.
3
4#include "CoinPragma.hpp"
5
6#include <cassert>
7#include <cstdio>
8#include <cmath>
9#include <cfloat>
10#include <string>
11#include <iostream>
12
13
14#include "CoinPragma.hpp"
15#include "CoinHelperFunctions.hpp"
16#define CLPVERSION "0.98.5"
17
18#include "CoinMpsIO.hpp"
19
20#include "ClpFactorization.hpp"
21#include "CoinTime.hpp"
22#include "ClpSimplex.hpp"
23#include "ClpSolve.hpp"
24#include "ClpPackedMatrix.hpp"
25#include "ClpPlusMinusOneMatrix.hpp"
26#include "ClpNetworkMatrix.hpp"
27#include "ClpDualRowSteepest.hpp"
28#include "ClpDualRowDantzig.hpp"
29#include "ClpLinearObjective.hpp"
30#include "ClpPrimalColumnSteepest.hpp"
31#include "ClpPrimalColumnDantzig.hpp"
32#include "ClpPresolve.hpp"
33
34// For Branch and bound
35//  #include "OsiClpSolverInterface.hpp"
36//  #include "OsiCuts.hpp"
37//  #include "OsiRowCut.hpp"
38//  #include "OsiColCut.hpp"
39
40#ifdef DMALLOC
41#include "dmalloc.h"
42#endif
43
44static double totalTime=0.0;
45
46//#############################################################################
47
48#ifdef NDEBUG
49#undef NDEBUG
50#endif
51
52int mainTest (int argc, const char *argv[],bool doDual,
53              ClpSimplex empty, bool doPresolve,int doIdiot);
54enum ClpParameterType {
55  GENERALQUERY=-100,
56 
57  DUALTOLERANCE=1,PRIMALTOLERANCE,DUALBOUND,PRIMALWEIGHT,MAXTIME,OBJSCALE,
58
59  LOGLEVEL=101,MAXFACTOR,PERTVALUE,MAXITERATION,PRESOLVEPASS,IDIOT,SPRINT,
60 
61  DIRECTION=201,DUALPIVOT,SCALING,ERRORSALLOWED,KEEPNAMES,SPARSEFACTOR,
62  PRIMALPIVOT,PRESOLVE,CRASH,BIASLU,PERTURBATION,MESSAGES,
63 
64  DIRECTORY=301,IMPORT,EXPORT,RESTORE,SAVE,DUALSIMPLEX,PRIMALSIMPLEX,
65  MAXIMIZE,MINIMIZE,EXIT,STDIN,UNITTEST,NETLIB_DUAL,NETLIB_PRIMAL,SOLUTION,
66  TIGHTEN,FAKEBOUND,HELP,PLUSMINUS,NETWORK,ALLSLACK,REVERSE,
67
68  INVALID=1000
69};
70static void printit(const char * input)
71{
72  int length =strlen(input);
73  char temp[101];
74  int i;
75  int n=0;
76  for (i=0;i<length;i++) {
77    if (input[i]=='\n') {
78      temp[n]='\0';
79      std::cout<<temp<<std::endl;
80      n=0;
81    } else if (n>=65&&input[i]==' ') {
82      temp[n]='\0';
83      std::cout<<temp<<std::endl;
84      n=0;
85    } else if (n||input[i]!=' ') {
86      temp[n++]=input[i];
87    }
88  }
89  if (n) {
90    temp[n]='\0';
91    std::cout<<temp<<std::endl;
92  }
93}
94/// Very simple class for setting parameters
95class ClpItem {
96
97public:
98
99  /**@name Constructor and destructor */
100  //@{
101  /// Constructors
102  ClpItem (  );
103  ClpItem (std::string name, std::string help,
104           double lower, double upper, ClpParameterType type,bool display=true);
105  ClpItem (std::string name, std::string help,
106           int lower, int upper, ClpParameterType type,bool display=true);
107  // Other strings will be added by insert
108  ClpItem (std::string name, std::string help, std::string firstValue,
109           ClpParameterType type,int defaultIndex=0,bool display=true);
110  // Action
111  ClpItem (std::string name, std::string help,
112           ClpParameterType type,int indexNumber=-1,bool display=true);
113  /// Copy constructor.
114  ClpItem(const ClpItem &);
115  /// Assignment operator. This copies the data
116    ClpItem & operator=(const ClpItem & rhs);
117  /// Destructor
118  ~ClpItem (  );
119  //@}
120
121  /**@name stuff */
122  //@{
123  /// Insert string (only valid for keywords)
124  void append(std::string keyWord);
125  /// Adds one help line
126  void addHelp(std::string keyWord);
127  /// Returns name
128  inline std::string  name(  ) const {
129    return name_;
130  };
131  /// Returns short help
132  inline std::string  shortHelp(  ) const {
133    return shortHelp_;
134  };
135  /// Sets a double parameter (nonzero code if error)
136  int setDoubleParameter(ClpSimplex * model, double value) const;
137  /// Gets a double parameter
138  double doubleParameter(ClpSimplex * model) const;
139  /// Sets a int parameter (nonzero code if error)
140  int setIntParameter(ClpSimplex * model, int value) const;
141  /// Gets a int parameter
142  int intParameter(ClpSimplex * model) const;
143  /// Returns name which could match
144  std::string matchName (  ) const;
145  /// Returns parameter option which matches (-1 if none)
146  int parameterOption ( std::string check ) const;
147  /// Prints parameter options
148  void printOptions (  ) const;
149  /// Returns current parameter option
150  inline std::string currentOption (  ) const
151  { return definedKeyWords_[currentKeyWord_]; };
152  /// Sets current parameter option
153  inline void setCurrentOption ( int value )
154  { currentKeyWord_=value; };
155  /// Sets int value
156  inline void setIntValue ( int value )
157  { intValue_=value; };
158  inline int intValue () const
159  { return intValue_; };
160  /// Sets double value
161  inline void setDoubleValue ( double value )
162  { doubleValue_=value; };
163  inline double doubleValue () const
164  { return doubleValue_; };
165  /// Sets string value
166  inline void setStringValue ( std::string value )
167  { stringValue_=value; };
168  inline std::string stringValue () const
169  { return stringValue_; };
170  /// Returns 1 if matches minimum, 2 if matches less, 0 if not matched
171  int matches (std::string input) const;
172  /// type
173  inline ClpParameterType type() const
174  { return type_;};
175  /// whether to display
176  inline bool displayThis() const
177  { return display_;};
178  /// Set Long help
179  inline void setLonghelp(const std::string help) 
180  {longHelp_=help;};
181  /// Print Long help
182  void printLongHelp() const;
183  /// Print action and string
184  void printString() const;
185  /// type for classification
186  inline int indexNumber() const
187  { return indexNumber_;};
188private:
189  /// gutsOfConstructor
190  void gutsOfConstructor();
191  //@}
192////////////////// data //////////////////
193private:
194
195  /**@name data
196   We might as well throw all type data in - could derive?
197  */
198  //@{
199  // Type see ClpParameterType
200  ClpParameterType type_;
201  /// If double == okay
202  double lowerDoubleValue_;
203  double upperDoubleValue_;
204  /// If int == okay
205  int lowerIntValue_;
206  int upperIntValue_;
207  // Length of name
208  unsigned int lengthName_;
209  // Minimum match
210  unsigned int lengthMatch_;
211  /// set of valid strings
212  std::vector<std::string> definedKeyWords_;
213  /// Name
214  std::string name_;
215  /// Short help
216  std::string shortHelp_;
217  /// Long help
218  std::string longHelp_;
219  /// Action
220  ClpParameterType action_;
221  /// Current keyWord (if a keyword parameter)
222  int currentKeyWord_;
223  /// Display on ?
224  bool display_;
225  /// Integer parameter - current value
226  int intValue_;
227  /// Double parameter - current value
228  double doubleValue_;
229  /// String parameter - current value
230  std::string stringValue_;
231  /// index number to use for display purposes
232  int indexNumber_;
233  //@}
234};
235//#############################################################################
236// Constructors / Destructor / Assignment
237//#############################################################################
238
239//-------------------------------------------------------------------
240// Default Constructor
241//-------------------------------------------------------------------
242ClpItem::ClpItem () 
243  : type_(INVALID),
244    lowerDoubleValue_(0.0),
245    upperDoubleValue_(0.0),
246    lowerIntValue_(0),
247    upperIntValue_(0),
248    lengthName_(0),
249    lengthMatch_(0),
250    definedKeyWords_(),
251    name_(),
252    shortHelp_(),
253    longHelp_(),
254    action_(INVALID),
255    currentKeyWord_(-1),
256    display_(false),
257    intValue_(-1),
258    doubleValue_(-1.0),
259    stringValue_(""),
260    indexNumber_(INVALID)
261{
262}
263// Other constructors
264ClpItem::ClpItem (std::string name, std::string help,
265           double lower, double upper, ClpParameterType type,bool display)
266  : type_(type),
267    lowerIntValue_(0),
268    upperIntValue_(0),
269    definedKeyWords_(),
270    name_(name),
271    shortHelp_(help),
272    longHelp_(),
273    action_(type),
274    currentKeyWord_(-1),
275    display_(display),
276    intValue_(-1),
277    doubleValue_(-1.0),
278    stringValue_(""),
279    indexNumber_(type)
280{
281  lowerDoubleValue_ = lower;
282  upperDoubleValue_ = upper;
283  gutsOfConstructor();
284}
285ClpItem::ClpItem (std::string name, std::string help,
286           int lower, int upper, ClpParameterType type,bool display)
287  : type_(type),
288    lowerDoubleValue_(0.0),
289    upperDoubleValue_(0.0),
290    definedKeyWords_(),
291    name_(name),
292    shortHelp_(help),
293    longHelp_(),
294    action_(type),
295    currentKeyWord_(-1),
296    display_(display),
297    intValue_(-1),
298    doubleValue_(-1.0),
299    stringValue_(""),
300    indexNumber_(type)
301{
302  gutsOfConstructor();
303  lowerIntValue_ = lower;
304  upperIntValue_ = upper;
305}
306// Other strings will be added by append
307ClpItem::ClpItem (std::string name, std::string help, 
308                  std::string firstValue,
309                  ClpParameterType type,
310                  int defaultIndex,bool display)
311  : type_(type),
312    lowerDoubleValue_(0.0),
313    upperDoubleValue_(0.0),
314    lowerIntValue_(0),
315    upperIntValue_(0),
316    definedKeyWords_(),
317    name_(name),
318    shortHelp_(help),
319    longHelp_(),
320    action_(type),
321    currentKeyWord_(defaultIndex),
322    display_(display),
323    intValue_(-1),
324    doubleValue_(-1.0),
325    stringValue_(""),
326    indexNumber_(type)
327{
328  gutsOfConstructor();
329  definedKeyWords_.push_back(firstValue);
330}
331// Action
332ClpItem::ClpItem (std::string name, std::string help,
333           ClpParameterType type,int indexNumber,bool display)
334  : type_(type),
335    lowerDoubleValue_(0.0),
336    upperDoubleValue_(0.0),
337    lowerIntValue_(0),
338    upperIntValue_(0),
339    definedKeyWords_(),
340    name_(name),
341    shortHelp_(help),
342    longHelp_(),
343    action_(type),
344    currentKeyWord_(-1),
345    display_(display),
346    intValue_(-1),
347    doubleValue_(-1.0),
348    stringValue_("")
349{
350  if (indexNumber<0)
351    indexNumber_=type;
352  else
353    indexNumber_=indexNumber;
354  gutsOfConstructor();
355}
356
357//-------------------------------------------------------------------
358// Copy constructor
359//-------------------------------------------------------------------
360ClpItem::ClpItem (const ClpItem & rhs) 
361{ 
362  type_ = rhs.type_;
363  lowerDoubleValue_ = rhs.lowerDoubleValue_;
364  upperDoubleValue_ = rhs.upperDoubleValue_;
365  lowerIntValue_ = rhs.lowerIntValue_;
366  upperIntValue_ = rhs.upperIntValue_;
367  lengthName_ = rhs.lengthName_;
368  lengthMatch_ = rhs.lengthMatch_;
369  definedKeyWords_ = rhs.definedKeyWords_;
370  name_ = rhs.name_;
371  shortHelp_ = rhs.shortHelp_;
372  longHelp_ = rhs.longHelp_;
373  action_ = rhs.action_;
374  currentKeyWord_ = rhs.currentKeyWord_;
375  display_=rhs.display_;
376  intValue_=rhs.intValue_;
377  doubleValue_=rhs.doubleValue_;
378  stringValue_=rhs.stringValue_;
379  indexNumber_=rhs.indexNumber_;
380}
381
382//-------------------------------------------------------------------
383// Destructor
384//-------------------------------------------------------------------
385ClpItem::~ClpItem ()
386{
387}
388
389//----------------------------------------------------------------
390// Assignment operator
391//-------------------------------------------------------------------
392ClpItem &
393ClpItem::operator=(const ClpItem& rhs)
394{
395  if (this != &rhs) {
396    type_ = rhs.type_;
397    lowerDoubleValue_ = rhs.lowerDoubleValue_;
398    upperDoubleValue_ = rhs.upperDoubleValue_;
399    lowerIntValue_ = rhs.lowerIntValue_;
400    upperIntValue_ = rhs.upperIntValue_;
401    lengthName_ = rhs.lengthName_;
402    lengthMatch_ = rhs.lengthMatch_;
403    definedKeyWords_ = rhs.definedKeyWords_;
404    name_ = rhs.name_;
405    shortHelp_ = rhs.shortHelp_;
406    longHelp_ = rhs.longHelp_;
407    action_ = rhs.action_;
408    currentKeyWord_ = rhs.currentKeyWord_;
409    display_=rhs.display_;
410    intValue_=rhs.intValue_;
411    doubleValue_=rhs.doubleValue_;
412    stringValue_=rhs.stringValue_;
413    indexNumber_=rhs.indexNumber_;
414  }
415  return *this;
416}
417void 
418ClpItem::gutsOfConstructor()
419{
420  unsigned int  shriekPos = name_.find('!');
421  lengthName_ = name_.length();
422  if ( shriekPos==std::string::npos ) {
423    //does not contain '!'
424    lengthMatch_= lengthName_;
425  } else {
426    lengthMatch_=shriekPos;
427    name_ = name_.substr(0,shriekPos)+name_.substr(shriekPos+1);
428    lengthName_--;
429  }
430}
431// Insert string (only valid for keywords)
432void 
433ClpItem::append(std::string keyWord)
434{
435  definedKeyWords_.push_back(keyWord);
436}
437
438int 
439ClpItem::matches (std::string input) const
440{
441  // look up strings to do more elegantly
442  if (input.length()>lengthName_) {
443    return 0;
444  } else {
445    unsigned int i;
446    for (i=0;i<input.length();i++) {
447      if (tolower(name_[i])!=tolower(input[i])) 
448        break;
449    }
450    if (i<input.length()) {
451      return 0;
452    } else if (i>=lengthMatch_) {
453      return 1;
454    } else {
455      // matched but too short
456      return 2;
457    }
458  }
459}
460// Returns name which could match
461std::string
462ClpItem::matchName (  ) const
463{ 
464  if (lengthMatch_==lengthName_) 
465    return name_;
466  else
467    return name_.substr(0,lengthMatch_)+"("+name_.substr(lengthMatch_)+")";
468}
469
470// Returns parameter option which matches (-1 if none)
471int 
472ClpItem::parameterOption ( std::string check ) const
473{
474  int numberItems = definedKeyWords_.size();
475  if (!numberItems) {
476    return -1;
477  } else {
478    int whichItem=0;
479    unsigned int it;
480    for (it=0;it<definedKeyWords_.size();it++) {
481      std::string thisOne = definedKeyWords_[it];
482      unsigned int  shriekPos = thisOne.find('!');
483      unsigned int length1 = thisOne.length();
484      unsigned int length2 = length1;
485      if ( shriekPos!=std::string::npos ) {
486        //contains '!'
487        length2 = shriekPos;
488        thisOne = thisOne.substr(0,shriekPos)+
489          thisOne.substr(shriekPos+1);
490        length1 = thisOne.length();
491      }
492      if (check.length()<=length1) {
493        unsigned int i;
494        for (i=0;i<check.length();i++) {
495          if (tolower(thisOne[i])!=tolower(check[i])) 
496            break;
497        }
498        if (i<check.length()) {
499          whichItem++;
500        } else if (i>=length2) {
501          break;
502        } 
503      } else {
504        whichItem++;
505      }
506    }
507    if (whichItem<numberItems)
508      return whichItem;
509    else
510      return -1;
511  }
512}
513// Prints parameter options
514void 
515ClpItem::printOptions (  ) const
516{
517  std::cout<<"Possible options for "<<name_<<" are:"<<std::endl;
518  unsigned int it;
519  for (it=0;it<definedKeyWords_.size();it++) {
520    std::string thisOne = definedKeyWords_[it];
521    unsigned int  shriekPos = thisOne.find('!');
522    if ( shriekPos!=std::string::npos ) {
523      //contains '!'
524      thisOne = thisOne.substr(0,shriekPos)+
525        "("+thisOne.substr(shriekPos+1)+")";
526    }
527    std::cout<<thisOne<<std::endl;
528  }
529}
530// Print action and string
531void 
532ClpItem::printString() const
533{
534  if (name_=="directory")
535    std::cout<<"Current working directory is "<<stringValue_<<std::endl;
536  else
537    std::cout<<"Current default (if $ as parameter) for "<<name_
538             <<" is "<<stringValue_<<std::endl;
539}
540int
541ClpItem::setDoubleParameter (ClpSimplex * model,double value) const
542{
543  double oldValue = doubleParameter(model);
544  if (value<lowerDoubleValue_||value>upperDoubleValue_) {
545    std::cout<<value<<" was provided for "<<name_<<
546      " - valid range is "<<lowerDoubleValue_<<" to "<<
547      upperDoubleValue_<<std::endl;
548    return 1;
549  } else {
550    std::cout<<name_<<" was changed from "<<oldValue<<" to "
551             <<value<<std::endl;
552    switch(type_) {
553    case DUALTOLERANCE:
554      model->setDualTolerance(value);
555      break;
556    case PRIMALTOLERANCE:
557      model->setPrimalTolerance(value);
558      break;
559    case DUALBOUND:
560      model->setDualBound(value);
561      break;
562    case PRIMALWEIGHT:
563      model->setInfeasibilityCost(value);
564      break;
565    case MAXTIME:
566      model->setMaximumSeconds(value);
567      break;
568    case OBJSCALE:
569      model->setOptimizationDirection(value);
570      break;
571    default:
572      abort();
573    }
574    return 0;
575  }
576}
577double 
578ClpItem::doubleParameter (ClpSimplex * model) const
579{
580  double value;
581  switch(type_) {
582  case DUALTOLERANCE:
583    value=model->dualTolerance();
584    break;
585  case PRIMALTOLERANCE:
586    value=model->primalTolerance();
587    break;
588  case DUALBOUND:
589    value=model->dualBound();
590    break;
591  case PRIMALWEIGHT:
592    value=model->infeasibilityCost();
593    break;
594  case MAXTIME:
595    value=model->maximumSeconds();
596    break;
597  case OBJSCALE:
598    value=model->optimizationDirection();
599    break;
600  default:
601    abort();
602  }
603  return value;
604}
605int 
606ClpItem::setIntParameter (ClpSimplex * model,int value) const
607{
608  int oldValue = intParameter(model);
609  if (value<lowerIntValue_||value>upperIntValue_) {
610    std::cout<<value<<" was provided for "<<name_<<
611      " - valid range is "<<lowerIntValue_<<" to "<<
612      upperIntValue_<<std::endl;
613    return 1;
614  } else {
615    std::cout<<name_<<" was changed from "<<oldValue<<" to "
616             <<value<<std::endl;
617    switch(type_) {
618    case LOGLEVEL:
619      model->setLogLevel(value);
620      break;
621    case MAXFACTOR:
622      model->factorization()->maximumPivots(value);
623      break;
624    case PERTVALUE:
625      model->setPerturbation(value);
626      break;
627    case MAXITERATION:
628      model->setMaximumIterations(value);
629      break;
630    default:
631      abort();
632    }
633    return 0;
634  }
635}
636int 
637ClpItem::intParameter (ClpSimplex * model) const
638{
639  int value;
640  switch(type_) {
641  case LOGLEVEL:
642    value=model->logLevel();
643    break;
644  case MAXFACTOR:
645    value=model->factorization()->maximumPivots();
646    break;
647    break;
648  case PERTVALUE:
649    value=model->perturbation();
650    break;
651  case MAXITERATION:
652    value=model->maximumIterations();
653    break;
654  default:
655    value=-1;
656    break;
657  }
658  return value;
659}
660// Print Long help
661void 
662ClpItem::printLongHelp() const
663{
664  if (type_>=1&&type_<400) {
665    if (type_<LOGLEVEL) {
666      printf("Range of values is %g to %g\n",lowerDoubleValue_,upperDoubleValue_);
667    } else if (type_<DIRECTION) {
668      printf("Range of values is %d to %d\n",lowerIntValue_,upperIntValue_);
669    } else if (type_<DIRECTORY) {
670      printOptions();
671    }
672    printit(longHelp_.c_str());
673  }
674}
675#ifdef READLINE     
676#include <readline/readline.h>
677#include <readline/history.h>
678#endif
679// Returns next valid field
680static int read_mode=1;
681static char line[1000];
682static char * where=NULL;
683
684std::string
685nextField()
686{
687  std::string field;
688  if (!where) {
689    // need new line
690#ifdef READLINE     
691    // Get a line from the user.
692    where = readline ("Clp:");
693     
694    // If the line has any text in it, save it on the history.
695    if (where) {
696      if ( *where)
697        add_history (where);
698      strcpy(line,where);
699    }
700#else
701    fprintf(stdout,"Clp:");
702    fflush(stdout);
703    where = fgets(line,1000,stdin);
704#endif
705    if (!where)
706      return field; // EOF
707    where = line;
708    // clean image
709    char * lastNonBlank = line-1;
710    while ( *where != '\0' ) {
711      if ( *where != '\t' && *where < ' ' ) {
712        break;
713      } else if ( *where != '\t' && *where != ' ') {
714        lastNonBlank = where;
715      }
716      where++;
717    }
718    where=line;
719    *(lastNonBlank+1)='\0';
720  }
721  // munch white space
722  while(*where==' '||*where=='\t')
723    where++;
724  char * saveWhere = where;
725  while (*where!=' '&&*where!='\t'&&*where!='\0')
726    where++;
727  if (where!=saveWhere) {
728    char save = *where;
729    *where='\0';
730    //convert to string
731    field=saveWhere;
732    *where=save;
733  } else {
734    where=NULL;
735    field="EOL";
736  }
737  return field;
738}
739
740std::string
741getCommand(int argc, const char *argv[])
742{
743  std::string field="EOL";
744  while (field=="EOL") {
745    if (read_mode>0) {
746      if (read_mode<argc) {
747        field = argv[read_mode++];
748        if (field=="-") {
749          std::cout<<"Switching to line mode"<<std::endl;
750          read_mode=-1;
751          field=nextField();
752        } else if (field[0]!='-') {
753          if (read_mode!=2) {
754            std::cout<<"skipping non-command "<<field<<std::endl;
755            field="EOL"; // skip
756          } else {
757            // special dispensation - taken as -import name
758            read_mode--;
759            field="import";
760          }
761        } else {
762          if (field!="--") {
763            // take off -
764            field = field.substr(1);
765          } else {
766            // special dispensation - taken as -import --
767            read_mode--;
768            field="import";
769          }
770        }
771      } else {
772        field="";
773      }
774    } else {
775      field=nextField();
776    }
777  }
778  //std::cout<<field<<std::endl;
779  return field;
780}
781std::string
782getString(int argc, const char *argv[])
783{
784  std::string field="EOL";
785  if (read_mode>0) {
786    if (read_mode<argc) {
787      if (argv[read_mode][0]!='-') { 
788        field = argv[read_mode++];
789      } else if (!strcmp(argv[read_mode],"--")) {
790        field = argv[read_mode++];
791        // -- means import from stdin
792        field = "-";
793      }
794    }
795  } else {
796    field=nextField();
797  }
798  //std::cout<<field<<std::endl;
799  return field;
800}
801// valid 0 - okay, 1 bad, 2 not there
802int
803getIntField(int argc, const char *argv[],int * valid)
804{
805  std::string field="EOL";
806  if (read_mode>0) {
807    if (read_mode<argc) {
808      // may be negative value so do not check for -
809      field = argv[read_mode++];
810    }
811  } else {
812    field=nextField();
813  }
814  int value=0;
815  //std::cout<<field<<std::endl;
816  if (field!="EOL") {
817    // how do I check valid
818    value =  atoi(field.c_str());
819    *valid=0;
820  } else {
821    *valid=2;
822  }
823  return value;
824}
825double
826getDoubleField(int argc, const char *argv[],int * valid)
827{
828  std::string field="EOL";
829  if (read_mode>0) {
830    if (read_mode<argc) {
831      // may be negative value so do not check for -
832      field = argv[read_mode++];
833    }
834  } else {
835    field=nextField();
836  }
837  double value=0.0;
838  //std::cout<<field<<std::endl;
839  if (field!="EOL") {
840    // how do I check valid
841    value = atof(field.c_str());
842    *valid=0;
843  } else {
844    *valid=2;
845  }
846  return value;
847}
848int main (int argc, const char *argv[])
849{
850  // next {} is just to make sure all memory should be freed - for debug
851  {
852    double time1 = CoinCpuTime(),time2;
853    // Set up all non-standard stuff
854    //int numberModels=1;
855    ClpSimplex * models = new ClpSimplex[1];
856   
857    // default action on import
858    int allowImportErrors=0;
859    int keepImportNames=1;
860    int doIdiot=-1;
861    int doCrash=0;
862    int doSprint=-1;
863    // set reasonable defaults
864    int preSolve=5;
865    models->setPerturbation(50);
866    models->messageHandler()->setPrefix(false);
867    std::string directory ="./";
868    std::string importFile ="";
869    std::string exportFile ="default.mps";
870    std::string saveFile ="default.prob";
871    std::string restoreFile ="default.prob";
872    std::string solutionFile ="stdout";
873#define MAXPARAMETERS 100
874    ClpItem parameters[MAXPARAMETERS];
875    int numberParameters=0;
876    parameters[numberParameters++]=
877      ClpItem("?","For help",GENERALQUERY,-1,false);
878    parameters[numberParameters++]=
879      ClpItem("-","From stdin",
880              STDIN,299,false);
881    parameters[numberParameters++]=
882      ClpItem("allS!lack","Set basis back to all slack",
883              ALLSLACK,false);
884    parameters[numberParameters-1].setLonghelp
885      (
886       "Useful for playing around"
887       ); 
888    parameters[numberParameters++]=
889      ClpItem("biasLU","Whether factorization biased towards U",
890              "UU",BIASLU,2,false);
891    parameters[numberParameters-1].append("UX");
892    parameters[numberParameters-1].append("LX");
893    parameters[numberParameters-1].append("LL");
894    parameters[numberParameters++]=
895      ClpItem("crash","Whether to create basis for problem",
896              "off",CRASH);
897    parameters[numberParameters-1].append("on");
898    parameters[numberParameters-1].setLonghelp
899      (
900       "If crash is set on and there is an all slack basis then Clp will put structural\
901 variables into basis with the aim of getting dual feasible.  On the whole dual seems to be\
902 better without it and there alernative types of 'crash' for primal e.g. 'idiot' or 'sprint'."
903       ); 
904    parameters[numberParameters++]=
905      ClpItem("direction","Minimize or Maximize",
906              "min!imize",DIRECTION);
907    parameters[numberParameters-1].append("max!imize");
908    parameters[numberParameters-1].append("zero");
909    parameters[numberParameters-1].setLonghelp
910      (
911       "The default is minimize - use 'direction maximize' for maximization.\n\
912You can also use the parameters 'maximize' or 'minimize'."
913       ); 
914    parameters[numberParameters++]=
915      ClpItem("directory","Set Default directory for import etc.",
916              DIRECTORY,299);
917    parameters[numberParameters-1].setLonghelp
918      (
919       "This sets the directory which import, export, saveModel and restoreModel will use.\
920  It is initialized to './'"
921       ); 
922    parameters[numberParameters-1].setStringValue(directory);
923    parameters[numberParameters++]=
924      ClpItem("dualB!ound","Initially algorithm acts as if no \
925gap between bounds exceeds this value",
926              1.0e-20,1.0e12,DUALBOUND);
927    parameters[numberParameters-1].setLonghelp
928      (
929       "The dual algorithm in Clp is a single phase algorithm as opposed to a two phase\
930 algorithm where you first get feasible then optimal.  If a problem has both upper and\
931 lower bounds then it is trivial to get dual feasible by setting non basic variables\
932 to correct bound.  If the gap between the upper and lower bounds of a variable is more\
933 than the value of dualBound Clp introduces fake bounds so that it can make the problem\
934 dual feasible.  This has the same effect as a composite objective function in the\
935 primal algorithm.  Too high a value may mean more iterations, while too low a bound means\
936 the code may go all the way and then have to increase the bounds.  OSL had a heuristic to\
937 adjust bounds, maybe we need that here."
938       );
939    parameters[numberParameters-1].setDoubleValue(models->dualBound());
940    parameters[numberParameters++]=
941      ClpItem("dualP!ivot","Dual pivot choice algorithm",
942              "auto!matic",DUALPIVOT);
943    parameters[numberParameters-1].append("dant!zig");
944    parameters[numberParameters-1].append("partial");
945    parameters[numberParameters-1].append("steep!est");
946    parameters[numberParameters-1].setLonghelp
947      (
948       "Clp can use any pivot selection algorithm which the user codes as long as it\
949 implements the features in the abstract pivot base class.  The Dantzig method is implemented\
950 to show a simple method but its use is deprecated.  Steepest is the method of choice and there\
951 are two variants which keep all weights updated but only scan a subset each iteration.\
952 Partial switches this on while automatic decides at each iteration based on information\
953 about the factorization."
954       ); 
955    parameters[numberParameters++]=
956      ClpItem("dualS!implex","Do dual simplex algorithm",
957              DUALSIMPLEX);
958    parameters[numberParameters-1].setLonghelp
959      (
960       "This command solves the current model using the dual steepest algorithm.\
961The time and iterations may be affected by settings such as presolve, scaling, crash\
962 and also by dual pivot method, fake bound on variables and dual and primal tolerances."
963       ); 
964    parameters[numberParameters++]=
965      ClpItem("dualT!olerance","For an optimal solution \
966no dual infeasibility may exceed this value",
967              1.0e-20,1.0e12,DUALTOLERANCE);
968    parameters[numberParameters-1].setLonghelp
969      (
970       "Normally the default tolerance is fine, but you may want to increase it a\
971 bit if a dual run seems to be having a hard time"
972       ); 
973    parameters[numberParameters-1].setDoubleValue(models->dualTolerance());
974    parameters[numberParameters++]=
975      ClpItem("end","Stops clp execution",
976              EXIT);
977    parameters[numberParameters-1].setLonghelp
978      (
979       "This stops the execution of Clp, end, exit, quit and stop are synonyms"
980       ); 
981    parameters[numberParameters++]=
982      ClpItem("error!sAllowed","Whether to allow import errors",
983              "off",ERRORSALLOWED);
984    parameters[numberParameters-1].setLonghelp
985      (
986       "The default is not to use any model which had errors when reading the mps file.\
987  Setting this to 'on' will allow all errors from which the code can recover\
988 by ignoring the error."
989       );
990    parameters[numberParameters++]=
991      ClpItem("exit","Stops clp execution",
992              EXIT);
993    parameters[numberParameters-1].setLonghelp
994      (
995       "This stops the execution of Clp, end, exit, quit and stop are synonyms"
996       ); 
997    parameters[numberParameters++]=
998      ClpItem("export","Export model as mps file",
999              EXPORT);
1000    parameters[numberParameters-1].setLonghelp
1001      (
1002       "This will write an MPS format file to the given file name.  It will use the default\
1003 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1004 is initialized to 'default.mps'."
1005       ); 
1006    parameters[numberParameters-1].setStringValue(exportFile);
1007    parameters[numberParameters++]=
1008      ClpItem("fakeB!ound","All bounds <= this value - DEBUG",
1009              1.0,1.0e15,FAKEBOUND,false);
1010    parameters[numberParameters++]=
1011      ClpItem("help","Print out version, non-standard options and some help",
1012              HELP);
1013    parameters[numberParameters++]=
1014      ClpItem("idiot!Crash","Whether to try idiot crash",
1015              -1,200,IDIOT);
1016    parameters[numberParameters-1].setLonghelp
1017      (
1018       "This is a type of 'crash' which works well on some homogeneous problems.\
1019 It works best on problems with unit elements and rhs but will do something to any model.  It should only be\
1020 used before primal.  It can be set to -1 when the code decides for itself whether to use it,\
1021 0 to switch off or n > 0 to do n passes."
1022       ); 
1023    parameters[numberParameters-1].setIntValue(doIdiot);
1024    parameters[numberParameters++]=
1025      ClpItem("import","Import model from mps file",
1026              IMPORT);
1027    parameters[numberParameters-1].setLonghelp
1028      (
1029       "This will read an MPS format file from the given file name.  It will use the default\
1030 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1031 is initialized to '', i.e. it must be set.  If you have libgz then it can read compressed\
1032 files 'xxxxxxxx.gz'.."
1033       ); 
1034    parameters[numberParameters-1].setStringValue(importFile);
1035    parameters[numberParameters++]=
1036      ClpItem("keepN!ames","Whether to keep names from import",
1037              "on",KEEPNAMES);
1038    parameters[numberParameters-1].append("off");
1039    parameters[numberParameters-1].setLonghelp
1040      (
1041       "It saves space to get rid of names so if you need to you can set this to off."
1042       ); 
1043    parameters[numberParameters++]=
1044      ClpItem("log!Level","Level of detail in output",
1045              0,63,LOGLEVEL);
1046    parameters[numberParameters-1].setLonghelp
1047      (
1048       "If 0 then there should be no output in normal circumstances.  1 is probably the best\
1049 value for most uses, while 2 and 3 give more information."
1050       ); 
1051    parameters[numberParameters-1].setIntValue(models->logLevel());
1052    parameters[numberParameters++]=
1053      ClpItem("max!imize","Set optimization direction to maximize",
1054              MAXIMIZE,299);
1055    parameters[numberParameters-1].setLonghelp
1056      (
1057       "The default is minimize - use 'maximize' for maximization.\n\
1058You can also use the parameters 'direction maximize'."
1059       ); 
1060    parameters[numberParameters++]=
1061      ClpItem("maxF!actor","Maximum number of iterations between \
1062refactorizations",
1063              1,999999,MAXFACTOR);
1064    parameters[numberParameters-1].setLonghelp
1065      (
1066       "If this is at its default value of 200 then in this executable clp will guess at a\
1067 value to use.  Otherwise the user can set a value.  The code may decide to re-factorize\
1068 earlier."
1069       ); 
1070    parameters[numberParameters-1].setIntValue(models->factorizationFrequency());
1071    parameters[numberParameters++]=
1072      ClpItem("maxIt!erations","Maximum number of iterations before \
1073stopping",
1074              0,99999999,MAXITERATION);
1075    parameters[numberParameters-1].setLonghelp
1076      (
1077       "This can be used for testing purposes.  The corresponding library call\n\
1078      \tsetMaximumIterations(value)\n can be useful.  If the code stops on\
1079 seconds or by an interrupt this will be treated as stopping on maximum iterations"
1080       ); 
1081    parameters[numberParameters-1].setIntValue(models->maximumIterations());
1082    parameters[numberParameters++]=
1083      ClpItem("min!imize","Set optimization direction to minimize",
1084              MINIMIZE,299);
1085    parameters[numberParameters-1].setLonghelp
1086      (
1087       "The default is minimize - use 'maximize' for maximization.\n\
1088This should only be necessary if you have previously set maximization \
1089You can also use the parameters 'direction minimize'."
1090       ); 
1091    parameters[numberParameters++]=
1092      ClpItem("mess!ages","Controls if Clpnnnn is printed",
1093              "off",MESSAGES);
1094    parameters[numberParameters-1].append("on");
1095    parameters[numberParameters-1].setLonghelp
1096      ("The default for the Clp library is to put out messages such as:\n\
1097   Clp0005 2261  Objective 109.024 Primal infeas 944413 (758)\n\
1098but this program turns this off to make it look more friendly.  It can be useful\
1099 to turn them back on if you want to be able 'grep' for particular messages or if\
1100 you intend to override the behavior of a particular message."
1101       ); 
1102    parameters[numberParameters++]=
1103      ClpItem("netlib","Solve entire netlib test set",
1104              NETLIB_DUAL,-1,false);
1105    parameters[numberParameters++]=
1106      ClpItem("netlibP!rimal","Solve entire netlib test set (primal)",
1107              NETLIB_PRIMAL,-1,false);
1108    parameters[numberParameters++]=
1109      ClpItem("network","Tries to make network matrix",
1110              NETWORK,-1,false);
1111    parameters[numberParameters-1].setLonghelp
1112      (
1113       "Clp will go faster if the matrix can be converted to a network.  The matrix\
1114 operations may be a bit faster with more efficient storage, but the main advantage\
1115 comes from using a network factorization.  It will probably not be as fast as a \
1116specialized network code."
1117       ); 
1118    parameters[numberParameters++]=
1119      ClpItem("objective!Scale","Scale factor to apply to objective",
1120              -1.0e20,1.0e20,OBJSCALE,false);
1121    parameters[numberParameters-1].setDoubleValue(models->optimizationDirection());
1122    parameters[numberParameters++]=
1123      ClpItem("passP!resolve","How many passes in presolve",
1124              0,100,PRESOLVEPASS);
1125    parameters[numberParameters-1].setLonghelp
1126      (
1127       "Normally Presolve does 5 passes but you may want to do less to make it\
1128 more lightweight or do more if improvements are still being made.  As Presolve will return\
1129 if nothing is being taken out, then you should not need to use this fine tuning."
1130       ); 
1131    parameters[numberParameters-1].setIntValue(preSolve);
1132    parameters[numberParameters++]=
1133      ClpItem("pertV!alue","Method of perturbation",
1134              -5000,102,PERTVALUE,false);
1135    parameters[numberParameters-1].setIntValue(models->perturbation());
1136    parameters[numberParameters++]=
1137      ClpItem("perturb!ation","Whether to perturb problem",
1138              "on",PERTURBATION);
1139    parameters[numberParameters-1].append("off");
1140    parameters[numberParameters-1].setLonghelp
1141      (
1142       "Perturbation helps to stop cycling, but Clp uses other measures for this.\
1143  However large problems and especially ones with unit elements and unit rhs or costs\
1144 benefit from perturbation.  Normally Clp tries to be intelligent, but you can switch this off.\
1145  The Clp library has this off by default.  This program has it on."
1146       ); 
1147    parameters[numberParameters++]=
1148      ClpItem("plus!Minus","Tries to make +- 1 matrix",
1149              PLUSMINUS,-1,false);
1150    parameters[numberParameters-1].setLonghelp
1151      (
1152       "Clp will go slightly faster if the matrix can be converted so that the elements are\
1153 not stored and are known to be unit.  The main advantage is memory use.  Clp may automatically\
1154 see if it can convert the problem so you should not need to use this."
1155       ); 
1156    parameters[numberParameters++]=
1157      ClpItem("presolve","Whether to presolve problem",
1158              "on",PRESOLVE);
1159    parameters[numberParameters-1].append("off");
1160    parameters[numberParameters-1].append("more");
1161    parameters[numberParameters-1].setLonghelp
1162      (
1163       "Presolve analyzes the model to find such things as redundant equations, equations\
1164 which fix some variables, equations which can be transformed into bounds etc etc.  For the\
1165 initial solve of any problem this is worth doing unless you know that it will have no effect."
1166       ); 
1167    parameters[numberParameters++]=
1168      ClpItem("primalP!ivot","Primal pivot choice algorithm",
1169              "auto!matic",PRIMALPIVOT);
1170    parameters[numberParameters-1].append("exa!ct");
1171    parameters[numberParameters-1].append("dant!zig");
1172    parameters[numberParameters-1].append("part!ial");
1173    parameters[numberParameters-1].append("steep!est");
1174    parameters[numberParameters-1].append("change");
1175    parameters[numberParameters-1].setLonghelp
1176      (
1177       "Clp can use any pivot selection algorithm which the user codes as long as it\
1178 implements the features in the abstract pivot base class.  The Dantzig method is implemented\
1179 to show a simple method but its use is deprecated.  Exact devex is the method of choice and there\
1180 are two variants which keep all weights updated but only scan a subset each iteration.\
1181 Partial switches this on while change initially does dantzig until the factorization\
1182 becomes denser.  This is still a work in progress."
1183       ); 
1184    parameters[numberParameters++]=
1185      ClpItem("primalS!implex","Do primal simplex algorithm",
1186              PRIMALSIMPLEX);
1187    parameters[numberParameters-1].setLonghelp
1188      (
1189       "This command solves the current model using the primal algorithm.\
1190  The default is to use exact devex.\
1191 The time and iterations may be affected by settings such as presolve, scaling, crash\
1192 and also by column selection  method, infeasibility weight and dual and primal tolerances."
1193       ); 
1194    parameters[numberParameters++]=
1195      ClpItem("primalT!olerance","For an optimal solution \
1196no primal infeasibility may exceed this value",
1197              1.0e-20,1.0e12,PRIMALTOLERANCE);
1198    parameters[numberParameters-1].setLonghelp
1199      (
1200       "Normally the default tolerance is fine, but you may want to increase it a\
1201 bit if a primal run seems to be having a hard time"
1202       ); 
1203    parameters[numberParameters-1].setDoubleValue(models->primalTolerance());
1204    parameters[numberParameters++]=
1205      ClpItem("primalW!eight","Initially algorithm acts as if it \
1206costs this much to be infeasible",
1207              1.0e-20,1.0e12,PRIMALWEIGHT);
1208    parameters[numberParameters-1].setLonghelp
1209      (
1210       "The primal algorithm in Clp is a single phase algorithm as opposed to a two phase\
1211 algorithm where you first get feasible then optimal.  So Clp is minimizing this weight times\
1212 the sum of primal infeasibilities plus the true objective function (in minimization sense).\
1213  Too high a value may mean more iterations, while too low a bound means\
1214 the code may go all the way and then have to increase the weight in order to get feasible.\
1215  OSL had a heuristic to\
1216 adjust bounds, maybe we need that here."
1217       ); 
1218    parameters[numberParameters-1].setDoubleValue(models->infeasibilityCost());
1219    parameters[numberParameters++]=
1220      ClpItem("quit","Stops clp execution",
1221              EXIT);
1222    parameters[numberParameters-1].setLonghelp
1223      (
1224       "This stops the execution of Clp, end, exit, quit and stop are synonyms"
1225       ); 
1226    parameters[numberParameters++]=
1227      ClpItem("restore!Model","Restore model from binary file",
1228              RESTORE);
1229    parameters[numberParameters-1].setLonghelp
1230      (
1231       "This reads data save by saveModel from the given file.  It will use the default\
1232 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1233 is initialized to 'default.prob'."
1234       ); 
1235    parameters[numberParameters-1].setStringValue(restoreFile);
1236    parameters[numberParameters++]=
1237      ClpItem("reverse","Reverses sign of objective",
1238              REVERSE,false);
1239    parameters[numberParameters-1].setLonghelp
1240      (
1241       "Useful for testing if maximization works correctly"
1242       ); 
1243    parameters[numberParameters++]=
1244      ClpItem("save!Model","Save model to binary file",
1245              SAVE);
1246    parameters[numberParameters-1].setLonghelp
1247      (
1248       "This will save the problem to the given file name for future use\
1249 by restoreModel.  It will use the default\
1250 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1251 is initialized to 'default.prob'."
1252       ); 
1253    parameters[numberParameters-1].setStringValue(saveFile);
1254    parameters[numberParameters++]=
1255      ClpItem("scal!ing","Whether to scale problem",
1256              "on",SCALING);
1257    parameters[numberParameters-1].append("off");
1258    parameters[numberParameters-1].append("geo!metric");
1259    parameters[numberParameters-1].append("auto!matic");
1260    parameters[numberParameters-1].setLonghelp
1261      (
1262       "Scaling can help in solving problems which might otherwise fail because of lack of\
1263 accuracy.  It can also reduce the number of iterations.  It is not applied if the range\
1264 of elements is small.  When unscaled it is possible that there may be small primal and/or\
1265 infeasibilities."
1266       ); 
1267    parameters[numberParameters++]=
1268      ClpItem("sec!onds","maximum seconds",
1269              0.0,1.0e12,MAXTIME);
1270    parameters[numberParameters-1].setLonghelp
1271      (
1272       "After this many seconds clp will act as if maximum iterations had been reached.\
1273  In this program it is really only useful for testing but the library function\n\
1274      \tsetMaximumSeconds(value)\n can be useful."
1275       ); 
1276    parameters[numberParameters-1].setDoubleValue(models->maximumSeconds());
1277    parameters[numberParameters++]=
1278      ClpItem("sol!ution","Prints solution to file",
1279              SOLUTION);
1280    parameters[numberParameters-1].setLonghelp
1281      (
1282       "This will write a primitive solution file to the given file name.  It will use the default\
1283 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1284 is initialized to 'stdout'."
1285       ); 
1286    parameters[numberParameters-1].setStringValue(solutionFile);
1287    parameters[numberParameters++]=
1288      ClpItem("spars!eFactor","Whether factorization treated as sparse",
1289              "on",SPARSEFACTOR,0,false);
1290    parameters[numberParameters-1].append("off");
1291    parameters[numberParameters-1].append("on");
1292    parameters[numberParameters++]=
1293      ClpItem("sprint!Crash","Whether to try sprint crash",
1294              -1,500,SPRINT);
1295    parameters[numberParameters-1].setLonghelp
1296      (
1297       "For long and thin problems this program may solve a series of small problems\
1298 created by taking a subset of the columns.  I introduced the idea as 'Sprint' after\
1299 an LP code of that name of the 60's which tried the same tactic (not totally successfully).\
1300  Cplex calls it 'sifting'.  -1 is automatic choice, 0 is off, n is number of passes"
1301       ); 
1302    parameters[numberParameters-1].setIntValue(doSprint);
1303      ClpItem("stdin","From stdin",
1304              STDIN,-1,false);
1305    parameters[numberParameters++]=
1306      ClpItem("stop","Stops clp execution",
1307              EXIT);
1308    parameters[numberParameters-1].setLonghelp
1309      (
1310       "This stops the execution of Clp, end, exit, quit and stop are synonyms"
1311       ); 
1312    parameters[numberParameters++]=
1313      ClpItem("tight!en","Poor person's preSolve for now",
1314              TIGHTEN,-1,false);
1315    parameters[numberParameters++]=
1316      ClpItem("unitTest","Do unit test",
1317              UNITTEST,-1,false);
1318    assert(numberParameters<MAXPARAMETERS);
1319   
1320    // total number of commands read
1321    int numberGoodCommands=0;
1322    bool * goodModels = new bool[1];
1323   
1324   
1325    int iModel=0;
1326    goodModels[0]=false;
1327    //models[0].scaling(1);
1328    //models[0].setDualBound(1.0e6);
1329    //models[0].setDualTolerance(1.0e-7);
1330    //ClpDualRowSteepest steep;
1331    //models[0].setDualRowPivotAlgorithm(steep);
1332    //models[0].setPrimalTolerance(1.0e-7);
1333    //ClpPrimalColumnSteepest steepP;
1334    //models[0].setPrimalColumnPivotAlgorithm(steepP);
1335    std::string field;
1336    std::cout<<"Coin LP version "<<CLPVERSION
1337             <<", build "<<__DATE__<<std::endl;
1338   
1339    while (1) {
1340      // next command
1341      field=getCommand(argc,argv);
1342     
1343      // exit if null or similar
1344      if (!field.length()) {
1345        if (numberGoodCommands==1&&goodModels[0]) {
1346          // we just had file name - do dual
1347          field="duals";
1348        } else if (!numberGoodCommands) {
1349          // let's give the sucker a hint
1350          std::cout
1351            <<"Clp takes input from arguments ( - switches to stdin)"
1352            <<std::endl
1353            <<"Enter ? for list of commands or help"<<std::endl;
1354          field="-";
1355        } else {
1356          break;
1357        }
1358      }
1359     
1360      // see if ? at end
1361      int numberQuery=0;
1362      if (field!="?") {
1363        int length = field.length();
1364        int i;
1365        for (i=length-1;i>0;i--) {
1366          if (field[i]=='?') 
1367            numberQuery++;
1368          else
1369            break;
1370        }
1371        field=field.substr(0,length-numberQuery);
1372      }
1373      // find out if valid command
1374      int iParam;
1375      int numberMatches=0;
1376      int firstMatch=-1;
1377      for ( iParam=0; iParam<numberParameters; iParam++ ) {
1378        int match = parameters[iParam].matches(field);
1379        if (match==1) {
1380          numberMatches = 1;
1381          firstMatch=iParam;
1382          break;
1383        } else {
1384          if (match&&firstMatch<0)
1385            firstMatch=iParam;
1386          numberMatches += match>>1;
1387        }
1388      }
1389      if (iParam<numberParameters&&!numberQuery) {
1390        // found
1391        ClpItem found = parameters[iParam];
1392        ClpParameterType type = found.type();
1393        int valid;
1394        numberGoodCommands++;
1395        if (type==GENERALQUERY) {
1396          std::cout<<"In argument list keywords have leading - "
1397            ", -stdin or just - switches to stdin"<<std::endl;
1398          std::cout<<"One command per line (and no -)"<<std::endl;
1399          std::cout<<"abcd? gives list of possibilities, if only one + explanation"<<std::endl;
1400          std::cout<<"abcd?? adds explanation, if only one fuller help"<<std::endl;
1401          std::cout<<"abcd without value (where expected) gives current value"<<std::endl;
1402          std::cout<<"abcd value sets value"<<std::endl;
1403          std::cout<<"Commands are:"<<std::endl;
1404          int maxAcross=5;
1405          int limits[]={1,101,201,301,401};
1406          std::vector<std::string> types;
1407          types.push_back("Double parameters:");
1408          types.push_back("Int parameters:");
1409          types.push_back("Keyword parameters and others:");
1410          types.push_back("Actions:");
1411          int iType;
1412          for (iType=0;iType<4;iType++) {
1413            int across=0;
1414            std::cout<<types[iType]<<std::endl;
1415            for ( iParam=0; iParam<numberParameters; iParam++ ) {
1416              int type = parameters[iParam].indexNumber();
1417              if (parameters[iParam].displayThis()&&type>=limits[iType]
1418                  &&type<limits[iType+1]) {
1419                if (!across)
1420                  std::cout<<"  ";
1421                std::cout<<parameters[iParam].matchName()<<"  ";
1422                across++;
1423                if (across==maxAcross) {
1424                  std::cout<<std::endl;
1425                  across=0;
1426                }
1427              }
1428            }
1429            if (across)
1430              std::cout<<std::endl;
1431          }
1432        } else if (type<101) {
1433          // get next field as double
1434          double value = getDoubleField(argc,argv,&valid);
1435          if (!valid) {
1436            parameters[iParam].setDoubleValue(value);
1437            parameters[iParam].setDoubleParameter(models+iModel,value);
1438          } else if (valid==1) {
1439            abort();
1440          } else {
1441            std::cout<<parameters[iParam].name()<<" has value "<<
1442              parameters[iParam].doubleValue()<<std::endl;
1443          }
1444        } else if (type<201) {
1445          // get next field as int
1446          int value = getIntField(argc,argv,&valid);
1447          if (!valid) {
1448            parameters[iParam].setIntValue(value);
1449            if (parameters[iParam].type()==PRESOLVEPASS)
1450              preSolve = value;
1451            else if (parameters[iParam].type()==IDIOT)
1452              doIdiot = value;
1453            else if (parameters[iParam].type()==SPRINT)
1454              doSprint = value;
1455            else
1456              parameters[iParam].setIntParameter(models+iModel,value);
1457          } else if (valid==1) {
1458            abort();
1459          } else {
1460            std::cout<<parameters[iParam].name()<<" has value "<<
1461              parameters[iParam].intValue()<<std::endl;
1462          }
1463        } else if (type<301) {
1464          // one of several strings
1465          std::string value = getString(argc,argv);
1466          int action = parameters[iParam].parameterOption(value);
1467          if (action<0) {
1468            if (value!="EOL") {
1469              // no match
1470              parameters[iParam].printOptions();
1471            } else {
1472              // print current value
1473              std::cout<<parameters[iParam].name()<<" has value "<<
1474                parameters[iParam].currentOption()<<std::endl;
1475            }
1476          } else {
1477            parameters[iParam].setCurrentOption(action);
1478            // for now hard wired
1479            switch (type) {
1480            case DIRECTION:
1481              if (action==0)
1482                models[iModel].setOptimizationDirection(1);
1483              else if (action==1)
1484                models[iModel].setOptimizationDirection(-1);
1485              else
1486                models[iModel].setOptimizationDirection(0);
1487              break;
1488            case DUALPIVOT:
1489              if (action==0) {
1490                ClpDualRowSteepest steep(3);
1491                models[iModel].setDualRowPivotAlgorithm(steep);
1492              } else if (action==1) {
1493                ClpDualRowDantzig dantzig;
1494                models[iModel].setDualRowPivotAlgorithm(dantzig);
1495              } else if (action==2) {
1496                // partial steep
1497                ClpDualRowSteepest steep(2);
1498                models[iModel].setDualRowPivotAlgorithm(steep);
1499              } else {
1500                ClpDualRowSteepest steep;
1501                models[iModel].setDualRowPivotAlgorithm(steep);
1502              }
1503              break;
1504            case PRIMALPIVOT:
1505              if (action==0) {
1506                ClpPrimalColumnSteepest steep(3);
1507                models[iModel].setPrimalColumnPivotAlgorithm(steep);
1508              } else if (action==1) {
1509                ClpPrimalColumnSteepest steep(0);
1510                models[iModel].setPrimalColumnPivotAlgorithm(steep);
1511              } else if (action==2) {
1512                ClpPrimalColumnDantzig dantzig;
1513                models[iModel].setPrimalColumnPivotAlgorithm(dantzig);
1514              } else if (action==3) {
1515                ClpPrimalColumnSteepest steep(2);
1516                models[iModel].setPrimalColumnPivotAlgorithm(steep);
1517              } else if (action==4) {
1518                ClpPrimalColumnSteepest steep(1);
1519                models[iModel].setPrimalColumnPivotAlgorithm(steep);
1520              } else if (action==5) {
1521                ClpPrimalColumnSteepest steep(4);
1522                models[iModel].setPrimalColumnPivotAlgorithm(steep);
1523              }
1524              break;
1525            case SCALING:
1526              if (action<2)
1527                models[iModel].scaling(1-action);
1528              else
1529                models[iModel].scaling(action);
1530              break;
1531            case SPARSEFACTOR:
1532              models[iModel].setSparseFactorization((1-action)!=0);
1533              break;
1534            case BIASLU:
1535              models[iModel].factorization()->setBiasLU(action);
1536              break;
1537            case PERTURBATION:
1538              if (action==0)
1539                models[iModel].setPerturbation(50);
1540              else
1541                models[iModel].setPerturbation(100);
1542              break;
1543            case ERRORSALLOWED:
1544              allowImportErrors = action;
1545              break;
1546            case KEEPNAMES:
1547              keepImportNames = 1-action;
1548              break;
1549            case PRESOLVE:
1550              if (action==0)
1551                preSolve = 5;
1552              else if (action==1)
1553                preSolve=0;
1554              else
1555                preSolve=10;
1556              break;
1557            case CRASH:
1558              doCrash=action;
1559              break;
1560            case MESSAGES:
1561              models[iModel].messageHandler()->setPrefix(action!=0);
1562              break;
1563            default:
1564              abort();
1565            }
1566          }
1567        } else {
1568          // action
1569          if (type==EXIT)
1570            break; // stop all
1571          switch (type) {
1572          case DUALSIMPLEX:
1573          case PRIMALSIMPLEX:
1574            if (goodModels[iModel]) {
1575              ClpSolve::SolveType method;
1576              ClpSolve::PresolveType presolveType;
1577              ClpSimplex * model2 = models+iModel;
1578              ClpSolve solveOptions;
1579              if (preSolve!=5&&preSolve)
1580                presolveType=ClpSolve::presolveNumber;
1581              else if (preSolve)
1582                presolveType=ClpSolve::presolveOn;
1583              else
1584                presolveType=ClpSolve::presolveOff;
1585              solveOptions.setPresolveType(presolveType,preSolve);
1586              if (type==DUALSIMPLEX)
1587                method=ClpSolve::useDual;
1588              else
1589                method=ClpSolve::usePrimalorSprint;
1590              solveOptions.setSolveType(method);
1591              if (method==ClpSolve::useDual) {
1592                // dual
1593                if (doCrash)
1594                  solveOptions.setSpecialOption(0,1); // crash
1595              } else {
1596                // primal
1597                if (doCrash) {
1598                  solveOptions.setSpecialOption(1,1); // crash
1599                } else if (doSprint>0) {
1600                  // sprint overrides idiot
1601                  solveOptions.setSpecialOption(1,3,doSprint); // sprint
1602                } else if (doIdiot>0) {
1603                  solveOptions.setSpecialOption(1,2,doIdiot); // idiot
1604                } else {
1605                  if (doIdiot==0) {
1606                    if (doSprint==0)
1607                      solveOptions.setSpecialOption(1,4); // all slack
1608                    else
1609                      solveOptions.setSpecialOption(1,9); // all slack or sprint
1610                  } else {
1611                    if (doSprint==0)
1612                      solveOptions.setSpecialOption(1,8); // all slack or idiot
1613                    else
1614                      solveOptions.setSpecialOption(1,7); // initiative
1615                  }
1616                }
1617              }
1618              model2->initialSolve(solveOptions);
1619            } else {
1620              std::cout<<"** Current model not valid"<<std::endl;
1621            }
1622            break;
1623          case TIGHTEN:
1624            if (goodModels[iModel]) {
1625              int numberInfeasibilities = models[iModel].tightenPrimalBounds();
1626              if (numberInfeasibilities)
1627                std::cout<<"** Analysis indicates model infeasible"<<std::endl;
1628            } else {
1629              std::cout<<"** Current model not valid"<<std::endl;
1630            }
1631            break;
1632          case PLUSMINUS:
1633            if (goodModels[iModel]) {
1634              ClpMatrixBase * saveMatrix = models[iModel].clpMatrix();
1635              ClpPackedMatrix* clpMatrix =
1636                dynamic_cast< ClpPackedMatrix*>(saveMatrix);
1637              if (clpMatrix) {
1638                ClpPlusMinusOneMatrix * newMatrix = new ClpPlusMinusOneMatrix(*(clpMatrix->matrix()));
1639                if (newMatrix->getIndices()) {
1640                  models[iModel].replaceMatrix(newMatrix);
1641                  delete saveMatrix;
1642                  std::cout<<"Matrix converted to +- one matrix"<<std::endl;
1643                } else {
1644                  std::cout<<"Matrix can not be converted to +- 1 matrix"<<std::endl;
1645                }
1646              } else {
1647                std::cout<<"Matrix not a ClpPackedMatrix"<<std::endl;
1648              }
1649            } else {
1650              std::cout<<"** Current model not valid"<<std::endl;
1651            }
1652            break;
1653          case NETWORK:
1654            if (goodModels[iModel]) {
1655              ClpMatrixBase * saveMatrix = models[iModel].clpMatrix();
1656              ClpPackedMatrix* clpMatrix =
1657                dynamic_cast< ClpPackedMatrix*>(saveMatrix);
1658              if (clpMatrix) {
1659                ClpNetworkMatrix * newMatrix = new ClpNetworkMatrix(*(clpMatrix->matrix()));
1660                if (newMatrix->getIndices()) {
1661                  models[iModel].replaceMatrix(newMatrix);
1662                  delete saveMatrix;
1663                  std::cout<<"Matrix converted to network matrix"<<std::endl;
1664                } else {
1665                  std::cout<<"Matrix can not be converted to network matrix"<<std::endl;
1666                }
1667              } else {
1668                std::cout<<"Matrix not a ClpPackedMatrix"<<std::endl;
1669              }
1670            } else {
1671              std::cout<<"** Current model not valid"<<std::endl;
1672            }
1673            break;
1674          case IMPORT:
1675            {
1676              // get next field
1677              field = getString(argc,argv);
1678              if (field=="$") {
1679                field = parameters[iParam].stringValue();
1680              } else if (field=="EOL") {
1681                parameters[iParam].printString();
1682                break;
1683              } else {
1684                parameters[iParam].setStringValue(field);
1685              }
1686              std::string fileName;
1687              bool canOpen=false;
1688              if (field=="-") {
1689                // stdin
1690                canOpen=true;
1691                fileName = "-";
1692              } else {
1693                if (field[0]=='/'||field[0]=='~')
1694                  fileName = field;
1695                else
1696                  fileName = directory+field;
1697                FILE *fp=fopen(fileName.c_str(),"r");
1698                if (fp) {
1699                  // can open - lets go for it
1700                  fclose(fp);
1701                  canOpen=true;
1702                } else {
1703                  std::cout<<"Unable to open file "<<fileName<<std::endl;
1704                }
1705              }
1706              if (canOpen) {
1707                int status =models[iModel].readMps(fileName.c_str(),
1708                                                   keepImportNames!=0,
1709                                                   allowImportErrors!=0);
1710                if (!status||(status>0&&allowImportErrors)) {
1711                  goodModels[iModel]=true;
1712                  // sets to all slack (not necessary?)
1713                  models[iModel].createStatus();
1714                  time2 = CoinCpuTime();
1715                  totalTime += time2-time1;
1716                  time1=time2;
1717                } else {
1718                  // errors
1719                  std::cout<<"There were "<<status<<
1720                    " errors on input"<<std::endl;
1721                }
1722              }
1723            }
1724            break;
1725          case EXPORT:
1726            {
1727              // get next field
1728              field = getString(argc,argv);
1729              if (field=="$") {
1730                field = parameters[iParam].stringValue();
1731              } else if (field=="EOL") {
1732                parameters[iParam].printString();
1733                break;
1734              } else {
1735                parameters[iParam].setStringValue(field);
1736              }
1737              std::string fileName;
1738              bool canOpen=false;
1739              if (field[0]=='/'||field[0]=='~')
1740                fileName = field;
1741              else
1742                fileName = directory+field;
1743              FILE *fp=fopen(fileName.c_str(),"w");
1744              if (fp) {
1745                // can open - lets go for it
1746                fclose(fp);
1747                canOpen=true;
1748              } else {
1749                std::cout<<"Unable to open file "<<fileName<<std::endl;
1750              }
1751              if (canOpen) {
1752                // If presolve on then save presolved
1753                bool deleteModel2=false;
1754                ClpSimplex * model2 = models+iModel;
1755#ifdef USE_PRESOLVE
1756                if (preSolve) {
1757                  ClpPresolve pinfo;
1758                  model2 = 
1759                    pinfo.presolvedModel(models[iModel],1.0e-8,
1760                                         false,preSolve);
1761                  if (model2) {
1762                    printf("Saving presolved model on %s\n",
1763                           fileName.c_str());
1764                    deleteModel2=true;
1765                  } else {
1766                    printf("Presolved model looks infeasible - saving original on %s\n",
1767                           fileName.c_str());
1768                    deleteModel2=false;
1769                    model2 = models+iModel;
1770
1771                  }
1772                } else {
1773#endif
1774                  printf("Saving model on %s\n",
1775                           fileName.c_str());
1776#ifdef USE_PRESOLVE
1777                }
1778#endif
1779                // Convert names
1780                int iRow;
1781                int numberRows=model2->numberRows();
1782                int iColumn;
1783                int numberColumns=model2->numberColumns();
1784
1785                char ** rowNames = NULL;
1786                char ** columnNames = NULL;
1787                if (model2->lengthNames()) {
1788                  rowNames = new char * [numberRows];
1789                  for (iRow=0;iRow<numberRows;iRow++) {
1790                    rowNames[iRow] = 
1791                      strdup(model2->rowName(iRow).c_str());
1792#ifdef STRIPBLANKS
1793                    char * xx = rowNames[iRow];
1794                    int i;
1795                    int length = strlen(xx);
1796                    int n=0;
1797                    for (i=0;i<length;i++) {
1798                      if (xx[i]!=' ')
1799                        xx[n++]=xx[i];
1800                    }
1801                    xx[n]='\0';
1802#endif
1803                  }
1804                 
1805                  columnNames = new char * [numberColumns];
1806                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
1807                    columnNames[iColumn] = 
1808                      strdup(model2->columnName(iColumn).c_str());
1809#ifdef STRIPBLANKS
1810                    char * xx = columnNames[iColumn];
1811                    int i;
1812                    int length = strlen(xx);
1813                    int n=0;
1814                    for (i=0;i<length;i++) {
1815                      if (xx[i]!=' ')
1816                        xx[n++]=xx[i];
1817                    }
1818                    xx[n]='\0';
1819#endif
1820                  }
1821                }
1822
1823                CoinMpsIO writer;
1824                writer.setMpsData(*model2->matrix(), COIN_DBL_MAX,
1825                                  model2->getColLower(), model2->getColUpper(),
1826                                  model2->getObjCoefficients(),
1827                                  (const char*) 0 /*integrality*/,
1828                                  model2->getRowLower(), model2->getRowUpper(),
1829                                  columnNames, rowNames);
1830                // Pass in array saying if each variable integer
1831                writer.copyInIntegerInformation(model2->integerInformation());
1832                writer.writeMps(fileName.c_str(),0,0,1);
1833                if (rowNames) {
1834                  for (iRow=0;iRow<numberRows;iRow++) {
1835                    free(rowNames[iRow]);
1836                  }
1837                  delete [] rowNames;
1838                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
1839                    free(columnNames[iColumn]);
1840                  }
1841                  delete [] columnNames;
1842                }
1843                if (deleteModel2)
1844                  delete model2;
1845                time2 = CoinCpuTime();
1846                totalTime += time2-time1;
1847                time1=time2;
1848              }
1849            }
1850            break;
1851          case SAVE:
1852            {
1853              // get next field
1854              field = getString(argc,argv);
1855              if (field=="$") {
1856                field = parameters[iParam].stringValue();
1857              } else if (field=="EOL") {
1858                parameters[iParam].printString();
1859                break;
1860              } else {
1861                parameters[iParam].setStringValue(field);
1862              }
1863              std::string fileName;
1864              bool canOpen=false;
1865              if (field[0]=='/'||field[0]=='~')
1866                fileName = field;
1867              else
1868                fileName = directory+field;
1869              FILE *fp=fopen(fileName.c_str(),"wb");
1870              if (fp) {
1871                // can open - lets go for it
1872                fclose(fp);
1873                canOpen=true;
1874              } else {
1875                std::cout<<"Unable to open file "<<fileName<<std::endl;
1876              }
1877              if (canOpen) {
1878                int status;
1879                // If presolve on then save presolved
1880                bool deleteModel2=false;
1881                ClpSimplex * model2 = models+iModel;
1882#ifdef USE_PRESOLVE
1883                if (preSolve) {
1884                  ClpPresolve pinfo;
1885                  model2 = 
1886                    pinfo.presolvedModel(models[iModel],1.0e-8,
1887                                         false,preSolve);
1888                  if (model2) {
1889                    printf("Saving presolved model on %s\n",
1890                           fileName.c_str());
1891                    deleteModel2=true;
1892                  } else {
1893                    printf("Presolved model looks infeasible - saving original on %s\n",
1894                           fileName.c_str());
1895                    deleteModel2=false;
1896                    model2 = models+iModel;
1897
1898                  }
1899                } else {
1900#endif
1901                  printf("Saving model on %s\n",
1902                           fileName.c_str());
1903#ifdef USE_PRESOLVE
1904                }
1905#endif
1906                status =model2->saveModel(fileName.c_str());
1907                if (deleteModel2)
1908                  delete model2;
1909                if (!status) {
1910                  goodModels[iModel]=true;
1911                  time2 = CoinCpuTime();
1912                  totalTime += time2-time1;
1913                  time1=time2;
1914                } else {
1915                  // errors
1916                  std::cout<<"There were errors on output"<<std::endl;
1917                }
1918              }
1919            }
1920            break;
1921          case RESTORE:
1922            {
1923              // get next field
1924              field = getString(argc,argv);
1925              if (field=="$") {
1926                field = parameters[iParam].stringValue();
1927              } else if (field=="EOL") {
1928                parameters[iParam].printString();
1929                break;
1930              } else {
1931                parameters[iParam].setStringValue(field);
1932              }
1933              std::string fileName;
1934              bool canOpen=false;
1935              if (field[0]=='/'||field[0]=='~')
1936                fileName = field;
1937              else
1938                fileName = directory+field;
1939              FILE *fp=fopen(fileName.c_str(),"rb");
1940              if (fp) {
1941                // can open - lets go for it
1942                fclose(fp);
1943                canOpen=true;
1944              } else {
1945                std::cout<<"Unable to open file "<<fileName<<std::endl;
1946              }
1947              if (canOpen) {
1948                int status =models[iModel].restoreModel(fileName.c_str());
1949                if (!status) {
1950                  goodModels[iModel]=true;
1951                  time2 = CoinCpuTime();
1952                  totalTime += time2-time1;
1953                  time1=time2;
1954                } else {
1955                  // errors
1956                  std::cout<<"There were errors on input"<<std::endl;
1957                }
1958              }
1959            }
1960            break;
1961          case MAXIMIZE:
1962            models[iModel].setOptimizationDirection(-1);
1963            break;
1964          case MINIMIZE:
1965            models[iModel].setOptimizationDirection(1);
1966            break;
1967          case ALLSLACK:
1968            models[iModel].createStatus();
1969            {
1970              // and do solution
1971              int iColumn;
1972              double * solution = models[iModel].primalColumnSolution();
1973              const double * lower = models[iModel].columnLower();
1974              const double * upper = models[iModel].columnUpper();
1975              int numberColumns = models[iModel].numberColumns();
1976              for (iColumn=0;iColumn<numberColumns;iColumn++) {
1977                if (lower[iColumn]>0.0) {
1978                  solution[iColumn]=lower[iColumn];
1979                } else if (upper[iColumn]<0.0) {
1980                  solution[iColumn]=upper[iColumn];
1981                } else {
1982                  solution[iColumn]=0.0;
1983                }
1984              }
1985            }
1986            break;
1987          case REVERSE:
1988            if (goodModels[iModel]) {
1989              int iColumn;
1990              int numberColumns=models[iModel].numberColumns();
1991              double * dualColumnSolution = 
1992                models[iModel].dualColumnSolution();
1993              ClpObjective * obj = models[iModel].objectiveAsObject();
1994              assert(dynamic_cast<ClpLinearObjective *> (obj));
1995              double offset;
1996              double * objective = obj->gradient(NULL,offset,true);
1997              for (iColumn=0;iColumn<numberColumns;iColumn++) {
1998                dualColumnSolution[iColumn] = dualColumnSolution[iColumn];
1999                objective[iColumn] = -objective[iColumn];
2000              }
2001              int iRow;
2002              int numberRows=models[iModel].numberRows();
2003              double * dualRowSolution = 
2004                models[iModel].dualRowSolution();
2005              for (iRow=0;iRow<numberRows;iRow++) 
2006                dualRowSolution[iRow] = dualRowSolution[iRow];
2007            }
2008            break;
2009          case DIRECTORY:
2010            {
2011              std::string name = getString(argc,argv);
2012              if (name!="EOL") {
2013                int length=name.length();
2014                if (name[length-1]=='/')
2015                  directory=name;
2016                else
2017                  directory = name+"/";
2018                parameters[iParam].setStringValue(directory);
2019              } else {
2020                parameters[iParam].printString();
2021              }
2022            }
2023            break;
2024          case STDIN:
2025            read_mode=-1;
2026            break;
2027          case NETLIB_DUAL:
2028          case NETLIB_PRIMAL:
2029            {
2030              // create fields for unitTest
2031              const char * fields[4];
2032              int nFields=2;
2033              fields[0]="fake main from unitTest";
2034              fields[1]="-netlib";
2035              if (directory!="./") {
2036                fields[2]="-netlibDir";
2037                fields[3]=directory.c_str();
2038                nFields=4;
2039              }
2040              if (type==NETLIB_DUAL)
2041                std::cerr<<"Doing netlib with dual agorithm"<<std::endl;
2042              else
2043                std::cerr<<"Doing netlib with primal agorithm"<<std::endl;
2044              mainTest(nFields,fields,(type==NETLIB_DUAL),models[iModel],
2045                       (preSolve!=0),doIdiot);
2046            }
2047            break;
2048          case UNITTEST:
2049            {
2050              // create fields for unitTest
2051              const char * fields[3];
2052              int nFields=1;
2053              fields[0]="fake main from unitTest";
2054              if (directory!="./") {
2055                fields[1]="-mpsDir";
2056                fields[2]=directory.c_str();
2057                nFields=3;
2058              }
2059              mainTest(nFields,fields,false,models[iModel],(preSolve!=0),
2060                       false);
2061            }
2062            break;
2063          case FAKEBOUND:
2064            if (goodModels[iModel]) {
2065              // get bound
2066              double value = getDoubleField(argc,argv,&valid);
2067              if (!valid) {
2068                std::cout<<"Setting "<<parameters[iParam].name()<<
2069                  " to DEBUG "<<value<<std::endl;
2070                int iRow;
2071                int numberRows=models[iModel].numberRows();
2072                double * rowLower = models[iModel].rowLower();
2073                double * rowUpper = models[iModel].rowUpper();
2074                for (iRow=0;iRow<numberRows;iRow++) {
2075                  // leave free ones for now
2076                  if (rowLower[iRow]>-1.0e20||rowUpper[iRow]<1.0e20) {
2077                    rowLower[iRow]=max(rowLower[iRow],-value);
2078                    rowUpper[iRow]=min(rowUpper[iRow],value);
2079                  }
2080                }
2081                int iColumn;
2082                int numberColumns=models[iModel].numberColumns();
2083                double * columnLower = models[iModel].columnLower();
2084                double * columnUpper = models[iModel].columnUpper();
2085                for (iColumn=0;iColumn<numberColumns;iColumn++) {
2086                  // leave free ones for now
2087                  if (columnLower[iColumn]>-1.0e20||
2088                      columnUpper[iColumn]<1.0e20) {
2089                    columnLower[iColumn]=max(columnLower[iColumn],-value);
2090                    columnUpper[iColumn]=min(columnUpper[iColumn],value);
2091                  }
2092                }
2093              } else if (valid==1) {
2094                abort();
2095              } else {
2096                std::cout<<"enter value for "<<parameters[iParam].name()<<
2097                  std::endl;
2098              }
2099            }
2100            break;
2101          case HELP:
2102            std::cout<<"Coin LP version "<<CLPVERSION
2103                     <<", build "<<__DATE__<<std::endl;
2104            std::cout<<"Non default values:-"<<std::endl;
2105            std::cout<<"Perturbation "<<models[0].perturbation()<<" (default 100)"
2106                     <<std::endl;
2107            printit(
2108                    "Presolve being done with 5 passes\n\
2109Dual steepest edge steep/partial on matrix shape and factorization density\n\
2110Clpnnnn taken out of messages\n\
2111If Factorization frequency default then done on size of matrix\n\n\
2112(-)unitTest, (-)netlib or (-)netlibp will do standard tests\n\n\
2113You can switch to interactive mode at any time so\n\
2114clp watson.mps -scaling off -primalsimplex\nis the same as\n\
2115clp watson.mps -\nscaling off\nprimalsimplex"
2116                    );
2117            break;
2118          case SOLUTION:
2119            if (goodModels[iModel]) {
2120              // get next field
2121              field = getString(argc,argv);
2122              if (field=="$") {
2123                field = parameters[iParam].stringValue();
2124              } else if (field=="EOL") {
2125                parameters[iParam].printString();
2126                break;
2127              } else {
2128                parameters[iParam].setStringValue(field);
2129              }
2130              std::string fileName;
2131              FILE *fp=NULL;
2132              if (field=="-"||field=="EOL"||field=="stdout") {
2133                // stdout
2134                fp=stdout;
2135              } else if (field=="stderr") {
2136                // stderr
2137                fp=stderr;
2138              } else {
2139                if (field[0]=='/'||field[0]=='~')
2140                  fileName = field;
2141                else
2142                  fileName = directory+field;
2143                fp=fopen(fileName.c_str(),"w");
2144              }
2145              if (fp) {
2146                // make fancy later on
2147                int iRow;
2148                int numberRows=models[iModel].numberRows();
2149                int lengthName = models[iModel].lengthNames(); // 0 if no names
2150                // in general I don't want to pass around massive
2151                // amounts of data but seems simpler here
2152                std::vector<std::string> rowNames =
2153                  *(models[iModel].rowNames());
2154                std::vector<std::string> columnNames =
2155                  *(models[iModel].columnNames());
2156
2157                double * dualRowSolution = models[iModel].dualRowSolution();
2158                double * primalRowSolution = 
2159                  models[iModel].primalRowSolution();
2160                double * rowLower = models[iModel].rowLower();
2161                double * rowUpper = models[iModel].rowUpper();
2162                double primalTolerance = models[iModel].primalTolerance();
2163                char format[6];
2164                sprintf(format,"%%-%ds",max(lengthName,8));
2165                for (iRow=0;iRow<numberRows;iRow++) {
2166                  if (primalRowSolution[iRow]>rowUpper[iRow]+primalTolerance||
2167                      primalRowSolution[iRow]<rowLower[iRow]-primalTolerance)
2168                    fprintf(fp,"** ");
2169                  fprintf(fp,"%7d ",iRow);
2170                  if (lengthName)
2171                    fprintf(fp,format,rowNames[iRow].c_str());
2172                  fprintf(fp,"%15.8g        %15.8g\n",primalRowSolution[iRow],
2173                          dualRowSolution[iRow]);
2174                }
2175                int iColumn;
2176                int numberColumns=models[iModel].numberColumns();
2177                double * dualColumnSolution = 
2178                  models[iModel].dualColumnSolution();
2179                double * primalColumnSolution = 
2180                  models[iModel].primalColumnSolution();
2181                double * columnLower = models[iModel].columnLower();
2182                double * columnUpper = models[iModel].columnUpper();
2183                for (iColumn=0;iColumn<numberColumns;iColumn++) {
2184                  if (primalColumnSolution[iColumn]>columnUpper[iColumn]+primalTolerance||
2185                      primalColumnSolution[iColumn]<columnLower[iColumn]-primalTolerance)
2186                    fprintf(fp,"** ");
2187                  fprintf(fp,"%7d ",iColumn);
2188                  if (lengthName)
2189                    fprintf(fp,format,columnNames[iColumn].c_str());
2190                  fprintf(fp,"%15.8g        %15.8g\n",
2191                          primalColumnSolution[iColumn],
2192                          dualColumnSolution[iColumn]);
2193                }
2194                if (fp!=stdout)
2195                  fclose(fp);
2196              } else {
2197                std::cout<<"Unable to open file "<<fileName<<std::endl;
2198              }
2199            } else {
2200              std::cout<<"** Current model not valid"<<std::endl;
2201             
2202            }
2203            break;
2204          default:
2205            abort();
2206          }
2207        } 
2208      } else if (!numberMatches) {
2209        std::cout<<"No match for "<<field<<" - ? for list of commands"
2210                 <<std::endl;
2211      } else if (numberMatches==1) {
2212        if (!numberQuery) {
2213          std::cout<<"Short match for "<<field<<" - completion: ";
2214          std::cout<<parameters[firstMatch].matchName()<<std::endl;
2215        } else if (numberQuery) {
2216          std::cout<<parameters[firstMatch].matchName()<<" : ";
2217          std::cout<<parameters[firstMatch].shortHelp()<<std::endl;
2218          if (numberQuery>=2) 
2219            parameters[firstMatch].printLongHelp();
2220        }
2221      } else {
2222        if (!numberQuery) 
2223          std::cout<<"Multiple matches for "<<field<<" - possible completions:"
2224                   <<std::endl;
2225        else
2226          std::cout<<"Completions of "<<field<<":"<<std::endl;
2227        for ( iParam=0; iParam<numberParameters; iParam++ ) {
2228          int match = parameters[iParam].matches(field);
2229          if (match&&parameters[iParam].displayThis()) {
2230            std::cout<<parameters[iParam].matchName();
2231            if (numberQuery>=2) 
2232              std::cout<<" : "<<parameters[iParam].shortHelp();
2233            std::cout<<std::endl;
2234          }
2235        }
2236      }
2237    }
2238    delete [] models;
2239    delete [] goodModels;
2240  }
2241  // By now all memory should be freed
2242#ifdef DMALLOC
2243  dmalloc_log_unfreed();
2244  dmalloc_shutdown();
2245#endif
2246  return 0;
2247}   
Note: See TracBrowser for help on using the repository browser.