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