Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

QpGenDriver.h

00001 /* OOQP                                                               *
00002  * Authors: E. Michael Gertz, Stephen J. Wright                       *
00003  * (C) 2001 University of Chicago. See Copyright Notification in OOQP */
00004 
00005 #ifndef QPGENDRIVER
00006 #define QPGENDRIVER
00007 
00008 #include <memory>
00009 #include <cstring>
00010 #include <iostream>
00011 #include <fstream>
00012 using namespace std;
00013 #include <cstdlib>
00014 
00015 #ifdef HAVE_GETRUSAGE
00016 #include <sys/time.h>
00017 #include <sys/resource.h>
00018 #include <unistd.h>
00019 #endif
00020 
00021 #include "QpGenVars.h"
00022 #include "QpGenResiduals.h"
00023 #include "MpsReader.h"
00024 #include "SimpleVector.h"
00025 #include "Status.h"
00026 #include "QpGenData.h"
00027 #include "OoqpVersion.h"
00028 
00029 extern int gOoqpPrintLevel;
00030 int scale = 0;
00031 
00032 template<class SOLVER, class FORMULATION>
00033 int qpgen_solve( int argc, char * argv[],
00034                  SOLVER * /* dum1 */, FORMULATION * /* dum2 */ )
00035 {
00036   char filename[256];
00037   int goodUsage = 1; // Assume good. Why not be optimistic
00038   int iargv    = 1;
00039 
00040   while( iargv < argc ) {
00041     if( argv[iargv][0] != '-' ) break; // done with the options
00042     int iopt = 1; // Assume argv[iargv][1] is the start of the option name
00043     if( argv[iargv][1] == '-' ) iopt = 2; // it is a --arg
00044     if( 0 == strcmp( "print-level", &argv[iargv][iopt] ) ) {
00045       if( ++iargv >= argc ) break;
00046       char * endptr;
00047       gOoqpPrintLevel = strtol( argv[iargv], &endptr, 10 );
00048       if( '\0' != *endptr ) { 
00049         goodUsage = 0;
00050         break;
00051       }
00052     } else if( 0 == strcmp( "quiet", &argv[iargv][iopt] ) ) {
00053       gOoqpPrintLevel = 0;
00054     } else if( 0 == strcmp( "verbose", &argv[iargv][iopt] ) ) {
00055       gOoqpPrintLevel = 1000;
00056     } else if( 0 == strcmp( "version", &argv[iargv][iopt] ) ) {
00057       printOoqpVersionString();
00058       exit(0);
00059     } else if( 0 == strcmp( "scale", &argv[iargv][iopt] ) ) {
00060       scale = 1;
00061     } else {
00062       // Unknown option, bug out of the option parsing loop
00063       goodUsage = 0;
00064       break;
00065     }
00066     iargv++;
00067   }
00068   if( iargv == argc - 1 && goodUsage ) {
00069     strncpy( filename, argv[iargv], 255 );
00070     filename[255] = '\0';
00071   } else {
00072     cerr << "Usage: " << argv[0] << " [ --version ] [ --print-level num ] "
00073       "[ --quiet ] [ --verbose ] [--scale] problem.qps\n";
00074     return 1;
00075   }
00076 
00077   try {
00078     int iErr;
00079 #ifdef HAVE_GETRUSAGE
00080     rusage before_read;
00081     getrusage( RUSAGE_SELF, &before_read );
00082 #endif
00083     MpsReader * reader  = MpsReader::newReadingFile( filename, iErr );
00084     if( !reader ) {
00085       cerr << "Couldn't read file " << filename << endl 
00086            << "For what it is worth, the error number is " << iErr << endl;
00087       return 1;
00088     }
00089     
00090     int n1, m1, m2, nnzQ, nnzA, nnzC;
00091     reader->getSizes( n1, m1, m2 );
00092     reader->numberOfNonZeros( nnzQ, nnzA, nnzC );
00093     
00094     FORMULATION * qp 
00095       = new FORMULATION( n1, m1, m2, nnzQ, nnzA, nnzC );
00096     QpGenData * prob = (QpGenData * ) qp->makeData();
00097  
00098     /* Set the scaling option */
00099     if( scale == 1)
00100         reader->scalingOption = 1;
00101     else
00102         reader->scalingOption = 0;
00103 
00104     prob->datainput( reader, iErr );
00105     if( 0 != iErr ) {
00106       cerr << "Couldn't read file " << filename << endl
00107            << "For what it is worth, the error number is " << iErr << endl;
00108       return 1;
00109     }
00110     reader->releaseFile( iErr );
00111 #ifdef HAVE_GETRUSAGE
00112     rusage  after_read;
00113     getrusage( RUSAGE_SELF, &after_read );
00114 #endif
00115 
00116     if( 0 != iErr ) {
00117       cerr << "Couldn't close file " << filename << endl 
00118            << "For what it is worth, the error number is " << iErr << endl;
00119       return 1;
00120     }
00121     
00122     QpGenVars     * vars  = (QpGenVars * ) qp->makeVariables( prob );
00123     Residuals     * resid = qp->makeResiduals( prob );
00124     SOLVER * s            = new SOLVER( qp, prob );
00125     
00126     s->monitorSelf();
00127 #ifdef HAVE_GETRUSAGE
00128     rusage before_solve;
00129     getrusage( RUSAGE_SELF, &before_solve );
00130 #endif
00131     int result = s->solve(prob,vars, resid);
00132     if( 0 == result ) {
00133       if( gOoqpPrintLevel > 0 ) {
00134 #ifdef HAVE_GETRUSAGE
00135         rusage  after_solve;
00136         getrusage( RUSAGE_SELF, &after_solve );
00137         double read_time =
00138           (after_read.ru_utime.tv_sec - before_read.ru_utime.tv_sec)
00139           + (after_read.ru_utime.tv_usec - before_read.ru_utime.tv_usec)
00140           / 1000000.0;
00141         double solve_time =
00142           (after_solve.ru_utime.tv_sec - before_solve.ru_utime.tv_sec)
00143           + (after_solve.ru_utime.tv_usec - before_solve.ru_utime.tv_usec)
00144           / 1000000.0;
00145 
00146         cout << " QP read in " << read_time << " seconds.  "
00147              << "QP solved in " << solve_time << " seconds.\n";
00148 #endif
00149       //  vars->print();
00150       
00151       double objective = reader->objconst() + prob->objectiveValue(vars);
00152       
00153       cout << " " << n1 << " variables, " 
00154            << m1  << " equality constraints, " 
00155            << m2  << " inequality constraints.\n";
00156       
00157       cout << " Iterates: " << s->iter
00158            <<",    Optimal Solution:  " << objective << endl;
00159       }
00160       vars->printSolution(reader, prob, iErr);
00161     } else {
00162       if ( gOoqpPrintLevel > 0 ) {
00163         cout << "Could not solve this QP.\n";
00164         cout << "Terminated with code " << result;
00165         if( result > 0 && result <= UNKNOWN ) {
00166           cout << " : " << TerminationStrings[result];
00167         }
00168         cout << ".\n";
00169       }
00170     }
00171     
00172     delete s;
00173     delete vars;  
00174     delete resid;
00175     delete prob;
00176     delete qp;
00177     delete reader;
00178 
00179     return result;
00180   } 
00181   catch( ... ) {
00182     cerr << "\nOops, out of memory\n";
00183     return -1;
00184   }
00185 }
00186 
00187 #endif

Generated on Wed Mar 22 13:58:33 2006 for OOQP by doxygen 1.3.5