00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00038 #include <qpOASES/QProblem.hpp>
00039
00040
00041 using namespace qpOASES;
00042
00043 #include <qpOASES_matlab_utils.cpp>
00044
00045
00046
00047 static QProblem* globalQP = 0;
00048 static SymmetricMatrix* globalQP_H = 0;
00049 static Matrix* globalQP_A = 0;
00050 static long* globalQP_Hdiag = 0;
00051
00052
00053
00054
00055
00056 void allocateGlobalQProblemInstance( int nV, int nC, Options* options
00057 )
00058 {
00059 globalQP = new QProblem( nV,nC );
00060 globalQP->setOptions( *options );
00061
00062 return;
00063 }
00064
00065
00066
00067
00068
00069 void deleteGlobalQProblemInstance( )
00070 {
00071 if ( globalQP != 0 )
00072 {
00073 delete globalQP;
00074 globalQP = 0;
00075 }
00076
00077 return;
00078 }
00079
00080
00081
00082
00083
00084 void deleteGlobalQProblemMatrices( )
00085 {
00086 if ( globalQP_H != 0 )
00087 {
00088 delete globalQP_H;
00089 globalQP_H = 0;
00090 }
00091
00092 if ( globalQP_A != 0 )
00093 {
00094 delete globalQP_A;
00095 globalQP_A = 0;
00096 }
00097
00098 if ( globalQP_Hdiag != 0 )
00099 {
00100 delete[] globalQP_Hdiag;
00101 globalQP_Hdiag = 0;
00102 }
00103
00104 return;
00105 }
00106
00107
00108
00109
00110
00111 void init( int nV, int nC,
00112 SymmetricMatrix *H, real_t* g, Matrix *A,
00113 const real_t* const lb, const real_t* const ub, const real_t* const lbA, const real_t* const ubA,
00114 int nWSR, const real_t* const x0, Options* options,
00115 int nOutputs, mxArray* plhs[]
00116 )
00117 {
00118
00119 allocateGlobalQProblemInstance( nV,nC,options );
00120
00121
00122 returnValue returnvalue;
00123
00124 if ( x0 == 0 )
00125 returnvalue = globalQP->init( H,g,A,lb,ub,lbA,ubA, nWSR,0 );
00126 else
00127 returnvalue = globalQP->init( H,g,A,lb,ub,lbA,ubA, nWSR,0, x0,0,0,0 );
00128
00129
00130 obtainOutputs( 0,globalQP,returnvalue,nWSR,
00131 nOutputs,plhs,0,0 );
00132
00133 return;
00134 }
00135
00136
00137
00138
00139
00140 void hotstart( const real_t* const g,
00141 const real_t* const lb, const real_t* const ub,
00142 const real_t* const lbA, const real_t* const ubA,
00143 int nWSR, Options* options,
00144 int nOutputs, mxArray* plhs[]
00145 )
00146 {
00147
00148 globalQP->setOptions( *options );
00149 returnValue returnvalue = globalQP->hotstart( g,lb,ub,lbA,ubA, nWSR,0 );
00150
00151
00152 obtainOutputs( 0,globalQP,returnvalue,nWSR,
00153 nOutputs,plhs,0,0 );
00154
00155 return;
00156 }
00157
00158
00159
00160
00161
00162 void mexFunction( int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[] )
00163 {
00164 unsigned int i,j;
00165
00166
00167 char* typeString;
00168 real_t *H_for=0, *H_mem=0, *g=0, *A_for=0, *A_mem=0, *lb=0, *ub=0, *lbA=0, *ubA=0, *x0=0;
00169
00170 Options options;
00171 options.printLevel = PL_LOW;
00172 #ifdef __DEBUG__
00173 options.printLevel = PL_HIGH;
00174 #endif
00175 #ifdef __SUPPRESSANYOUTPUT__
00176 options.printLevel = PL_NONE;
00177 #endif
00178
00179
00180 unsigned int nV=0, nC=0;
00181
00182
00183
00184
00185 if ( ( nrhs < 6 ) || ( nrhs > 10 ) )
00186 if ( nrhs != 1 )
00187 mexErrMsgTxt( "ERROR (qpOASES): Invalid number of input arguments!\nType 'help qpOASES_sequence' for further information." );
00188
00189
00190 if ( mxIsChar( prhs[0] ) != 1 )
00191 mexErrMsgTxt( "ERROR (qpOASES): First input argument must be a string!" );
00192
00193 typeString = (char*) mxGetPr( prhs[0] );
00194
00195
00196 if ( ( strcmp( typeString,"i" ) != 0 ) && ( strcmp( typeString,"I" ) != 0 ) &&
00197 ( strcmp( typeString,"h" ) != 0 ) && ( strcmp( typeString,"H" ) != 0 ) &&
00198 ( strcmp( typeString,"c" ) != 0 ) && ( strcmp( typeString,"C" ) != 0 ) )
00199 {
00200 mexErrMsgTxt( "ERROR (qpOASES): Undefined first input argument!\nType 'help qpOASES_sequence' for further information." );
00201 }
00202
00203
00204
00205
00206 if ( ( strcmp( typeString,"i" ) == 0 ) || ( strcmp( typeString,"I" ) == 0 ) )
00207 {
00208
00209 if ( ( nlhs < 1 ) || ( nlhs > 5 ) )
00210 mexErrMsgTxt( "ERROR (qpOASES): Invalid number of output arguments!\nType 'help qpOASES_sequence' for further information." );
00211
00212 if ( ( nrhs < 8 ) || ( nrhs > 10 ) )
00213 mexErrMsgTxt( "ERROR (qpOASES): Invalid number of input arguments!\nType 'help qpOASES_sequence' for further information." );
00214
00215
00216 if ( ( mxIsDouble( prhs[1] ) == 0 ) ||
00217 ( mxIsDouble( prhs[2] ) == 0 ) ||
00218 ( mxIsDouble( prhs[3] ) == 0 ) )
00219 mexErrMsgTxt( "ERROR (qpOASES): All data has to be provided in real_t precision!" );
00220
00221
00222
00223
00224
00225
00226
00227 nV = mxGetM( prhs[1] );
00228 nC = mxGetM( prhs[3] );
00229
00230 if ( ( mxGetN( prhs[1] ) != nV ) || ( ( mxGetN( prhs[3] ) != 0 ) && ( mxGetN( prhs[3] ) != nV ) ) )
00231 mexErrMsgTxt( "ERROR (qpOASES): Input dimension mismatch!" );
00232
00233
00234 if ( smartDimensionCheck( &g,nV,1, BT_FALSE,prhs,2 ) != SUCCESSFUL_RETURN )
00235 return;
00236
00237 if ( smartDimensionCheck( &lb,nV,1, BT_TRUE,prhs,4 ) != SUCCESSFUL_RETURN )
00238 return;
00239
00240 if ( smartDimensionCheck( &ub,nV,1, BT_TRUE,prhs,5 ) != SUCCESSFUL_RETURN )
00241 return;
00242
00243 if ( smartDimensionCheck( &lbA,nC,1, BT_TRUE,prhs,6 ) != SUCCESSFUL_RETURN )
00244 return;
00245
00246 if ( smartDimensionCheck( &ubA,nC,1, BT_TRUE,prhs,7 ) != SUCCESSFUL_RETURN )
00247 return;
00248
00249
00250 int nWSRin = 5*(nV+nC);
00251
00252
00253
00254 if ( nrhs > 8 )
00255 {
00256 if ( smartDimensionCheck( &x0,nV,1, BT_TRUE,prhs,8 ) != SUCCESSFUL_RETURN )
00257 return;
00258
00259 if ( nrhs > 9 )
00260 if ( ( !mxIsEmpty( prhs[9] ) ) && ( mxIsStruct( prhs[9] ) ) )
00261 setupOptions( &options,prhs[9],nWSRin );
00262 }
00263
00264 deleteGlobalQProblemInstance( );
00265 deleteGlobalQProblemMatrices( );
00266
00267
00268 if ( mxIsSparse( prhs[1] ) != 0 )
00269 {
00270 long *ir = (long *)mxGetIr(prhs[1]);
00271 long *jc = (long *)mxGetJc(prhs[1]);
00272 real_t *v = (real_t*)mxGetPr(prhs[1]);
00273
00274
00275
00276
00277
00278
00279 SymSparseMat *sH;
00280 globalQP_H = sH = new SymSparseMat(nV, nV, ir, jc, v);
00281 globalQP_Hdiag = sH->createDiagInfo();
00282 }
00283 else
00284 {
00285 H_for = (real_t*) mxGetPr( prhs[1] );
00286 H_mem = new real_t[nV*nV];
00287 for( int i=0; i<nV*nV; ++i )
00288 H_mem[i] = H_for[i];
00289 globalQP_H = new SymDenseMat( nV, nV, nV, H_mem );
00290 globalQP_H->doFreeMemory();
00291 }
00292
00293
00294
00295 if ( nC > 0 )
00296 {
00297
00298 if ( mxIsSparse( prhs[3] ) != 0 )
00299 {
00300 long *ir = (long *)mxGetIr(prhs[3]);
00301 long *jc = (long *)mxGetJc(prhs[3]);
00302 real_t *v = (real_t*)mxGetPr(prhs[3]);
00303
00304 globalQP_A = new SparseMatrix(nC, nV, ir, jc, v);
00305 }
00306 else
00307 {
00308
00309
00310 A_for = (real_t*) mxGetPr( prhs[3] );
00311 A_mem = new real_t[nC*nV];
00312 convertFortranToC( A_for,nV,nC, A_mem );
00313 globalQP_A = new DenseMatrix(nC, nV, nV, A_mem );
00314 globalQP_A->doFreeMemory();
00315 }
00316 }
00317
00318
00319 allocateOutputs( nlhs,plhs, nV,nC );
00320
00321
00322 init( nV,nC,
00323 globalQP_H,g,globalQP_A,
00324 lb,ub,lbA,ubA,
00325 nWSRin,x0,&options,
00326 nlhs,plhs
00327 );
00328
00329 return;
00330 }
00331
00332
00333 if ( ( strcmp( typeString,"h" ) == 0 ) || ( strcmp( typeString,"H" ) == 0 ) )
00334 {
00335
00336 if ( ( nlhs < 1 ) || ( nlhs > 5 ) )
00337 mexErrMsgTxt( "ERROR (qpOASES): Invalid number of output arguments!\nType 'help qpOASES_sequence' for further information." );
00338
00339 if ( ( nrhs < 6 ) || ( nrhs > 7 ) )
00340 mexErrMsgTxt( "ERROR (qpOASES): Invalid number of input arguments!\nType 'help qpOASES_sequence' for further information." );
00341
00342
00343 if ( globalQP == 0 )
00344 mexErrMsgTxt( "ERROR (qpOASES): QP sequence needs to be initialised first!" );
00345
00346
00347
00348 nV = globalQP->getNV( );
00349 nC = globalQP->getNC( );
00350
00351 if ( smartDimensionCheck( &g,nV,1, BT_FALSE,prhs,1 ) != SUCCESSFUL_RETURN )
00352 return;
00353
00354 if ( smartDimensionCheck( &lb,nV,1, BT_TRUE,prhs,2 ) != SUCCESSFUL_RETURN )
00355 return;
00356
00357 if ( smartDimensionCheck( &ub,nV,1, BT_TRUE,prhs,3 ) != SUCCESSFUL_RETURN )
00358 return;
00359
00360 if ( smartDimensionCheck( &lbA,nC,1, BT_TRUE,prhs,4 ) != SUCCESSFUL_RETURN )
00361 return;
00362
00363 if ( smartDimensionCheck( &ubA,nC,1, BT_TRUE,prhs,5 ) != SUCCESSFUL_RETURN )
00364 return;
00365
00366
00367 int nWSRin = 5*(nV+nC);
00368
00369
00370 if ( nrhs == 7 )
00371 if ( ( !mxIsEmpty( prhs[6] ) ) && ( mxIsStruct( prhs[6] ) ) )
00372 setupOptions( &options,prhs[6],nWSRin );
00373
00374
00375 allocateOutputs( nlhs,plhs, nV,nC );
00376
00377
00378 hotstart( g,
00379 lb,ub,lbA,ubA,
00380 nWSRin,&options,
00381 nlhs,plhs
00382 );
00383
00384 return;
00385 }
00386
00387
00388 if ( ( strcmp( typeString,"c" ) == 0 ) || ( strcmp( typeString,"C" ) == 0 ) )
00389 {
00390
00391 if ( nlhs != 0 )
00392 mexErrMsgTxt( "ERROR (qpOASES): Invalid number of output arguments!\nType 'help qpOASES_sequence' for further information." );
00393
00394 if ( nrhs != 1 )
00395 mexErrMsgTxt( "ERROR (qpOASES): Invalid number of input arguments!\nType 'help qpOASES_sequence' for further information." );
00396
00397
00398 deleteGlobalQProblemInstance( );
00399 deleteGlobalQProblemMatrices( );
00400
00401 return;
00402 }
00403 }
00404
00405
00406
00407