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