00001
00002
00003
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 * , FORMULATION * )
00035 {
00036 char filename[256];
00037 int goodUsage = 1;
00038 int iargv = 1;
00039
00040 while( iargv < argc ) {
00041 if( argv[iargv][0] != '-' ) break;
00042 int iopt = 1;
00043 if( argv[iargv][1] == '-' ) iopt = 2;
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
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
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
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