00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00035 #include <QProblem.hpp>
00036
00037 #include <stdio.h>
00038
00039 void printmatrix2(char *name, double *A, int m, int n) {
00040 int i, j;
00041
00042 printf("%s = [...\n", name);
00043 for (i = 0; i < m; i++) {
00044 for (j = 0; j < n; j++)
00045 printf(" % 9.4f", A[i*n+j]);
00046 printf(",\n");
00047 }
00048 printf("];\n");
00049 }
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 QProblem::QProblem( ) : QProblemB( )
00063 {
00064 constraints.init( 0 );
00065
00066 sizeT = 0;
00067
00068 cyclingManager.init( 0,0 );
00069 }
00070
00071
00072
00073
00074
00075 QProblem::QProblem( int _nV, int _nC ) : QProblemB( _nV )
00076 {
00077
00078 if ( _nV <= 0 )
00079 _nV = 1;
00080
00081 if ( _nC < 0 )
00082 {
00083 _nC = 0;
00084 THROWERROR( RET_INVALID_ARGUMENTS );
00085 }
00086
00087 constraints.init( _nC );
00088
00089
00090 sizeT = _nC;
00091 if ( _nC > _nV )
00092 sizeT = _nV;
00093
00094 cyclingManager.init( _nV,_nC );
00095 }
00096
00097
00098
00099
00100
00101 QProblem::QProblem( const QProblem& rhs ) : QProblemB( rhs )
00102 {
00103 int i, j;
00104
00105 int _nV = rhs.bounds.getNV( );
00106 int _nC = rhs.constraints.getNC( );
00107
00108 for( i=0; i<_nC; ++i )
00109 for( j=0; j<_nV; ++j )
00110 A[i*NVMAX + j] = rhs.A[i*NVMAX + j];
00111
00112 for( i=0; i<_nC; ++i )
00113 lbA[i] = rhs.lbA[i];
00114
00115 for( i=0; i<_nC; ++i )
00116 ubA[i] = rhs.ubA[i];
00117
00118 constraints = rhs.constraints;
00119
00120 for( i=0; i<(_nV+_nC); ++i )
00121 y[i] = rhs.y[i];
00122
00123
00124 sizeT = rhs.sizeT;
00125
00126 for( i=0; i<sizeT; ++i )
00127 for( j=0; j<sizeT; ++j )
00128 T[i*NVMAX + j] = rhs.T[i*NVMAX + j];
00129
00130 for( i=0; i<_nV; ++i )
00131 for( j=0; j<_nV; ++j )
00132 Q[i*NVMAX + j] = rhs.Q[i*NVMAX + j];
00133
00134 for( i=0; i<_nC; ++i )
00135 Ax[i] = rhs.Ax[i];
00136
00137 cyclingManager = rhs.cyclingManager;
00138 }
00139
00140
00141
00142
00143
00144 QProblem::~QProblem( )
00145 {
00146 }
00147
00148
00149
00150
00151
00152 QProblem& QProblem::operator=( const QProblem& rhs )
00153 {
00154 int i, j;
00155
00156 if ( this != &rhs )
00157 {
00158 QProblemB::operator=( rhs );
00159
00160
00161 int _nV = rhs.bounds.getNV( );
00162 int _nC = rhs.constraints.getNC( );
00163
00164 for( i=0; i<_nC; ++i )
00165 for( j=0; j<_nV; ++j )
00166 A[i*NVMAX + j] = rhs.A[i*NVMAX + j];
00167
00168 for( i=0; i<_nC; ++i )
00169 lbA[i] = rhs.lbA[i];
00170
00171 for( i=0; i<_nC; ++i )
00172 ubA[i] = rhs.ubA[i];
00173
00174 constraints = rhs.constraints;
00175
00176 for( i=0; i<(_nV+_nC); ++i )
00177 y[i] = rhs.y[i];
00178
00179
00180 sizeT = rhs.sizeT;
00181
00182 for( i=0; i<sizeT; ++i )
00183 for( j=0; j<sizeT; ++j )
00184 T[i*NVMAX + j] = rhs.T[i*NVMAX + j];
00185
00186 for( i=0; i<_nV; ++i )
00187 for( j=0; j<_nV; ++j )
00188 Q[i*NVMAX + j] = rhs.Q[i*NVMAX + j];
00189
00190 for( i=0; i<_nC; ++i )
00191 Ax[i] = rhs.Ax[i];
00192
00193 cyclingManager = rhs.cyclingManager;
00194 }
00195
00196 return *this;
00197 }
00198
00199
00200
00201
00202
00203 returnValue QProblem::reset( )
00204 {
00205 int i, j;
00206 int nV = getNV( );
00207 int nC = getNC( );
00208
00209
00210
00211 if ( QProblemB::reset( ) != SUCCESSFUL_RETURN )
00212 return THROWERROR( RET_RESET_FAILED );
00213
00214
00215 constraints.init( nC );
00216
00217
00218 for( i=0; i<sizeT; ++i )
00219 for( j=0; j<sizeT; ++j )
00220 T[i*NVMAX + j] = 0.0;
00221
00222 for( i=0; i<nV; ++i )
00223 for( j=0; j<nV; ++j )
00224 Q[i*NVMAX + j] = 0.0;
00225
00226
00227 if ( cyclingManager.clearCyclingData( ) != SUCCESSFUL_RETURN )
00228 return THROWERROR( RET_RESET_FAILED );
00229
00230 return SUCCESSFUL_RETURN;
00231 }
00232
00233
00234
00235
00236
00237 returnValue QProblem::init( const real_t* const _H, const real_t* const _g, const real_t* const _A,
00238 const real_t* const _lb, const real_t* const _ub,
00239 const real_t* const _lbA, const real_t* const _ubA,
00240 int& nWSR, const real_t* const yOpt, real_t* const cputime
00241 )
00242 {
00243
00244 if ( setupQPdata( _H,_g,_A,_lb,_ub,_lbA,_ubA ) != SUCCESSFUL_RETURN )
00245 return THROWERROR( RET_INVALID_ARGUMENTS );
00246
00247
00248 return solveInitialQP( 0,yOpt,0,0, nWSR,cputime );
00249 }
00250
00251
00252
00253
00254
00255 returnValue QProblem::hotstart( const real_t* const g_new, const real_t* const lb_new, const real_t* const ub_new,
00256 const real_t* const lbA_new, const real_t* const ubA_new,
00257 int& nWSR, real_t* const cputime
00258 )
00259 {
00260 int l;
00261
00262
00263 if ( ( getStatus( ) == QPS_NOTINITIALISED ) ||
00264 ( getStatus( ) == QPS_PREPARINGAUXILIARYQP ) ||
00265 ( getStatus( ) == QPS_PERFORMINGHOMOTOPY ) )
00266 {
00267 return THROWERROR( RET_HOTSTART_FAILED_AS_QP_NOT_INITIALISED );
00268 }
00269
00270
00271 real_t starttime = 0.0;
00272 if ( cputime != 0 )
00273 starttime = getCPUtime( );
00274
00275
00276
00277
00278 cyclingManager.clearCyclingData( );
00279
00280 infeasible = BT_FALSE;
00281 unbounded = BT_FALSE;
00282
00283 ++count;
00284
00285
00286 returnValue returnvalue;
00287 BooleanType Delta_bC_isZero, Delta_bB_isZero;
00288
00289 int FR_idx[NVMAX];
00290 int FX_idx[NVMAX];
00291 int AC_idx[NCMAX_ALLOC];
00292 int IAC_idx[NCMAX_ALLOC];
00293
00294 real_t delta_g[NVMAX];
00295 real_t delta_lb[NVMAX];
00296 real_t delta_ub[NVMAX];
00297 real_t delta_lbA[NCMAX_ALLOC];
00298 real_t delta_ubA[NCMAX_ALLOC];
00299
00300 real_t delta_xFR[NVMAX];
00301 real_t delta_xFX[NVMAX];
00302 real_t delta_yAC[NCMAX_ALLOC];
00303 real_t delta_yFX[NVMAX];
00304 real_t delta_Ax[NCMAX_ALLOC];
00305
00306 int BC_idx;
00307 SubjectToStatus BC_status;
00308 BooleanType BC_isBound;
00309
00310 #ifdef PC_DEBUG
00311 char messageString[80];
00312 #endif
00313
00314
00315
00316 for( l=0; l<nWSR; ++l )
00317 {
00318 status = QPS_PERFORMINGHOMOTOPY;
00319
00320 if ( printlevel == PL_HIGH )
00321 {
00322 #ifdef PC_DEBUG
00323 sprintf( messageString,"%d ...",l );
00324 getGlobalMessageHandler( )->throwInfo( RET_ITERATION_STARTED,messageString,__FUNCTION__,__FILE__,__LINE__,VS_VISIBLE );
00325 #endif
00326 }
00327
00328
00329 if ( bounds.getFree( )->getNumberArray( FR_idx ) != SUCCESSFUL_RETURN )
00330 return THROWERROR( RET_HOTSTART_FAILED );
00331
00332 if ( bounds.getFixed( )->getNumberArray( FX_idx ) != SUCCESSFUL_RETURN )
00333 return THROWERROR( RET_HOTSTART_FAILED );
00334
00335 if ( constraints.getActive( )->getNumberArray( AC_idx ) != SUCCESSFUL_RETURN )
00336 return THROWERROR( RET_HOTSTART_FAILED );
00337
00338 if ( constraints.getInactive( )->getNumberArray( IAC_idx ) != SUCCESSFUL_RETURN )
00339 return THROWERROR( RET_HOTSTART_FAILED );
00340
00341
00342 returnvalue = hotstart_determineDataShift( FX_idx, AC_idx,
00343 g_new,lbA_new,ubA_new,lb_new,ub_new,
00344 delta_g,delta_lbA,delta_ubA,delta_lb,delta_ub,
00345 Delta_bC_isZero, Delta_bB_isZero );
00346 if ( returnvalue != SUCCESSFUL_RETURN )
00347 {
00348 nWSR = l;
00349 THROWERROR( RET_SHIFT_DETERMINATION_FAILED );
00350 return returnvalue;
00351 }
00352
00353
00354 returnvalue = hotstart_determineStepDirection( FR_idx,FX_idx,AC_idx,
00355 delta_g,delta_lbA,delta_ubA,delta_lb,delta_ub,
00356 Delta_bC_isZero, Delta_bB_isZero,
00357 delta_xFX,delta_xFR,delta_yAC,delta_yFX
00358 );
00359 if ( returnvalue != SUCCESSFUL_RETURN )
00360 {
00361 nWSR = l;
00362 THROWERROR( RET_STEPDIRECTION_DETERMINATION_FAILED );
00363 return returnvalue;
00364 }
00365
00366
00367 returnvalue = hotstart_determineStepLength( FR_idx,FX_idx,AC_idx,IAC_idx,
00368 delta_lbA,delta_ubA,delta_lb,delta_ub,
00369 delta_xFX,delta_xFR,delta_yAC,delta_yFX,delta_Ax,
00370 BC_idx,BC_status,BC_isBound
00371 );
00372 if ( returnvalue != SUCCESSFUL_RETURN )
00373 {
00374 nWSR = l;
00375 THROWERROR( RET_STEPLENGTH_DETERMINATION_FAILED );
00376 return returnvalue;
00377 }
00378
00379
00380 returnvalue = hotstart_performStep( FR_idx,FX_idx,AC_idx,IAC_idx,
00381 delta_g,delta_lbA,delta_ubA,delta_lb,delta_ub,
00382 delta_xFX,delta_xFR,delta_yAC,delta_yFX,delta_Ax,
00383 BC_idx,BC_status,BC_isBound
00384 );
00385
00386 if ( returnvalue != SUCCESSFUL_RETURN )
00387 {
00388 nWSR = l;
00389
00390
00391 if ( cputime != 0 )
00392 *cputime = getCPUtime( ) - starttime;
00393
00394
00395 if ( returnvalue == RET_OPTIMAL_SOLUTION_FOUND )
00396 {
00397 status = QPS_SOLVED;
00398
00399 if ( printlevel == PL_HIGH )
00400 THROWINFO( RET_OPTIMAL_SOLUTION_FOUND );
00401
00402 #ifdef PC_DEBUG
00403 if ( printIteration( l,BC_idx,BC_status,BC_isBound ) != SUCCESSFUL_RETURN )
00404 THROWERROR( RET_PRINT_ITERATION_FAILED );
00405 #endif
00406
00407
00408 return checkKKTconditions( );
00409 }
00410 else
00411 {
00412
00413 if ( isInfeasible( ) == BT_TRUE )
00414 {
00415 status = QPS_HOMOTOPYQPSOLVED;
00416 return THROWERROR( RET_HOTSTART_STOPPED_INFEASIBILITY );
00417 }
00418
00419
00420 if ( unbounded == BT_TRUE )
00421 return THROWERROR( RET_HOTSTART_STOPPED_UNBOUNDEDNESS );
00422
00423
00424 THROWERROR( RET_HOMOTOPY_STEP_FAILED );
00425 return returnvalue;
00426 }
00427 }
00428
00429
00430 status = QPS_HOMOTOPYQPSOLVED;
00431
00432 #ifdef PC_DEBUG
00433 if ( printIteration( l,BC_idx,BC_status,BC_isBound ) != SUCCESSFUL_RETURN )
00434 THROWERROR( RET_PRINT_ITERATION_FAILED );
00435 #endif
00436 }
00437
00438
00439
00440 if ( cputime != 0 )
00441 *cputime = getCPUtime( ) - starttime;
00442
00443
00444
00445
00446 if ( printlevel == PL_HIGH )
00447 {
00448 #ifdef PC_DEBUG
00449 sprintf( messageString,"(nWSR = %d)",nWSR );
00450 return getGlobalMessageHandler( )->throwWarning( RET_MAX_NWSR_REACHED,messageString,__FUNCTION__,__FILE__,__LINE__,VS_VISIBLE );
00451 #endif
00452 }
00453
00454
00455 returnValue returnvalueKKTcheck = checkKKTconditions( );
00456
00457 if ( returnvalueKKTcheck != SUCCESSFUL_RETURN )
00458 return returnvalueKKTcheck;
00459 else
00460 return RET_MAX_NWSR_REACHED;
00461 }
00462
00463
00464
00465
00466
00467 int QProblem::getNZ( )
00468 {
00469
00470 return bounds.getFree( )->getLength( ) - constraints.getActive( )->getLength( );
00471 }
00472
00473
00474
00475
00476
00477 returnValue QProblem::getDualSolution( real_t* const yOpt ) const
00478 {
00479 int i;
00480
00481
00482
00483 if ( ( getStatus( ) == QPS_AUXILIARYQPSOLVED ) ||
00484 ( getStatus( ) == QPS_HOMOTOPYQPSOLVED ) ||
00485 ( getStatus( ) == QPS_SOLVED ) )
00486 {
00487 for( i=0; i<getNV( )+getNC( ); ++i )
00488 yOpt[i] = y[i];
00489
00490 return SUCCESSFUL_RETURN;
00491 }
00492 else
00493 {
00494 return RET_QP_NOT_SOLVED;
00495 }
00496 }
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507 returnValue QProblem::setupSubjectToType( )
00508 {
00509 int i;
00510 int nC = getNC( );
00511
00512
00513
00514 if ( QProblemB::setupSubjectToType( ) != SUCCESSFUL_RETURN )
00515 return THROWERROR( RET_SETUPSUBJECTTOTYPE_FAILED );
00516
00517
00518
00519
00520 constraints.setNoLower( BT_TRUE );
00521 for( i=0; i<nC; ++i )
00522 {
00523 if ( lbA[i] > -INFTY )
00524 {
00525 constraints.setNoLower( BT_FALSE );
00526 break;
00527 }
00528 }
00529
00530
00531 constraints.setNoUpper( BT_TRUE );
00532 for( i=0; i<nC; ++i )
00533 {
00534 if ( ubA[i] < INFTY )
00535 {
00536 constraints.setNoUpper( BT_FALSE );
00537 break;
00538 }
00539 }
00540
00541
00542 int nEC = 0;
00543 int nUC = 0;
00544
00545 for( i=0; i<nC; ++i )
00546 {
00547 if ( ( lbA[i] < -INFTY + BOUNDTOL ) && ( ubA[i] > INFTY - BOUNDTOL ) )
00548 {
00549 constraints.setType( i,ST_UNBOUNDED );
00550 ++nUC;
00551 }
00552 else
00553 {
00554 if ( lbA[i] > ubA[i] - BOUNDTOL )
00555 {
00556 constraints.setType( i,ST_EQUALITY );
00557 ++nEC;
00558 }
00559 else
00560 {
00561 constraints.setType( i,ST_BOUNDED );
00562 }
00563 }
00564 }
00565
00566
00567 constraints.setNEC( nEC );
00568 constraints.setNUC( nUC );
00569 constraints.setNIC( nC - nEC - nUC );
00570
00571 return SUCCESSFUL_RETURN;
00572 }
00573
00574
00575
00576
00577
00578 returnValue QProblem::setupCholeskyDecompositionProjected( )
00579 {
00580 int i, j, k, ii, kk;
00581 int nV = getNV( );
00582 int nFR = getNFR( );
00583 int nZ = getNZ( );
00584
00585
00586 for( i=0; i<nV; ++i )
00587 for( j=0; j<nV; ++j )
00588 R[i*NVMAX + j] = 0.0;
00589
00590
00591 if ( hessianType == HST_IDENTITY )
00592 {
00593
00594 for( i=0; i<nV; ++i )
00595 R[i*NVMAX + i] = 1.0;
00596 }
00597 else
00598 {
00599 if ( nZ > 0 )
00600 {
00601 int FR_idx[NVMAX];
00602 if ( bounds.getFree( )->getNumberArray( FR_idx ) != SUCCESSFUL_RETURN )
00603 return THROWERROR( RET_INDEXLIST_CORRUPTED );
00604
00605 int AC_idx[NCMAX_ALLOC];
00606 if ( constraints.getActive( )->getNumberArray( AC_idx ) != SUCCESSFUL_RETURN )
00607 return THROWERROR( RET_INDEXLIST_CORRUPTED );
00608
00609
00610 real_t HZ[NVMAX*NVMAX];
00611 real_t ZHZ[NVMAX*NVMAX];
00612
00613
00614 for ( i=0; i<nFR; ++i )
00615 {
00616 ii = FR_idx[i];
00617
00618 for ( j=0; j<nZ; ++j )
00619 {
00620 HZ[i*NVMAX + j] = 0.0;
00621 for ( k=0; k<nFR; ++k )
00622 {
00623 kk = FR_idx[k];
00624 HZ[i*NVMAX + j] += H[ii*NVMAX + kk] * Q[kk*NVMAX + j];
00625 }
00626 }
00627 }
00628
00629
00630 for ( i=0; i<nZ; ++i )
00631 for ( j=0; j<nZ; ++j )
00632 {
00633 ZHZ[i*NVMAX + j] = 0.0;
00634 for ( k=0; k<nFR; ++k )
00635 {
00636 kk = FR_idx[k];
00637 ZHZ[i*NVMAX + j] += Q[kk*NVMAX + i] * HZ[k*NVMAX + j];
00638 }
00639 }
00640
00641
00642 real_t sum;
00643
00644 for( i=0; i<nZ; ++i )
00645 {
00646
00647 sum = ZHZ[i*NVMAX + i];
00648
00649 for( k=(i-1); k>=0; --k )
00650 sum -= R[k*NVMAX + i] * R[k*NVMAX + i];
00651
00652 if ( sum > 0.0 )
00653 R[i*NVMAX + i] = sqrt( sum );
00654 else
00655 {
00656 hessianType = HST_SEMIDEF;
00657 return THROWERROR( RET_HESSIAN_NOT_SPD );
00658 }
00659
00660 for( j=(i+1); j<nZ; ++j )
00661 {
00662 sum = ZHZ[j*NVMAX + i];
00663
00664 for( k=(i-1); k>=0; --k )
00665 sum -= R[k*NVMAX + i] * R[k*NVMAX + j];
00666
00667 R[i*NVMAX + j] = sum / R[i*NVMAX + i];
00668 }
00669 }
00670 }
00671 }
00672
00673 return SUCCESSFUL_RETURN;
00674 }
00675
00676
00677
00678
00679
00680 returnValue QProblem::setupTQfactorisation( )
00681 {
00682 int i, j, ii;
00683 int nV = getNV( );
00684 int nFR = getNFR( );
00685
00686 int FR_idx[NVMAX];
00687 if ( bounds.getFree( )->getNumberArray( FR_idx ) != SUCCESSFUL_RETURN )
00688 return THROWERROR( RET_INDEXLIST_CORRUPTED );
00689
00690
00691 for( i=0; i<nV; ++i )
00692 for( j=0; j<nV; ++j )
00693 Q[i*NVMAX + j] = 0.0;
00694
00695 for( i=0; i<nFR; ++i )
00696 {
00697 ii = FR_idx[i];
00698 Q[ii*NVMAX + i] = 1.0;
00699 }
00700
00701
00702 for( i=0; i<sizeT; ++i )
00703 for( j=0; j<sizeT; ++j )
00704 T[i*NVMAX + j] = 0.0;
00705
00706 return SUCCESSFUL_RETURN;
00707 }
00708
00709
00710
00711
00712
00713 returnValue QProblem::solveInitialQP( const real_t* const xOpt, const real_t* const yOpt,
00714 const Bounds* const guessedBounds, const Constraints* const guessedConstraints,
00715 int& nWSR, real_t* const cputime
00716 )
00717 {
00718 int i;
00719
00720
00721 int nV = getNV( );
00722 int nC = getNC( );
00723
00724
00725
00726 real_t starttime = 0.0;
00727 if ( cputime != 0 )
00728 starttime = getCPUtime( );
00729
00730
00731 status = QPS_NOTINITIALISED;
00732
00733
00734
00735 if ( checkForIdentityHessian( ) != SUCCESSFUL_RETURN )
00736 return THROWERROR( RET_INIT_FAILED );
00737
00738
00739 if ( setupSubjectToType( ) != SUCCESSFUL_RETURN )
00740 return THROWERROR( RET_INIT_FAILED );
00741
00742
00743 cyclingManager.clearCyclingData( );
00744
00745 status = QPS_PREPARINGAUXILIARYQP;
00746
00747
00748
00749
00750 if ( bounds.setupAllFree( ) != SUCCESSFUL_RETURN )
00751 return THROWERROR( RET_INIT_FAILED );
00752
00753 if ( constraints.setupAllInactive( ) != SUCCESSFUL_RETURN )
00754 return THROWERROR( RET_INIT_FAILED );
00755
00756
00757 if ( setupAuxiliaryQPsolution( xOpt,yOpt ) != SUCCESSFUL_RETURN )
00758 return THROWERROR( RET_INIT_FAILED );
00759
00760
00761
00762 static Bounds auxiliaryBounds;
00763
00764 auxiliaryBounds.init( nV );
00765
00766 static Constraints auxiliaryConstraints;
00767
00768 auxiliaryConstraints.init( nC );
00769
00770 if ( obtainAuxiliaryWorkingSet( xOpt,yOpt,guessedBounds,guessedConstraints,
00771 &auxiliaryBounds,&auxiliaryConstraints ) != SUCCESSFUL_RETURN )
00772 return THROWERROR( RET_INIT_FAILED );
00773
00774
00775 if ( setupTQfactorisation( ) != SUCCESSFUL_RETURN )
00776 return THROWERROR( RET_INIT_FAILED_TQ );
00777
00778 if ( setupAuxiliaryWorkingSet( &auxiliaryBounds,&auxiliaryConstraints,BT_TRUE ) != SUCCESSFUL_RETURN )
00779 return THROWERROR( RET_INIT_FAILED );
00780
00781 if ( ( getNAC( ) + getNFX( ) ) == 0 )
00782 {
00783
00784 if ( setupCholeskyDecomposition( ) != SUCCESSFUL_RETURN )
00785 return THROWERROR( RET_INIT_FAILED_CHOLESKY );
00786 }
00787 else
00788 {
00789
00790 if ( setupCholeskyDecompositionProjected( ) != SUCCESSFUL_RETURN )
00791 return THROWERROR( RET_INIT_FAILED_CHOLESKY );
00792 }
00793
00794
00795 real_t g_original[NVMAX];
00796 real_t lb_original[NVMAX];
00797 real_t ub_original[NVMAX];
00798 real_t lbA_original[NCMAX_ALLOC];
00799 real_t ubA_original[NCMAX_ALLOC];
00800
00801 for( i=0; i<nV; ++i )
00802 {
00803 g_original[i] = g[i];
00804 lb_original[i] = lb[i];
00805 ub_original[i] = ub[i];
00806 }
00807
00808 for( i=0; i<nC; ++i )
00809 {
00810 lbA_original[i] = lbA[i];
00811 ubA_original[i] = ubA[i];
00812 }
00813
00814
00815
00816 if ( setupAuxiliaryQPgradient( ) != SUCCESSFUL_RETURN )
00817 return THROWERROR( RET_INIT_FAILED );
00818
00819 if ( setupAuxiliaryQPbounds( &auxiliaryBounds,&auxiliaryConstraints,BT_TRUE ) != SUCCESSFUL_RETURN )
00820 return THROWERROR( RET_INIT_FAILED );
00821
00822 status = QPS_AUXILIARYQPSOLVED;
00823
00824
00825
00826
00827 returnValue returnvalue = hotstart( g_original,lb_original,ub_original,lbA_original,ubA_original, nWSR,0 );
00828
00829
00830
00831 if ( isInfeasible( ) == BT_TRUE )
00832 return THROWERROR( RET_INIT_FAILED_INFEASIBILITY );
00833
00834 if ( isUnbounded( ) == BT_TRUE )
00835 return THROWERROR( RET_INIT_FAILED_UNBOUNDEDNESS );
00836
00837
00838 if ( ( returnvalue != SUCCESSFUL_RETURN ) && ( returnvalue != RET_MAX_NWSR_REACHED ) &&
00839 ( returnvalue != RET_INACCURATE_SOLUTION ) && ( returnvalue != RET_NO_SOLUTION ) )
00840 return THROWERROR( RET_INIT_FAILED_HOTSTART );
00841
00842
00843
00844 if ( cputime != 0 )
00845 *cputime = getCPUtime( ) - starttime;
00846
00847 if ( printlevel == PL_HIGH )
00848 THROWINFO( RET_INIT_SUCCESSFUL );
00849
00850 return returnvalue;
00851 }
00852
00853
00854
00855
00856
00857 returnValue QProblem::obtainAuxiliaryWorkingSet( const real_t* const xOpt, const real_t* const yOpt,
00858 const Bounds* const guessedBounds, const Constraints* const guessedConstraints,
00859 Bounds* auxiliaryBounds, Constraints* auxiliaryConstraints
00860 ) const
00861 {
00862 int i = 0;
00863 int nV = getNV( );
00864 int nC = getNC( );
00865
00866
00867
00868 if ( ( auxiliaryBounds == 0 ) || ( auxiliaryBounds == guessedBounds ) )
00869 return THROWERROR( RET_INVALID_ARGUMENTS );
00870
00871 if ( ( auxiliaryConstraints == 0 ) || ( auxiliaryConstraints == guessedConstraints ) )
00872 return THROWERROR( RET_INVALID_ARGUMENTS );
00873
00874
00875 SubjectToStatus guessedStatus;
00876
00877
00878 if ( QProblemB::obtainAuxiliaryWorkingSet( xOpt,yOpt,guessedBounds, auxiliaryBounds ) != SUCCESSFUL_RETURN )
00879 return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
00880
00881
00882 if ( guessedConstraints != 0 )
00883 {
00884
00885
00886 for( i=0; i<nC; ++i )
00887 {
00888 guessedStatus = guessedConstraints->getStatus( i );
00889
00890 if ( constraints.getType( i ) == ST_EQUALITY )
00891 {
00892 if ( auxiliaryConstraints->setupConstraint( i,ST_LOWER ) != SUCCESSFUL_RETURN )
00893 return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
00894 }
00895 else
00896 {
00897 if ( auxiliaryConstraints->setupConstraint( i,guessedStatus ) != SUCCESSFUL_RETURN )
00898 return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
00899 }
00900 }
00901 }
00902 else
00903 {
00904
00905 if ( ( xOpt != 0 ) && ( yOpt == 0 ) )
00906 {
00907 for( i=0; i<nC; ++i )
00908 {
00909 if ( Ax[i] <= lbA[i] + BOUNDTOL )
00910 {
00911 if ( auxiliaryConstraints->setupConstraint( i,ST_LOWER ) != SUCCESSFUL_RETURN )
00912 return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
00913 continue;
00914 }
00915
00916 if ( Ax[i] >= ubA[i] - BOUNDTOL )
00917 {
00918 if ( auxiliaryConstraints->setupConstraint( i,ST_UPPER ) != SUCCESSFUL_RETURN )
00919 return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
00920 continue;
00921 }
00922
00923
00924 if ( constraints.getType( i ) == ST_EQUALITY )
00925 {
00926 if ( auxiliaryConstraints->setupConstraint( i,ST_LOWER ) != SUCCESSFUL_RETURN )
00927 return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
00928 }
00929 else
00930 {
00931 if ( auxiliaryConstraints->setupConstraint( i,ST_INACTIVE ) != SUCCESSFUL_RETURN )
00932 return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
00933 }
00934 }
00935 }
00936
00937
00938 if ( ( xOpt == 0 ) && ( yOpt != 0 ) )
00939 {
00940 for( i=0; i<nC; ++i )
00941 {
00942 if ( yOpt[nV+i] > ZERO )
00943 {
00944 if ( auxiliaryConstraints->setupConstraint( i,ST_LOWER ) != SUCCESSFUL_RETURN )
00945 return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
00946 continue;
00947 }
00948
00949 if ( yOpt[nV+i] < -ZERO )
00950 {
00951 if ( auxiliaryConstraints->setupConstraint( i,ST_UPPER ) != SUCCESSFUL_RETURN )
00952 return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
00953 continue;
00954 }
00955
00956
00957 if ( constraints.getType( i ) == ST_EQUALITY )
00958 {
00959 if ( auxiliaryConstraints->setupConstraint( i,ST_LOWER ) != SUCCESSFUL_RETURN )
00960 return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
00961 }
00962 else
00963 {
00964 if ( auxiliaryConstraints->setupConstraint( i,ST_INACTIVE ) != SUCCESSFUL_RETURN )
00965 return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
00966 }
00967 }
00968 }
00969
00970
00971
00972
00973 if ( ( xOpt == 0 ) && ( yOpt == 0 ) )
00974 {
00975 for( i=0; i<nC; ++i )
00976 {
00977
00978 if ( constraints.getType( i ) == ST_EQUALITY )
00979 {
00980 if ( auxiliaryConstraints->setupConstraint( i,ST_LOWER ) != SUCCESSFUL_RETURN )
00981 return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
00982 }
00983 else
00984 {
00985 if ( auxiliaryConstraints->setupConstraint( i,ST_INACTIVE ) != SUCCESSFUL_RETURN )
00986 return THROWERROR( RET_OBTAINING_WORKINGSET_FAILED );
00987 }
00988 }
00989 }
00990 }
00991
00992 return SUCCESSFUL_RETURN;
00993 }
00994
00995
00996
00997
00998
00999
01000 returnValue QProblem::setupAuxiliaryWorkingSet( const Bounds* const auxiliaryBounds,
01001 const Constraints* const auxiliaryConstraints,
01002 BooleanType setupAfresh
01003 )
01004 {
01005 int i;
01006 int nV = getNV( );
01007 int nC = getNC( );
01008
01009
01010 if ( auxiliaryBounds != 0 )
01011 {
01012 for( i=0; i<nV; ++i )
01013 if ( ( bounds.getStatus( i ) == ST_UNDEFINED ) || ( auxiliaryBounds->getStatus( i ) == ST_UNDEFINED ) )
01014 return THROWERROR( RET_UNKNOWN_BUG );
01015 }
01016 else
01017 {
01018 return THROWERROR( RET_INVALID_ARGUMENTS );
01019 }
01020
01021 if ( auxiliaryConstraints != 0 )
01022 {
01023 for( i=0; i<nC; ++i )
01024 if ( ( constraints.getStatus( i ) == ST_UNDEFINED ) || ( auxiliaryConstraints->getStatus( i ) == ST_UNDEFINED ) )
01025 return THROWERROR( RET_UNKNOWN_BUG );
01026 }
01027 else
01028 {
01029 return THROWERROR( RET_INVALID_ARGUMENTS );
01030 }
01031
01032
01033
01034
01035
01036 BooleanType updateCholesky;
01037 if ( setupAfresh == BT_TRUE )
01038 updateCholesky = BT_FALSE;
01039 else
01040 updateCholesky = BT_TRUE;
01041
01042
01043
01044 if ( setupAfresh == BT_FALSE )
01045 {
01046
01047
01048 for( i=0; i<nC; ++i )
01049 {
01050 if ( ( constraints.getStatus( i ) == ST_LOWER ) && ( auxiliaryConstraints->getStatus( i ) != ST_LOWER ) )
01051 if ( removeConstraint( i,updateCholesky ) != SUCCESSFUL_RETURN )
01052 return THROWERROR( RET_SETUP_WORKINGSET_FAILED );
01053
01054 if ( ( constraints.getStatus( i ) == ST_UPPER ) && ( auxiliaryConstraints->getStatus( i ) != ST_UPPER ) )
01055 if ( removeConstraint( i,updateCholesky ) != SUCCESSFUL_RETURN )
01056 return THROWERROR( RET_SETUP_WORKINGSET_FAILED );
01057 }
01058
01059
01060
01061 for( i=0; i<nV; ++i )
01062 {
01063 if ( ( bounds.getStatus( i ) == ST_LOWER ) && ( auxiliaryBounds->getStatus( i ) != ST_LOWER ) )
01064 if ( removeBound( i,updateCholesky ) != SUCCESSFUL_RETURN )
01065 return THROWERROR( RET_SETUP_WORKINGSET_FAILED );
01066
01067 if ( ( bounds.getStatus( i ) == ST_UPPER ) && ( auxiliaryBounds->getStatus( i ) != ST_UPPER ) )
01068 if ( removeBound( i,updateCholesky ) != SUCCESSFUL_RETURN )
01069 return THROWERROR( RET_SETUP_WORKINGSET_FAILED );
01070 }
01071 }
01072
01073
01074
01075
01076
01077 for( i=0; i<nV; ++i )
01078 {
01079 if ( ( bounds.getStatus( i ) == ST_INACTIVE ) && ( auxiliaryBounds->getStatus( i ) != ST_INACTIVE ) )
01080 {
01081
01082 if ( addBound_checkLI( i ) == RET_LINEARLY_INDEPENDENT )
01083 {
01084 if ( addBound( i,auxiliaryBounds->getStatus( i ),updateCholesky ) != SUCCESSFUL_RETURN )
01085 return THROWERROR( RET_SETUP_WORKINGSET_FAILED );
01086 }
01087 }
01088 }
01089
01090
01091
01092 for( i=0; i<nC; ++i )
01093 {
01094 if ( ( auxiliaryConstraints->getStatus( i ) == ST_LOWER ) || ( auxiliaryConstraints->getStatus( i ) == ST_UPPER ) )
01095 {
01096
01097 if ( constraints.getStatus( i ) == ST_INACTIVE )
01098 {
01099
01100 if ( addConstraint_checkLI( i ) == RET_LINEARLY_INDEPENDENT )
01101 {
01102 if ( addConstraint( i,auxiliaryConstraints->getStatus( i ),updateCholesky ) != SUCCESSFUL_RETURN )
01103 return THROWERROR( RET_SETUP_WORKINGSET_FAILED );
01104 }
01105 }
01106 }
01107 }
01108
01109 return SUCCESSFUL_RETURN;
01110 }
01111
01112
01113
01114
01115
01116 returnValue QProblem::setupAuxiliaryQPsolution( const real_t* const xOpt, const real_t* const yOpt
01117 )
01118 {
01119 int i, j;
01120 int nV = getNV( );
01121 int nC = getNC( );
01122
01123
01124
01125
01126
01127 if ( xOpt != 0 )
01128 {
01129 if ( xOpt != x )
01130 for( i=0; i<nV; ++i )
01131 x[i] = xOpt[i];
01132
01133 for ( j=0; j<nC; ++j )
01134 {
01135 Ax[j] = 0.0;
01136
01137 for( i=0; i<nV; ++i )
01138 Ax[j] += A[j*NVMAX + i] * x[i];
01139 }
01140 }
01141 else
01142 {
01143 for( i=0; i<nV; ++i )
01144 x[i] = 0.0;
01145
01146 for ( j=0; j<nC; ++j )
01147 Ax[j] = 0.0;
01148 }
01149
01150 if ( yOpt != 0 )
01151 {
01152 if ( yOpt != y )
01153 for( i=0; i<nV+nC; ++i )
01154 y[i] = yOpt[i];
01155 }
01156 else
01157 {
01158 for( i=0; i<nV+nC; ++i )
01159 y[i] = 0.0;
01160 }
01161
01162 return SUCCESSFUL_RETURN;
01163 }
01164
01165
01166
01167
01168
01169 returnValue QProblem::setupAuxiliaryQPgradient( )
01170 {
01171 int i, j;
01172 int nV = getNV( );
01173 int nC = getNC( );
01174
01175
01176
01177 for ( i=0; i<nV; ++i )
01178 {
01179
01180 g[i] = y[i];
01181
01182
01183 for ( j=0; j<nC; ++j )
01184 g[i] += A[j*NVMAX + i] * y[nV+j];
01185
01186
01187 for ( j=0; j<nV; ++j )
01188 g[i] -= H[i*NVMAX + j] * x[j];
01189 }
01190
01191 return SUCCESSFUL_RETURN;
01192 }
01193
01194
01195
01196
01197
01198 returnValue QProblem::setupAuxiliaryQPbounds( const Bounds* const auxiliaryBounds,
01199 const Constraints* const auxiliaryConstraints,
01200 BooleanType useRelaxation
01201 )
01202 {
01203 int i;
01204 int nV = getNV( );
01205 int nC = getNC( );
01206
01207
01208
01209 for ( i=0; i<nV; ++i )
01210 {
01211 switch ( bounds.getStatus( i ) )
01212 {
01213 case ST_INACTIVE:
01214 if ( useRelaxation == BT_TRUE )
01215 {
01216 if ( bounds.getType( i ) == ST_EQUALITY )
01217 {
01218 lb[i] = x[i];
01219 ub[i] = x[i];
01220 }
01221 else
01222 {
01223
01224
01225
01226 if ( auxiliaryBounds->getStatus( i ) == ST_LOWER )
01227 lb[i] = x[i];
01228 else
01229 lb[i] = x[i] - BOUNDRELAXATION;
01230
01231 if ( auxiliaryBounds->getStatus( i ) == ST_UPPER )
01232 ub[i] = x[i];
01233 else
01234 ub[i] = x[i] + BOUNDRELAXATION;
01235 }
01236 }
01237 break;
01238
01239 case ST_LOWER:
01240 lb[i] = x[i];
01241 if ( bounds.getType( i ) == ST_EQUALITY )
01242 {
01243 ub[i] = x[i];
01244 }
01245 else
01246 {
01247 if ( useRelaxation == BT_TRUE )
01248 ub[i] = x[i] + BOUNDRELAXATION;
01249 }
01250 break;
01251
01252 case ST_UPPER:
01253 ub[i] = x[i];
01254 if ( bounds.getType( i ) == ST_EQUALITY )
01255 {
01256 lb[i] = x[i];
01257 }
01258 else
01259 {
01260 if ( useRelaxation == BT_TRUE )
01261 lb[i] = x[i] - BOUNDRELAXATION;
01262 }
01263 break;
01264
01265 default:
01266 return THROWERROR( RET_UNKNOWN_BUG );
01267 }
01268 }
01269
01270
01271 for ( i=0; i<nC; ++i )
01272 {
01273 switch ( constraints.getStatus( i ) )
01274 {
01275 case ST_INACTIVE:
01276 if ( useRelaxation == BT_TRUE )
01277 {
01278 if ( constraints.getType( i ) == ST_EQUALITY )
01279 {
01280 lbA[i] = Ax[i];
01281 ubA[i] = Ax[i];
01282 }
01283 else
01284 {
01285
01286
01287
01288 if ( auxiliaryConstraints->getStatus( i ) == ST_LOWER )
01289 lbA[i] = Ax[i];
01290 else
01291 lbA[i] = Ax[i] - BOUNDRELAXATION;
01292
01293 if ( auxiliaryConstraints->getStatus( i ) == ST_UPPER )
01294 ubA[i] = Ax[i];
01295 else
01296 ubA[i] = Ax[i] + BOUNDRELAXATION;
01297 }
01298 }
01299 break;
01300
01301 case ST_LOWER:
01302 lbA[i] = Ax[i];
01303 if ( constraints.getType( i ) == ST_EQUALITY )
01304 {
01305 ubA[i] = Ax[i];
01306 }
01307 else
01308 {
01309 if ( useRelaxation == BT_TRUE )
01310 ubA[i] = Ax[i] + BOUNDRELAXATION;
01311 }
01312 break;
01313
01314 case ST_UPPER:
01315 ubA[i] = Ax[i];
01316 if ( constraints.getType( i ) == ST_EQUALITY )
01317 {
01318 lbA[i] = Ax[i];
01319 }
01320 else
01321 {
01322 if ( useRelaxation == BT_TRUE )
01323 lbA[i] = Ax[i] - BOUNDRELAXATION;
01324 }
01325 break;
01326
01327 default:
01328 return THROWERROR( RET_UNKNOWN_BUG );
01329 }
01330 }
01331
01332 return SUCCESSFUL_RETURN;
01333 }
01334
01335
01336
01337
01338
01339 returnValue QProblem::addConstraint( int number, SubjectToStatus C_status,
01340 BooleanType updateCholesky
01341 )
01342 {
01343 int i, j, ii;
01344
01345
01346 if ( constraints.getStatus( number ) != ST_INACTIVE )
01347 return THROWERROR( RET_CONSTRAINT_ALREADY_ACTIVE );
01348
01349 if ( ( constraints.getNC( ) - getNAC( ) ) == constraints.getNUC( ) )
01350 return THROWERROR( RET_ALL_CONSTRAINTS_ACTIVE );
01351
01352 if ( ( getStatus( ) == QPS_NOTINITIALISED ) ||
01353 ( getStatus( ) == QPS_AUXILIARYQPSOLVED ) ||
01354 ( getStatus( ) == QPS_HOMOTOPYQPSOLVED ) ||
01355 ( getStatus( ) == QPS_SOLVED ) )
01356 {
01357 return THROWERROR( RET_UNKNOWN_BUG );
01358 }
01359
01360
01361
01362
01363
01364 if ( updateCholesky == BT_TRUE )
01365 {
01366 returnValue ensureLIreturnvalue = addConstraint_ensureLI( number,C_status );
01367
01368 switch ( ensureLIreturnvalue )
01369 {
01370 case SUCCESSFUL_RETURN:
01371 break;
01372
01373 case RET_LI_RESOLVED:
01374 break;
01375
01376 case RET_ENSURELI_FAILED_NOINDEX:
01377 return THROWERROR( RET_ADDCONSTRAINT_FAILED_INFEASIBILITY );
01378
01379 case RET_ENSURELI_FAILED_CYCLING:
01380 return THROWERROR( RET_ADDCONSTRAINT_FAILED_INFEASIBILITY );
01381
01382 default:
01383 return THROWERROR( RET_ENSURELI_FAILED );
01384 }
01385 }
01386
01387
01388 int nFR = getNFR( );
01389 int nAC = getNAC( );
01390 int nZ = getNZ( );
01391
01392 int tcol = sizeT - nAC;
01393
01394
01395 int FR_idx[NVMAX];
01396 if ( bounds.getFree( )->getNumberArray( FR_idx ) != SUCCESSFUL_RETURN )
01397 return THROWERROR( RET_ADDCONSTRAINT_FAILED );
01398
01399 real_t aFR[NVMAX];
01400 real_t wZ[NVMAX];
01401 for( i=0; i<nZ; ++i )
01402 wZ[i] = 0.0;
01403
01404
01405
01406
01407 for( i=0; i<nFR; ++i )
01408 {
01409 ii = FR_idx[i];
01410 aFR[i] = A[number*NVMAX + ii];
01411 }
01412
01413
01414 for( i=0; i<nFR; ++i )
01415 {
01416 ii = FR_idx[i];
01417 for( j=0; j<nZ; ++j )
01418 wZ[j] += aFR[i] * Q[ii*NVMAX + j];
01419 }
01420
01421
01422 if ( nAC > 0 )
01423 {
01424 for( j=0; j<nAC; ++j )
01425 T[nAC*NVMAX + tcol+j] = 0.0;
01426 for( i=0; i<nFR; ++i )
01427 {
01428 ii = FR_idx[i];
01429 for( j=0; j<nAC; ++j )
01430 T[nAC*NVMAX + tcol+j] += aFR[i] * Q[ii*NVMAX + nZ+j];
01431 }
01432 }
01433
01434
01435 real_t c, s;
01436
01437 if ( nZ > 0 )
01438 {
01439
01440
01441
01442 for( j=0; j<nZ-1; ++j )
01443 {
01444 computeGivens( wZ[j+1],wZ[j], wZ[j+1],wZ[j],c,s );
01445
01446 for( i=0; i<nFR; ++i )
01447 {
01448 ii = FR_idx[i];
01449 applyGivens( c,s,Q[ii*NVMAX + 1+j],Q[ii*NVMAX + j], Q[ii*NVMAX + 1+j],Q[ii*NVMAX + j] );
01450 }
01451
01452 if ( ( updateCholesky == BT_TRUE ) && ( hessianType != HST_IDENTITY ) )
01453 {
01454 for( i=0; i<=j+1; ++i )
01455 applyGivens( c,s,R[i*NVMAX + 1+j],R[i*NVMAX + j], R[i*NVMAX + 1+j],R[i*NVMAX + j] );
01456 }
01457 }
01458
01459 T[nAC*NVMAX + tcol-1] = wZ[nZ-1];
01460
01461
01462 if ( ( updateCholesky == BT_TRUE ) && ( hessianType != HST_IDENTITY ) )
01463 {
01464
01465
01466 for( i=0; i<nZ-1; ++i )
01467 {
01468 computeGivens( R[i*NVMAX + i],R[(1+i)*NVMAX + i], R[i*NVMAX + i],R[(1+i)*NVMAX + i],c,s );
01469
01470 for( j=(1+i); j<(nZ-1); ++j )
01471 applyGivens( c,s,R[i*NVMAX + j],R[(1+i)*NVMAX + j], R[i*NVMAX + j],R[(1+i)*NVMAX + j] );
01472 }
01473
01474 for( i=0; i<nZ; ++i )
01475 R[i*NVMAX + nZ-1] = 0.0;
01476 }
01477 }
01478
01479
01480
01481 if ( constraints.moveInactiveToActive( number,C_status ) != SUCCESSFUL_RETURN )
01482 return THROWERROR( RET_ADDCONSTRAINT_FAILED );
01483
01484
01485 return SUCCESSFUL_RETURN;
01486 }
01487
01488
01489
01490
01491
01492
01493 returnValue QProblem::addConstraint_checkLI( int number )
01494 {
01495 int i, j, jj;
01496 int nFR = getNFR( );
01497 int nZ = getNZ( );
01498
01499 int FR_idx[NVMAX];
01500 if ( bounds.getFree( )->getNumberArray( FR_idx ) != SUCCESSFUL_RETURN )
01501 return THROWERROR( RET_INDEXLIST_CORRUPTED );
01502
01503
01504
01505 real_t sum;
01506
01507 for( i=0; i<nZ; ++i )
01508 {
01509 sum = 0.0;
01510 for( j=0; j<nFR; ++j )
01511 {
01512 jj = FR_idx[j];
01513 sum += Q[jj*NVMAX + i] * A[number*NVMAX + jj];
01514 }
01515
01516 if ( getAbs( sum ) > 10.0*EPS )
01517 return RET_LINEARLY_INDEPENDENT;
01518 }
01519
01520 return RET_LINEARLY_DEPENDENT;
01521 }
01522
01523
01524
01525
01526
01527 returnValue QProblem::addConstraint_ensureLI( int number, SubjectToStatus C_status )
01528 {
01529 int i, j, ii, jj;
01530 int nV = getNV( );
01531 int nFR = getNFR( );
01532 int nFX = getNFX( );
01533 int nAC = getNAC( );
01534 int nZ = getNZ( );
01535
01536
01537
01538 returnValue returnvalueCheckLI = addConstraint_checkLI( number );
01539
01540 if ( returnvalueCheckLI == RET_INDEXLIST_CORRUPTED )
01541 return THROWERROR( RET_ENSURELI_FAILED );
01542
01543 if ( returnvalueCheckLI == RET_LINEARLY_INDEPENDENT )
01544 return SUCCESSFUL_RETURN;
01545
01546
01547
01548
01549
01550
01551
01552 int FR_idx[NVMAX];
01553 if ( bounds.getFree( )->getNumberArray( FR_idx ) != SUCCESSFUL_RETURN )
01554 return THROWERROR( RET_ENSURELI_FAILED );
01555
01556 int FX_idx[NVMAX];
01557 if ( bounds.getFixed( )->getNumberArray( FX_idx ) != SUCCESSFUL_RETURN )
01558 return THROWERROR( RET_ENSURELI_FAILED );
01559
01560 real_t xiC[NCMAX_ALLOC];
01561 real_t xiC_TMP[NCMAX_ALLOC];
01562 real_t xiB[NVMAX];
01563
01564
01565 if ( nAC > 0 )
01566 {
01567 if ( C_status == ST_LOWER )
01568 {
01569 for( i=0; i<nAC; ++i )
01570 {
01571 xiC_TMP[i] = 0.0;
01572 for( j=0; j<nFR; ++j )
01573 {
01574 jj = FR_idx[j];
01575 xiC_TMP[i] += Q[jj*NVMAX + nZ+i] * A[number*NVMAX + jj];
01576 }
01577 }
01578 }
01579 else
01580 {
01581 for( i=0; i<nAC; ++i )
01582 {
01583 xiC_TMP[i] = 0.0;
01584 for( j=0; j<nFR; ++j )
01585 {
01586 jj = FR_idx[j];
01587 xiC_TMP[i] -= Q[jj*NVMAX + nZ+i] * A[number*NVMAX + jj];
01588 }
01589 }
01590 }
01591
01592 if ( backsolveT( xiC_TMP, BT_TRUE, xiC ) != SUCCESSFUL_RETURN )
01593 return THROWERROR( RET_ENSURELI_FAILED_TQ );
01594 }
01595
01596
01597 int AC_idx[NCMAX_ALLOC];
01598 if ( constraints.getActive( )->getNumberArray( AC_idx ) != SUCCESSFUL_RETURN )
01599 return THROWERROR( RET_ENSURELI_FAILED );
01600
01601 if ( C_status == ST_LOWER )
01602 {
01603 for( i=0; i<nFX; ++i )
01604 {
01605 ii = FX_idx[i];
01606 xiB[i] = A[number*NVMAX + ii];
01607
01608 for( j=0; j<nAC; ++j )
01609 {
01610 jj = AC_idx[j];
01611 xiB[i] -= A[jj*NVMAX + ii] * xiC[j];
01612 }
01613 }
01614 }
01615 else
01616 {
01617 for( i=0; i<nFX; ++i )
01618 {
01619 ii = FX_idx[i];
01620 xiB[i] = -A[number*NVMAX + ii];
01621
01622 for( j=0; j<nAC; ++j )
01623 {
01624 jj = AC_idx[j];
01625 xiB[i] -= A[jj*NVMAX + ii] * xiC[j];
01626 }
01627 }
01628 }
01629
01630
01631
01632 real_t y_min = INFTY * INFTY;
01633 int y_min_number = -1;
01634 BooleanType y_min_isBound = BT_FALSE;
01635
01636
01637 for( i=0; i<nAC; ++i )
01638 {
01639 ii = AC_idx[i];
01640
01641 if ( constraints.getStatus( ii ) == ST_LOWER )
01642 {
01643 if ( ( xiC[i] > ZERO ) && ( y[nV+ii] >= 0.0 ) )
01644 {
01645 if ( y[nV+ii]/xiC[i] < y_min )
01646 {
01647 y_min = y[nV+ii]/xiC[i];
01648 y_min_number = ii;
01649 }
01650 }
01651 }
01652 else
01653 {
01654 if ( ( xiC[i] < -ZERO ) && ( y[nV+ii] <= 0.0 ) )
01655 {
01656 if ( y[nV+ii]/xiC[i] < y_min )
01657 {
01658 y_min = y[nV+ii]/xiC[i];
01659 y_min_number = ii;
01660 }
01661 }
01662 }
01663 }
01664
01665
01666 for( i=0; i<nFX; ++i )
01667 {
01668 ii = FX_idx[i];
01669
01670 if ( bounds.getStatus( ii ) == ST_LOWER )
01671 {
01672 if ( ( xiB[i] > ZERO ) && ( y[ii] >= 0.0 ) )
01673 {
01674 if ( y[ii]/xiB[i] < y_min )
01675 {
01676 y_min = y[ii]/xiB[i];
01677 y_min_number = ii;
01678 y_min_isBound = BT_TRUE;
01679 }
01680 }
01681 }
01682 else
01683 {
01684 if ( ( xiB[i] < -ZERO ) && ( y[ii] <= 0.0 ) )
01685 {
01686 if ( y[ii]/xiB[i] < y_min )
01687 {
01688 y_min = y[ii]/xiB[i];
01689 y_min_number = ii;
01690 y_min_isBound = BT_TRUE;
01691 }
01692 }
01693 }
01694 }
01695
01696
01697 #ifdef PC_DEBUG
01698 char messageString[80];
01699 VisibilityStatus visibilityStatus;
01700
01701 if ( printlevel == PL_HIGH )
01702 visibilityStatus = VS_VISIBLE;
01703 else
01704 visibilityStatus = VS_HIDDEN;
01705 #endif
01706
01707
01708
01709 if ( y_min_number >= 0 )
01710 {
01711
01712 if ( ( cyclingManager.getCyclingStatus( number,BT_FALSE ) == CYC_PREV_REMOVED ) &&
01713 ( cyclingManager.getCyclingStatus( y_min_number,y_min_isBound ) == CYC_PREV_ADDED ) )
01714 {
01715 infeasible = BT_TRUE;
01716
01717 return THROWERROR( RET_ENSURELI_FAILED_CYCLING );
01718 }
01719 else
01720 {
01721
01722 cyclingManager.clearCyclingData( );
01723 cyclingManager.setCyclingStatus( number,BT_FALSE, CYC_PREV_ADDED );
01724 cyclingManager.setCyclingStatus( y_min_number,y_min_isBound, CYC_PREV_REMOVED );
01725 }
01726
01727
01728 for( i=0; i<nAC; ++i )
01729 {
01730 ii = AC_idx[i];
01731 y[nV+ii] -= y_min * xiC[i];
01732 }
01733 for( i=0; i<nFX; ++i )
01734 {
01735 ii = FX_idx[i];
01736 y[ii] -= y_min * xiB[i];
01737 }
01738
01739
01740 if ( C_status == ST_LOWER )
01741 y[nV+number] = y_min;
01742 else
01743 y[nV+number] = -y_min;
01744
01745
01746 if ( y_min_isBound == BT_TRUE )
01747 {
01748 #ifdef PC_DEBUG
01749 sprintf( messageString,"bound no. %d.",y_min_number );
01750 getGlobalMessageHandler( )->throwInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNCTION__,__FILE__,__LINE__,visibilityStatus );
01751 #endif
01752
01753 if ( removeBound( y_min_number,BT_TRUE ) != SUCCESSFUL_RETURN )
01754 return THROWERROR( RET_REMOVE_FROM_ACTIVESET_FAILED );
01755
01756 y[y_min_number] = 0.0;
01757 }
01758 else
01759 {
01760 #ifdef PC_DEBUG
01761 sprintf( messageString,"constraint no. %d.",y_min_number );
01762 getGlobalMessageHandler( )->throwInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNCTION__,__FILE__,__LINE__,visibilityStatus );
01763 #endif
01764
01765 if ( removeConstraint( y_min_number,BT_TRUE ) != SUCCESSFUL_RETURN )
01766 return THROWERROR( RET_REMOVE_FROM_ACTIVESET_FAILED );
01767
01768 y[nV+y_min_number] = 0.0;
01769 }
01770 }
01771 else
01772 {
01773
01774 infeasible = BT_TRUE;
01775
01776 return THROWERROR( RET_ENSURELI_FAILED_NOINDEX );
01777 }
01778
01779 return getGlobalMessageHandler( )->throwInfo( RET_LI_RESOLVED,0,__FUNCTION__,__FILE__,__LINE__,VS_HIDDEN );
01780 }
01781
01782
01783
01784
01785
01786
01787 returnValue QProblem::addBound( int number, SubjectToStatus B_status,
01788 BooleanType updateCholesky
01789 )
01790 {
01791 int i, j, ii;
01792
01793
01794 if ( bounds.getStatus( number ) != ST_INACTIVE )
01795 return THROWERROR( RET_BOUND_ALREADY_ACTIVE );
01796
01797 if ( getNFR( ) == bounds.getNUV( ) )
01798 return THROWERROR( RET_ALL_BOUNDS_ACTIVE );
01799
01800 if ( ( getStatus( ) == QPS_NOTINITIALISED ) ||
01801 ( getStatus( ) == QPS_AUXILIARYQPSOLVED ) ||
01802 ( getStatus( ) == QPS_HOMOTOPYQPSOLVED ) ||
01803 ( getStatus( ) == QPS_SOLVED ) )
01804 {
01805 return THROWERROR( RET_UNKNOWN_BUG );
01806 }
01807
01808
01809
01810
01811
01812 if ( updateCholesky == BT_TRUE )
01813 {
01814 returnValue ensureLIreturnvalue = addBound_ensureLI( number,B_status );
01815
01816 switch ( ensureLIreturnvalue )
01817 {
01818 case SUCCESSFUL_RETURN:
01819 break;
01820
01821 case RET_LI_RESOLVED:
01822 break;
01823
01824 case RET_ENSURELI_FAILED_NOINDEX:
01825 return THROWERROR( RET_ADDBOUND_FAILED_INFEASIBILITY );
01826
01827 case RET_ENSURELI_FAILED_CYCLING:
01828 return THROWERROR( RET_ADDBOUND_FAILED_INFEASIBILITY );
01829
01830 default:
01831 return THROWERROR( RET_ENSURELI_FAILED );
01832 }
01833 }
01834
01835
01836
01837 int nFR = getNFR( );
01838 int nAC = getNAC( );
01839 int nZ = getNZ( );
01840
01841 int tcol = sizeT - nAC;
01842
01843
01844
01845
01846 int lastfreenumber = bounds.getFree( )->getLastNumber( );
01847 if ( lastfreenumber != number )
01848 if ( bounds.swapFree( number,lastfreenumber ) != SUCCESSFUL_RETURN )
01849 THROWERROR( RET_ADDBOUND_FAILED );
01850
01851
01852 int FR_idx[NVMAX];
01853 if ( bounds.getFree( )->getNumberArray( FR_idx ) != SUCCESSFUL_RETURN )
01854 return THROWERROR( RET_ADDBOUND_FAILED );
01855
01856 real_t w[NVMAX];
01857
01858
01859
01860
01861 for( i=0; i<nFR; ++i )
01862 w[i] = Q[FR_idx[nFR-1]*NVMAX + i];
01863
01864
01865
01866
01867 real_t c, s;
01868
01869 for( j=0; j<nZ-1; ++j )
01870 {
01871 computeGivens( w[j+1],w[j], w[j+1],w[j],c,s );
01872
01873 for( i=0; i<nFR; ++i )
01874 {
01875 ii = FR_idx[i];
01876 applyGivens( c,s,Q[ii*NVMAX + 1+j],Q[ii*NVMAX + j], Q[ii*NVMAX + 1+j],Q[ii*NVMAX + j] );
01877 }
01878
01879 if ( ( updateCholesky == BT_TRUE ) && ( hessianType != HST_IDENTITY ) )
01880 {
01881 for( i=0; i<=j+1; ++i )
01882 applyGivens( c,s,R[i*NVMAX + 1+j],R[i*NVMAX + j], R[i*NVMAX + 1+j],R[i*NVMAX + j] );
01883 }
01884 }
01885
01886
01887 if ( nAC > 0 )
01888 {
01889
01890 real_t tmp[NCMAX_ALLOC];
01891 for( i=0; i<nAC; ++i )
01892 tmp[i] = 0.0;
01893
01894 {
01895 j = nZ-1;
01896
01897 computeGivens( w[j+1],w[j], w[j+1],w[j],c,s );
01898
01899 for( i=0; i<nFR; ++i )
01900 {
01901 ii = FR_idx[i];
01902 applyGivens( c,s,Q[ii*NVMAX + 1+j],Q[ii*NVMAX + j], Q[ii*NVMAX + 1+j],Q[ii*NVMAX + j] );
01903 }
01904
01905 applyGivens( c,s,T[(nAC-1)*NVMAX + tcol],tmp[nAC-1], tmp[nAC-1],T[(nAC-1)*NVMAX + tcol] );
01906 }
01907
01908 for( j=nZ; j<nFR-1; ++j )
01909 {
01910 computeGivens( w[j+1],w[j], w[j+1],w[j],c,s );
01911
01912 for( i=0; i<nFR; ++i )
01913 {
01914 ii = FR_idx[i];
01915 applyGivens( c,s,Q[ii*NVMAX + 1+j],Q[ii*NVMAX + j], Q[ii*NVMAX + 1+j],Q[ii*NVMAX + j] );
01916 }
01917
01918 for( i=(nFR-2-j); i<nAC; ++i )
01919 applyGivens( c,s,T[i*NVMAX + 1+tcol-nZ+j],tmp[i], tmp[i],T[i*NVMAX + 1+tcol-nZ+j] );
01920 }
01921
01922 }
01923
01924
01925 if ( ( updateCholesky == BT_TRUE ) && ( hessianType != HST_IDENTITY ) )
01926 {
01927
01928
01929 for( i=0; i<nZ-1; ++i )
01930 {
01931 computeGivens( R[i*NVMAX + i],R[(1+i)*NVMAX + i], R[i*NVMAX + i],R[(1+i)*NVMAX + i],c,s );
01932
01933 for( j=(1+i); j<nZ-1; ++j )
01934 applyGivens( c,s,R[i*NVMAX + j],R[(1+i)*NVMAX + j], R[i*NVMAX + j],R[(1+i)*NVMAX + j] );
01935 }
01936
01937 for( i=0; i<nZ; ++i )
01938 R[i*NVMAX + nZ-1] = 0.0;
01939 }
01940
01941
01942
01943 if ( bounds.moveFreeToFixed( number,B_status ) != SUCCESSFUL_RETURN )
01944 return THROWERROR( RET_ADDBOUND_FAILED );
01945
01946 return SUCCESSFUL_RETURN;
01947 }
01948
01949
01950
01951
01952
01953 returnValue QProblem::addBound_checkLI( int number )
01954 {
01955 int i;
01956
01957
01958 int nZ = getNZ( );
01959
01960
01961
01962 for( i=0; i<nZ; ++i )
01963 {
01964 if ( getAbs( Q[number*NVMAX + i] ) > EPS )
01965 return RET_LINEARLY_INDEPENDENT;
01966 }
01967
01968 return RET_LINEARLY_DEPENDENT;
01969 }
01970
01971
01972
01973
01974
01975 returnValue QProblem::addBound_ensureLI( int number, SubjectToStatus B_status )
01976 {
01977 int i, j, ii, jj;
01978 int nV = getNV( );
01979 int nFX = getNFX( );
01980 int nAC = getNAC( );
01981 int nZ = getNZ( );
01982
01983
01984
01985 returnValue returnvalueCheckLI = addBound_checkLI( number );
01986
01987 if ( returnvalueCheckLI == RET_LINEARLY_INDEPENDENT )
01988 return SUCCESSFUL_RETURN;
01989
01990
01991
01992
01993
01994
01995
01996 int FR_idx[NVMAX];
01997 if ( bounds.getFree( )->getNumberArray( FR_idx ) != SUCCESSFUL_RETURN )
01998 return THROWERROR( RET_ENSURELI_FAILED );
01999
02000 int FX_idx[NVMAX];
02001 if ( bounds.getFixed( )->getNumberArray( FX_idx ) != SUCCESSFUL_RETURN )
02002 return THROWERROR( RET_ENSURELI_FAILED );
02003
02004 int AC_idx[NCMAX_ALLOC];
02005 if ( constraints.getActive( )->getNumberArray( AC_idx ) != SUCCESSFUL_RETURN )
02006 return THROWERROR( RET_ENSURELI_FAILED );
02007
02008 real_t xiC[NCMAX_ALLOC];
02009 real_t xiC_TMP[NCMAX_ALLOC];
02010 real_t xiB[NVMAX];
02011
02012
02013 if ( nAC > 0 )
02014 {
02015 if ( B_status == ST_LOWER )
02016 {
02017 for( i=0; i<nAC; ++i )
02018 xiC_TMP[i] = Q[number*NVMAX + nZ+i];
02019 }
02020 else
02021 {
02022 for( i=0; i<nAC; ++i )
02023 xiC_TMP[i] = -Q[number*NVMAX + nZ+i];
02024 }
02025
02026 if ( backsolveT( xiC_TMP, BT_TRUE, xiC ) != SUCCESSFUL_RETURN )
02027 return THROWERROR( RET_ENSURELI_FAILED_TQ );
02028 }
02029
02030
02031 for( i=0; i<nFX; ++i )
02032 {
02033 ii = FX_idx[i];
02034
02035 xiB[i] = 0.0;
02036 for( j=0; j<nAC; ++j )
02037 {
02038 jj = AC_idx[j];
02039 xiB[i] -= A[jj*NVMAX + ii] * xiC[j];
02040 }
02041 }
02042
02043
02044
02045 real_t y_min = INFTY * INFTY;
02046 int y_min_number = -1;
02047 BooleanType y_min_isBound = BT_FALSE;
02048
02049
02050 for( i=0; i<nAC; ++i )
02051 {
02052 ii = AC_idx[i];
02053
02054 if ( constraints.getStatus( ii ) == ST_LOWER )
02055 {
02056 if ( ( xiC[i] > ZERO ) && ( y[nV+ii] >= 0.0 ) )
02057 {
02058 if ( y[nV+ii]/xiC[i] < y_min )
02059 {
02060 y_min = y[nV+ii]/xiC[i];
02061 y_min_number = ii;
02062 }
02063 }
02064 }
02065 else
02066 {
02067 if ( ( xiC[i] < -ZERO ) && ( y[nV+ii] <= 0.0 ) )
02068 {
02069 if ( y[nV+ii]/xiC[i] < y_min )
02070 {
02071 y_min = y[nV+ii]/xiC[i];
02072 y_min_number = ii;
02073 }
02074 }
02075 }
02076 }
02077
02078
02079 for( i=0; i<nFX; ++i )
02080 {
02081 ii = FX_idx[i];
02082
02083 if ( bounds.getStatus( ii ) == ST_LOWER )
02084 {
02085 if ( ( xiB[i] > ZERO ) && ( y[ii] >= 0.0 ) )
02086 {
02087 if ( y[ii]/xiB[i] < y_min )
02088 {
02089 y_min = y[ii]/xiB[i];
02090 y_min_number = ii;
02091 y_min_isBound = BT_TRUE;
02092 }
02093 }
02094 }
02095 else
02096 {
02097 if ( ( xiB[i] < -ZERO ) && ( y[ii] <= 0.0 ) )
02098 {
02099 if ( y[ii]/xiB[i] < y_min )
02100 {
02101 y_min = y[ii]/xiB[i];
02102 y_min_number = ii;
02103 y_min_isBound = BT_TRUE;
02104 }
02105 }
02106 }
02107 }
02108
02109
02110 #ifdef PC_DEBUG
02111 char messageString[80];
02112 VisibilityStatus visibilityStatus;
02113
02114 if ( printlevel == PL_HIGH )
02115 visibilityStatus = VS_VISIBLE;
02116 else
02117 visibilityStatus = VS_HIDDEN;
02118 #endif
02119
02120
02121
02122 if ( y_min_number >= 0 )
02123 {
02124
02125 if ( ( cyclingManager.getCyclingStatus( number,BT_TRUE ) == CYC_PREV_REMOVED ) &&
02126 ( cyclingManager.getCyclingStatus( y_min_number,y_min_isBound ) == CYC_PREV_ADDED ) )
02127 {
02128 infeasible = BT_TRUE;
02129
02130 return THROWERROR( RET_ENSURELI_FAILED_CYCLING );
02131 }
02132 else
02133 {
02134
02135 cyclingManager.clearCyclingData( );
02136 cyclingManager.setCyclingStatus( number,BT_TRUE, CYC_PREV_ADDED );
02137 cyclingManager.setCyclingStatus( y_min_number,y_min_isBound, CYC_PREV_REMOVED );
02138 }
02139
02140
02141
02142 for( i=0; i<nAC; ++i )
02143 {
02144 ii = AC_idx[i];
02145 y[nV+ii] -= y_min * xiC[i];
02146 }
02147 for( i=0; i<nFX; ++i )
02148 {
02149 ii = FX_idx[i];
02150 y[ii] -= y_min * xiB[i];
02151 }
02152
02153
02154 if ( B_status == ST_LOWER )
02155 y[number] = y_min;
02156 else
02157 y[number] = -y_min;
02158
02159
02160 if ( y_min_isBound == BT_TRUE )
02161 {
02162 #ifdef PC_DEBUG
02163 sprintf( messageString,"bound no. %d.",y_min_number );
02164 getGlobalMessageHandler( )->throwInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNCTION__,__FILE__,__LINE__,visibilityStatus );
02165 #endif
02166
02167 if ( removeBound( y_min_number,BT_TRUE ) != SUCCESSFUL_RETURN )
02168 return THROWERROR( RET_REMOVE_FROM_ACTIVESET_FAILED );
02169
02170 y[y_min_number] = 0.0;
02171 }
02172 else
02173 {
02174 #ifdef PC_DEBUG
02175 sprintf( messageString,"constraint no. %d.",y_min_number );
02176 getGlobalMessageHandler( )->throwInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNCTION__,__FILE__,__LINE__,visibilityStatus );
02177 #endif
02178
02179 if ( removeConstraint( y_min_number,BT_TRUE ) != SUCCESSFUL_RETURN )
02180 return THROWERROR( RET_REMOVE_FROM_ACTIVESET_FAILED );
02181
02182 y[nV+y_min_number] = 0.0;
02183 }
02184 }
02185 else
02186 {
02187
02188 infeasible = BT_TRUE;
02189
02190 return THROWERROR( RET_ENSURELI_FAILED_NOINDEX );
02191 }
02192
02193 return getGlobalMessageHandler( )->throwInfo( RET_LI_RESOLVED,0,__FUNCTION__,__FILE__,__LINE__,VS_HIDDEN );
02194 }
02195
02196
02197
02198
02199
02200
02201 returnValue QProblem::removeConstraint( int number,
02202 BooleanType updateCholesky
02203 )
02204 {
02205 int i, j, ii, jj;
02206
02207
02208 if ( ( getStatus( ) == QPS_NOTINITIALISED ) ||
02209 ( getStatus( ) == QPS_AUXILIARYQPSOLVED ) ||
02210 ( getStatus( ) == QPS_HOMOTOPYQPSOLVED ) ||
02211 ( getStatus( ) == QPS_SOLVED ) )
02212 {
02213 return THROWERROR( RET_UNKNOWN_BUG );
02214 }
02215
02216
02217 int nFR = getNFR( );
02218 int nAC = getNAC( );
02219 int nZ = getNZ( );
02220
02221 int tcol = sizeT - nAC;
02222 int number_idx = constraints.getActive( )->getIndex( number );
02223
02224
02225
02226 if ( constraints.getStatus( number ) == ST_INACTIVE )
02227 return THROWERROR( RET_CONSTRAINT_NOT_ACTIVE );
02228
02229 if ( ( number_idx < 0 ) || ( number_idx >= nAC ) )
02230 return THROWERROR( RET_CONSTRAINT_NOT_ACTIVE );
02231
02232
02233 int FR_idx[NVMAX];
02234 if ( bounds.getFree( )->getNumberArray( FR_idx ) != SUCCESSFUL_RETURN )
02235 return THROWERROR( RET_REMOVECONSTRAINT_FAILED );
02236
02237
02238
02239
02240
02241 if ( number_idx < nAC-1 )
02242 {
02243 for( i=(number_idx+1); i<nAC; ++i )
02244 for( j=(nAC-i-1); j<nAC; ++j )
02245 T[(i-1)*NVMAX + tcol+j] = T[i*NVMAX + tcol+j];
02246
02247 for( j=0; j<nAC; ++j )
02248 T[(nAC-1)*NVMAX + tcol+j] = 0.0;
02249
02250
02251
02252
02253
02254 real_t c, s;
02255
02256 for( j=(nAC-2-number_idx); j>=0; --j )
02257 {
02258 computeGivens( T[(nAC-2-j)*NVMAX + tcol+1+j],T[(nAC-2-j)*NVMAX + tcol+j], T[(nAC-2-j)*NVMAX + tcol+1+j],T[(nAC-2-j)*NVMAX + tcol+j],c,s );
02259
02260 for( i=(nAC-j-1); i<(nAC-1); ++i )
02261 applyGivens( c,s,T[i*NVMAX + tcol+1+j],T[i*NVMAX + tcol+j], T[i*NVMAX + tcol+1+j],T[i*NVMAX + tcol+j] );
02262
02263 for( i=0; i<nFR; ++i )
02264 {
02265 ii = FR_idx[i];
02266 applyGivens( c,s,Q[ii*NVMAX + nZ+1+j],Q[ii*NVMAX + nZ+j], Q[ii*NVMAX + nZ+1+j],Q[ii*NVMAX + nZ+j] );
02267 }
02268 }
02269 }
02270 else
02271 {
02272
02273 for( j=0; j<nAC; ++j )
02274 T[(nAC-1)*NVMAX + tcol+j] = 0.0;
02275 }
02276
02277
02278 if ( ( updateCholesky == BT_TRUE ) && ( hessianType != HST_IDENTITY ) )
02279 {
02280
02281
02282
02283 real_t Hz[NVMAX];
02284 for ( i=0; i<nFR; ++i )
02285 Hz[i] = 0.0;
02286 real_t rho2 = 0.0;
02287
02288
02289
02290 for( j=0; j<nFR; ++j )
02291 {
02292 jj = FR_idx[j];
02293 for( i=0; i<nFR; ++i )
02294 Hz[i] += H[jj*NVMAX + FR_idx[i]] * Q[jj*NVMAX + nZ];
02295 }
02296
02297 if ( nZ > 0 )
02298 {
02299 real_t ZHz[NVMAX];
02300 for ( i=0; i<nZ; ++i )
02301 ZHz[i] = 0.0;
02302 real_t r[NVMAX];
02303
02304
02305 for( j=0; j<nFR; ++j )
02306 {
02307 jj = FR_idx[j];
02308
02309 for( i=0; i<nZ; ++i )
02310 ZHz[i] += Q[jj*NVMAX + i] * Hz[j];
02311 }
02312
02313
02314 if ( backsolveR( ZHz,BT_TRUE,r ) != SUCCESSFUL_RETURN )
02315 return THROWERROR( RET_REMOVECONSTRAINT_FAILED );
02316
02317
02318
02319 for( i=0; i<nZ; ++i )
02320 {
02321 rho2 -= r[i]*r[i];
02322 R[i*NVMAX + nZ] = r[i];
02323 }
02324 }
02325
02326 for( j=0; j<nFR; ++j )
02327 rho2 += Q[FR_idx[j]*NVMAX + nZ] * Hz[j];
02328
02329
02330 if ( rho2 > 0.0 )
02331 R[nZ*NVMAX + nZ] = sqrt( rho2 );
02332 else
02333 {
02334 hessianType = HST_SEMIDEF;
02335 return THROWERROR( RET_HESSIAN_NOT_SPD );
02336 }
02337 }
02338
02339
02340 if ( constraints.moveActiveToInactive( number ) != SUCCESSFUL_RETURN )
02341 return THROWERROR( RET_REMOVECONSTRAINT_FAILED );
02342
02343
02344 return SUCCESSFUL_RETURN;
02345 }
02346
02347
02348
02349
02350
02351 returnValue QProblem::removeBound( int number,
02352 BooleanType updateCholesky
02353 )
02354 {
02355 int i, j, ii, jj;
02356
02357
02358 if ( bounds.getStatus( number ) == ST_INACTIVE )
02359 return THROWERROR( RET_BOUND_NOT_ACTIVE );
02360
02361 if ( ( getStatus( ) == QPS_NOTINITIALISED ) ||
02362 ( getStatus( ) == QPS_AUXILIARYQPSOLVED ) ||
02363 ( getStatus( ) == QPS_HOMOTOPYQPSOLVED ) ||
02364 ( getStatus( ) == QPS_SOLVED ) )
02365 {
02366 return THROWERROR( RET_UNKNOWN_BUG );
02367 }
02368
02369
02370 int nFR = getNFR( );
02371 int nAC = getNAC( );
02372 int nZ = getNZ( );
02373
02374 int tcol = sizeT - nAC;
02375
02376
02377
02378 if ( bounds.moveFixedToFree( number ) != SUCCESSFUL_RETURN )
02379 return THROWERROR( RET_REMOVEBOUND_FAILED );
02380
02381
02382 int FR_idx[NVMAX];
02383 if ( bounds.getFree( )->getNumberArray( FR_idx ) != SUCCESSFUL_RETURN )
02384 return THROWERROR( RET_REMOVEBOUND_FAILED );
02385
02386
02387 int nnFRp1 = FR_idx[nFR];
02388 for( i=0; i<nFR; ++i )
02389 {
02390 ii = FR_idx[i];
02391 Q[ii*NVMAX + nFR] = 0.0;
02392 Q[nnFRp1*NVMAX + i] = 0.0;
02393 }
02394 Q[nnFRp1*NVMAX + nFR] = 1.0;
02395
02396 if ( nAC > 0 )
02397 {
02398
02399 int AC_idx[NCMAX_ALLOC];
02400 if ( constraints.getActive( )->getNumberArray( AC_idx ) != SUCCESSFUL_RETURN )
02401 return THROWERROR( RET_REMOVEBOUND_FAILED );
02402
02403 real_t tmp[NCMAX_ALLOC];
02404 for( i=0; i<nAC; ++i )
02405 {
02406 ii = AC_idx[i];
02407 tmp[i] = A[ii*NVMAX + number];
02408 }
02409
02410
02411
02412
02413
02414 real_t c, s;
02415
02416 for( j=(nAC-1); j>=0; --j )
02417 {
02418 computeGivens( tmp[nAC-1-j],T[(nAC-1-j)*NVMAX + tcol+j],T[(nAC-1-j)*NVMAX + tcol+j],tmp[nAC-1-j],c,s );
02419
02420 for( i=(nAC-j); i<nAC; ++i )
02421 applyGivens( c,s,tmp[i],T[i*NVMAX + tcol+j],T[i*NVMAX + tcol+j],tmp[i] );
02422
02423 for( i=0; i<=nFR; ++i )
02424 {
02425 ii = FR_idx[i];
02426
02427 applyGivens( c,s,Q[ii*NVMAX + nZ+1+j],Q[ii*NVMAX + nZ+j],Q[ii*NVMAX + nZ+1+j],Q[ii*NVMAX + nZ+j] );
02428 }
02429 }
02430 }
02431
02432
02433 if ( ( updateCholesky == BT_TRUE ) && ( hessianType != HST_IDENTITY ) )
02434 {
02435
02436
02437
02438 real_t z2 = Q[nnFRp1*NVMAX + nZ];
02439 real_t rho2 = H[nnFRp1*NVMAX + nnFRp1]*z2*z2;
02440
02441 if ( nFR > 0 )
02442 {
02443 real_t Hz[NVMAX];
02444 for( i=0; i<nFR; ++i )
02445 Hz[i] = 0.0;
02446
02447
02448 for( j=0; j<nFR; ++j )
02449 {
02450 jj = FR_idx[j];
02451 for( i=0; i<nFR; ++i )
02452 {
02453 ii = FR_idx[i];
02454
02455 Hz[i] += H[jj*NVMAX + ii] * Q[jj*NVMAX + nZ];
02456 }
02457 }
02458
02459 if ( nZ > 0 )
02460 {
02461 real_t r[NVMAX];
02462 real_t rhs[NVMAX];
02463 for( i=0; i<nZ; ++i )
02464 rhs[i] = 0.0;
02465
02466
02467 for( j=0; j<nFR; ++j )
02468 {
02469 jj = FR_idx[j];
02470 for( i=0; i<nZ; ++i )
02471
02472 rhs[i] += Q[jj*NVMAX + i] * ( Hz[j] + z2 * H[nnFRp1*NVMAX + jj] );
02473 }
02474
02475
02476 if ( backsolveR( rhs,BT_TRUE,BT_TRUE,r ) != SUCCESSFUL_RETURN )
02477 return THROWERROR( RET_REMOVEBOUND_FAILED );
02478
02479
02480
02481 for( i=0; i<nZ; ++i )
02482 {
02483 rho2 -= r[i]*r[i];
02484 R[i*NVMAX + nZ] = r[i];
02485 }
02486 }
02487
02488 for( j=0; j<nFR; ++j )
02489 {
02490 jj = FR_idx[j];
02491
02492 rho2 += Q[jj*NVMAX + nZ] * ( Hz[j] + 2.0*z2*H[nnFRp1*NVMAX + jj] );
02493 }
02494 }
02495
02496
02497
02498 if ( rho2 > 0.0 )
02499 R[nZ*NVMAX + nZ] = sqrt( rho2 );
02500 else
02501 {
02502 hessianType = HST_SEMIDEF;
02503 return THROWERROR( RET_HESSIAN_NOT_SPD );
02504 }
02505 }
02506
02507 return SUCCESSFUL_RETURN;
02508 }
02509
02510
02511
02512
02513
02514 returnValue QProblem::backsolveR( const real_t* const b, BooleanType transposed,
02515 real_t* const a
02516 )
02517 {
02518
02519 return backsolveR( b,transposed,BT_FALSE,a );
02520 }
02521
02522
02523
02524
02525
02526 returnValue QProblem::backsolveR( const real_t* const b, BooleanType transposed,
02527 BooleanType removingBound,
02528 real_t* const a
02529 )
02530 {
02531 int i, j;
02532 int nR = getNZ( );
02533
02534 real_t sum;
02535
02536
02537 if ( removingBound == BT_TRUE )
02538 --nR;
02539
02540
02541 if ( nR <= 0 )
02542 return SUCCESSFUL_RETURN;
02543
02544
02545
02546 if ( transposed == BT_FALSE )
02547 {
02548
02549 for( i=(nR-1); i>=0; --i )
02550 {
02551 sum = b[i];
02552 for( j=(i+1); j<nR; ++j )
02553 sum -= R[i*NVMAX + j] * a[j];
02554
02555 if ( getAbs( R[i*NVMAX + i] ) > ZERO )
02556 a[i] = sum / R[i*NVMAX + i];
02557 else
02558 return THROWERROR( RET_DIV_BY_ZERO );
02559 }
02560 }
02561 else
02562 {
02563
02564 for( i=0; i<nR; ++i )
02565 {
02566 sum = b[i];
02567
02568 for( j=0; j<i; ++j )
02569 sum -= R[j*NVMAX + i] * a[j];
02570
02571 if ( getAbs( R[i*NVMAX + i] ) > ZERO )
02572 a[i] = sum / R[i*NVMAX + i];
02573 else
02574 return THROWERROR( RET_DIV_BY_ZERO );
02575 }
02576 }
02577
02578 return SUCCESSFUL_RETURN;
02579 }
02580
02581
02582
02583
02584
02585
02586 returnValue QProblem::backsolveT( const real_t* const b, BooleanType transposed, real_t* const a )
02587 {
02588 int i, j;
02589 int nT = getNAC( );
02590 int tcol = sizeT - nT;
02591
02592 real_t sum;
02593
02594
02595 if ( nT <= 0 )
02596 return SUCCESSFUL_RETURN;
02597
02598
02599
02600 if ( transposed == BT_FALSE )
02601 {
02602
02603 for( i=0; i<nT; ++i )
02604 {
02605 sum = b[i];
02606 for( j=0; j<i; ++j )
02607 sum -= T[i*NVMAX + sizeT-1-j] * a[nT-1-j];
02608
02609 if ( getAbs( T[i*NVMAX + sizeT-1-i] ) > ZERO )
02610 a[nT-1-i] = sum / T[i*NVMAX + sizeT-1-i];
02611 else
02612 return THROWERROR( RET_DIV_BY_ZERO );
02613 }
02614 }
02615 else
02616 {
02617
02618 for( i=0; i<nT; ++i )
02619 {
02620 sum = b[i];
02621 for( j=0; j<i; ++j )
02622 sum -= T[(nT-1-j)*NVMAX + tcol+i] * a[nT-1-j];
02623
02624 if ( getAbs( T[(nT-1-i)*NVMAX + tcol+i] ) > ZERO )
02625 a[nT-1-i] = sum / T[(nT-1-i)*NVMAX + tcol+i];
02626 else
02627 return THROWERROR( RET_DIV_BY_ZERO );
02628 }
02629 }
02630
02631
02632 return SUCCESSFUL_RETURN;
02633 }
02634
02635
02636
02637
02638
02639 returnValue QProblem::hotstart_determineDataShift( const int* const FX_idx, const int* const AC_idx,
02640 const real_t* const g_new, const real_t* const lbA_new, const real_t* const ubA_new,
02641 const real_t* const lb_new, const real_t* const ub_new,
02642 real_t* const delta_g, real_t* const delta_lbA, real_t* const delta_ubA,
02643 real_t* const delta_lb, real_t* const delta_ub,
02644 BooleanType& Delta_bC_isZero, BooleanType& Delta_bB_isZero
02645 )
02646 {
02647 int i, ii;
02648 int nC = getNC( );
02649 int nAC = getNAC( );
02650
02651
02652
02653 QProblemB::hotstart_determineDataShift( FX_idx,g_new,lb_new,ub_new, delta_g,delta_lb,delta_ub, Delta_bB_isZero );
02654
02655
02656
02657
02658 for( i=0; i<nC; ++i )
02659 {
02660
02661 if ( lbA_new != 0 )
02662 delta_lbA[i] = lbA_new[i] - lbA[i];
02663 else
02664 delta_lbA[i] = -INFTY - lbA[i];
02665 }
02666
02667 for( i=0; i<nC; ++i )
02668 {
02669
02670 if ( ubA_new != 0 )
02671 delta_ubA[i] = ubA_new[i] - ubA[i];
02672 else
02673 delta_ubA[i] = INFTY - ubA[i];
02674 }
02675
02676
02677 Delta_bC_isZero = BT_TRUE;
02678
02679 for ( i=0; i<nAC; ++i )
02680 {
02681 ii = AC_idx[i];
02682
02683 if ( ( getAbs( delta_lbA[ii] ) > EPS ) || ( getAbs( delta_ubA[ii] ) > EPS ) )
02684 {
02685 Delta_bC_isZero = BT_FALSE;
02686 break;
02687 }
02688 }
02689
02690 return SUCCESSFUL_RETURN;
02691 }
02692
02693
02694
02695
02696
02697 returnValue QProblem::hotstart_determineStepDirection( const int* const FR_idx, const int* const FX_idx, const int* const AC_idx,
02698 const real_t* const delta_g, const real_t* const delta_lbA, const real_t* const delta_ubA,
02699 const real_t* const delta_lb, const real_t* const delta_ub,
02700 BooleanType Delta_bC_isZero, BooleanType Delta_bB_isZero,
02701 real_t* const delta_xFX, real_t* const delta_xFR,
02702 real_t* const delta_yAC, real_t* const delta_yFX
02703 )
02704 {
02705 int i, j, ii, jj;
02706 int nFR = getNFR( );
02707 int nFX = getNFX( );
02708 int nAC = getNAC( );
02709 int nZ = getNZ( );
02710
02711
02712 real_t HMX_delta_xFX[NVMAX];
02713 real_t YFR_delta_xFRy[NVMAX];
02714 real_t ZFR_delta_xFRz[NVMAX];
02715 real_t HFR_YFR_delta_xFRy[NVMAX];
02716 for( i=0; i<nFR; ++i )
02717 {
02718 delta_xFR[i] = 0.0;
02719 HMX_delta_xFX[i] = 0.0;
02720 YFR_delta_xFRy[i] = 0.0;
02721 ZFR_delta_xFRz[i] = 0.0;
02722 HFR_YFR_delta_xFRy[i] = 0.0;
02723 }
02724
02725 real_t delta_xFRy[NCMAX_ALLOC];
02726 real_t delta_xFRz[NVMAX];
02727 for( i=0; i<nZ; ++i )
02728 delta_xFRz[i] = 0.0;
02729
02730
02731
02732 if ( nFX > 0 )
02733 {
02734 for( i=0; i<nFX; ++i )
02735 {
02736 ii = FX_idx[i];
02737
02738 if ( bounds.getStatus( ii ) == ST_LOWER )
02739 delta_xFX[i] = delta_lb[ii];
02740 else
02741 delta_xFX[i] = delta_ub[ii];
02742 }
02743 }
02744
02745
02746 if ( nFR > 0 )
02747 {
02748
02749 if ( nAC > 0 )
02750 {
02751 if ( ( Delta_bC_isZero == BT_TRUE ) && ( Delta_bB_isZero == BT_TRUE ) )
02752 {
02753 for( i=0; i<nAC; ++i )
02754 delta_xFRy[i] = 0.0;
02755
02756 for( i=0; i<nFR; ++i )
02757 delta_xFR[i] = 0.0;
02758 }
02759 else
02760 {
02761
02762 real_t delta_xFRy_TMP[NCMAX_ALLOC];
02763
02764 for( i=0; i<nAC; ++i )
02765 {
02766 ii = AC_idx[i];
02767
02768 if ( constraints.getStatus( ii ) == ST_LOWER )
02769 delta_xFRy_TMP[i] = delta_lbA[ii];
02770 else
02771 delta_xFRy_TMP[i] = delta_ubA[ii];
02772
02773 if ( Delta_bB_isZero == BT_FALSE )
02774 {
02775 for( j=0; j<nFX; ++j )
02776 {
02777 jj = FX_idx[j];
02778 delta_xFRy_TMP[i] -= A[ii*NVMAX + jj] * delta_xFX[j];
02779 }
02780 }
02781 }
02782
02783 if ( backsolveT( delta_xFRy_TMP, BT_FALSE, delta_xFRy ) != SUCCESSFUL_RETURN )
02784 return THROWERROR( RET_STEPDIRECTION_FAILED_TQ );
02785
02786 for( i=0; i<nFR; ++i )
02787 {
02788 ii = FR_idx[i];
02789 for( j=0; j<nAC; ++j )
02790 YFR_delta_xFRy[i] += Q[ii*NVMAX + nZ+j] * delta_xFRy[j];
02791
02792
02793 delta_xFR[i] = YFR_delta_xFRy[i];
02794 }
02795 }
02796 }
02797
02798
02799 if ( hessianType == HST_IDENTITY )
02800 {
02801 for( j=0; j<nFR; ++j )
02802 {
02803 jj = FR_idx[j];
02804 for( i=0; i<nZ; ++i )
02805 delta_xFRz[i] -= Q[jj*NVMAX + i] * delta_g[jj];
02806 }
02807
02808 if ( nZ > 0 )
02809 {
02810 for( i=0; i<nFR; ++i )
02811 {
02812 ii = FR_idx[i];
02813 for( j=0; j<nZ; ++j )
02814 ZFR_delta_xFRz[i] += Q[ii*NVMAX + j] * delta_xFRz[j];
02815
02816 delta_xFR[i] += ZFR_delta_xFRz[i];
02817 }
02818 }
02819 }
02820 else
02821 {
02822 if ( Delta_bB_isZero == BT_FALSE )
02823 {
02824 for( i=0; i<nFR; ++i )
02825 {
02826 ii = FR_idx[i];
02827 for( j=0; j<nFX; ++j )
02828 {
02829 jj = FX_idx[j];
02830 HMX_delta_xFX[i] += H[ii*NVMAX + jj] * delta_xFX[j];
02831 }
02832 }
02833 }
02834
02835 if ( nAC > 0 )
02836 {
02837 if ( ( Delta_bC_isZero == BT_FALSE ) || ( Delta_bB_isZero == BT_FALSE ) )
02838 {
02839 for( i=0; i<nFR; ++i )
02840 {
02841 ii = FR_idx[i];
02842 for( j=0; j<nFR; ++j )
02843 {
02844 jj = FR_idx[j];
02845 HFR_YFR_delta_xFRy[i] += H[ii*NVMAX + jj] * YFR_delta_xFRy[j];
02846 }
02847 }
02848 }
02849 }
02850
02851
02852 if ( nZ > 0 )
02853 {
02854
02855 real_t delta_xFRz_TMP[NVMAX];
02856 real_t delta_xFRz_RHS[NVMAX];
02857
02858
02859 if ( ( nAC > 0 ) && ( nFX > 0 ) && ( Delta_bB_isZero == BT_FALSE ) )
02860 {
02861 for( j=0; j<nFR; ++j )
02862 {
02863 jj = FR_idx[j];
02864 delta_xFRz_RHS[j] = delta_g[jj] + HFR_YFR_delta_xFRy[j] + HMX_delta_xFX[j];
02865 }
02866 }
02867 else
02868 {
02869 if ( ( nAC == 0 ) && ( Delta_bB_isZero == BT_TRUE ) )
02870 {
02871 for( j=0; j<nFR; ++j )
02872 {
02873 jj = FR_idx[j];
02874 delta_xFRz_RHS[j] = delta_g[jj];
02875 }
02876 }
02877 else
02878 {
02879 if ( nAC > 0 )
02880 {
02881 for( j=0; j<nFR; ++j )
02882 {
02883 jj = FR_idx[j];
02884 delta_xFRz_RHS[j] = delta_g[jj] + HFR_YFR_delta_xFRy[j];
02885 }
02886 }
02887 else
02888 {
02889 for( j=0; j<nFR; ++j )
02890 {
02891 jj = FR_idx[j];
02892 delta_xFRz_RHS[j] = delta_g[jj] + HMX_delta_xFX[j];
02893 }
02894 }
02895 }
02896 }
02897
02898 for( j=0; j<nFR; ++j )
02899 {
02900 jj = FR_idx[j];
02901 for( i=0; i<nZ; ++i )
02902 delta_xFRz[i] -= Q[jj*NVMAX + i] * delta_xFRz_RHS[j];
02903 }
02904
02905
02906 if ( backsolveR( delta_xFRz,BT_TRUE,delta_xFRz_TMP ) != SUCCESSFUL_RETURN )
02907 return THROWERROR( RET_STEPDIRECTION_FAILED_CHOLESKY );
02908
02909 if ( backsolveR( delta_xFRz_TMP,BT_FALSE,delta_xFRz ) != SUCCESSFUL_RETURN )
02910 return THROWERROR( RET_STEPDIRECTION_FAILED_CHOLESKY );
02911
02912
02913 for( i=0; i<nFR; ++i )
02914 {
02915 ii = FR_idx[i];
02916 for( j=0; j<nZ; ++j )
02917 ZFR_delta_xFRz[i] += Q[ii*NVMAX + j] * delta_xFRz[j];
02918
02919 delta_xFR[i] += ZFR_delta_xFRz[i];
02920 }
02921 }
02922 }
02923 }
02924
02925
02926 if ( nAC > 0 )
02927 {
02928
02929 real_t delta_yAC_TMP[NCMAX_ALLOC];
02930 for( i=0; i<nAC; ++i )
02931 delta_yAC_TMP[i] = 0.0;
02932 real_t delta_yAC_RHS[NVMAX];
02933 for( i=0; i<nFR; ++i )
02934 delta_yAC_RHS[i] = 0.0;
02935
02936 if ( hessianType == HST_IDENTITY )
02937 {
02938
02939 for( j=0; j<nAC; ++j )
02940 {
02941 for( i=0; i<nFR; ++i )
02942 {
02943 ii = FR_idx[i];
02944 delta_yAC_TMP[j] += Q[ii*NVMAX + nZ+j] * delta_g[ii];
02945 }
02946
02947 delta_yAC_TMP[j] += delta_xFRy[j];
02948 }
02949 }
02950 else
02951 {
02952 if ( ( Delta_bC_isZero == BT_TRUE ) && ( Delta_bB_isZero == BT_TRUE ) )
02953 {
02954 for( i=0; i<nFR; ++i )
02955 {
02956 ii = FR_idx[i];
02957 delta_yAC_RHS[i] = delta_g[ii];
02958 }
02959 }
02960 else
02961 {
02962 for( i=0; i<nFR; ++i )
02963 {
02964 ii = FR_idx[i];
02965 delta_yAC_RHS[i] = HFR_YFR_delta_xFRy[i] + delta_g[ii];
02966 }
02967 }
02968
02969 if ( nZ > 0 )
02970 {
02971 for( i=0; i<nFR; ++i )
02972 {
02973 ii = FR_idx[i];
02974 for( j=0; j<nFR; ++j )
02975 {
02976 jj = FR_idx[j];
02977 delta_yAC_RHS[i] += H[ii*NVMAX + jj] * ZFR_delta_xFRz[j];
02978 }
02979 }
02980 }
02981
02982 if ( nFX > 0 )
02983 {
02984 if ( Delta_bB_isZero == BT_FALSE )
02985 {
02986 for( i=0; i<nFR; ++i )
02987 delta_yAC_RHS[i] += HMX_delta_xFX[i];
02988 }
02989 }
02990
02991 for( i=0; i<nAC; ++i)
02992 {
02993 for( j=0; j<nFR; ++j )
02994 {
02995 jj = FR_idx[j];
02996 delta_yAC_TMP[i] += Q[jj*NVMAX + nZ+i] * delta_yAC_RHS[j];
02997 }
02998 }
02999 }
03000
03001 if ( backsolveT( delta_yAC_TMP,BT_TRUE,delta_yAC ) != SUCCESSFUL_RETURN )
03002 return THROWERROR( RET_STEPDIRECTION_FAILED_TQ );
03003 }
03004
03005
03006
03007 if ( nFX > 0 )
03008 {
03009 for( i=0; i<nFX; ++i )
03010 {
03011 ii = FX_idx[i];
03012
03013 delta_yFX[i] = delta_g[ii];
03014
03015 for( j=0; j<nAC; ++j )
03016 {
03017 jj = AC_idx[j];
03018 delta_yFX[i] -= A[jj*NVMAX + ii] * delta_yAC[j];
03019 }
03020
03021 if ( hessianType == HST_IDENTITY )
03022 {
03023 delta_yFX[i] += delta_xFX[i];
03024 }
03025 else
03026 {
03027 for( j=0; j<nFR; ++j )
03028 {
03029 jj = FR_idx[j];
03030 delta_yFX[i] += H[ii*NVMAX + jj] * delta_xFR[j];
03031 }
03032
03033 if ( Delta_bB_isZero == BT_FALSE )
03034 {
03035 for( j=0; j<nFX; ++j )
03036 {
03037 jj = FX_idx[j];
03038 delta_yFX[i] += H[ii*NVMAX + jj] * delta_xFX[j];
03039 }
03040 }
03041 }
03042 }
03043 }
03044
03045 return SUCCESSFUL_RETURN;
03046 }
03047
03048
03049
03050
03051
03052 returnValue QProblem::hotstart_determineStepLength( const int* const FR_idx, const int* const FX_idx, const int* const AC_idx, const int* const IAC_idx,
03053 const real_t* const delta_lbA, const real_t* const delta_ubA,
03054 const real_t* const delta_lb, const real_t* const delta_ub,
03055 const real_t* const delta_xFX, const real_t* const delta_xFR,
03056 const real_t* const delta_yAC, const real_t* const delta_yFX,
03057 real_t* const delta_Ax, int& BC_idx, SubjectToStatus& BC_status, BooleanType& BC_isBound
03058 )
03059 {
03060 int i, j, ii, jj;
03061 int nV = getNV( );
03062 int nC = getNC( );
03063 int nFR = getNFR( );
03064 int nFX = getNFX( );
03065 int nAC = getNAC( );
03066 int nIAC = getNIAC( );
03067
03068
03069 real_t maxStepLength[2*(NVMAX+NCMAX_ALLOC)];
03070 for ( i=0; i<2*(nV+nC); ++i )
03071 maxStepLength[i] = 1.0;
03072
03073
03074
03075
03076
03077 for( i=0; i<nAC; ++i )
03078 {
03079 ii = AC_idx[i];
03080
03081 if ( constraints.getType( ii ) != ST_EQUALITY )
03082 {
03083 if ( constraints.getStatus( ii ) == ST_LOWER )
03084 {
03085
03086 if ( delta_yAC[i] < -ZERO )
03087 {
03088 if ( y[nV+ii] > 0.0 )
03089 maxStepLength[nV+ii] = y[nV+ii] / ( -delta_yAC[i] );
03090 else
03091 maxStepLength[nV+ii] = 0.0;
03092 }
03093 }
03094 else
03095 {
03096
03097 if ( delta_yAC[i] > ZERO )
03098 {
03099 if ( y[nV+ii] < 0.0 )
03100 maxStepLength[nV+ii] = y[nV+ii] / ( -delta_yAC[i] );
03101 else
03102 maxStepLength[nV+ii] = 0.0;
03103 }
03104 }
03105 }
03106 }
03107
03108
03109
03110 for( i=0; i<nFX; ++i )
03111 {
03112 ii = FX_idx[i];
03113
03114 if ( bounds.getType( ii ) != ST_EQUALITY )
03115 {
03116 if ( bounds.getStatus( ii ) == ST_LOWER )
03117 {
03118
03119 if ( delta_yFX[i] < -ZERO )
03120 {
03121 if ( y[ii] > 0.0 )
03122 maxStepLength[ii] = y[ii] / ( -delta_yFX[i] );
03123 else
03124 maxStepLength[ii] = 0.0;
03125 }
03126 }
03127 else
03128 {
03129
03130 if ( delta_yFX[i] > ZERO )
03131 {
03132 if ( y[ii] < 0.0 )
03133 maxStepLength[ii] = y[ii] / ( -delta_yFX[i] );
03134 else
03135 maxStepLength[ii] = 0.0;
03136 }
03137 }
03138 }
03139 }
03140
03141
03142
03143
03144
03145 real_t delta_x[NVMAX];
03146 for( j=0; j<nFR; ++j )
03147 {
03148 jj = FR_idx[j];
03149 delta_x[jj] = delta_xFR[j];
03150 }
03151 for( j=0; j<nFX; ++j )
03152 {
03153 jj = FX_idx[j];
03154 delta_x[jj] = delta_xFX[j];
03155 }
03156
03157 for( i=0; i<nIAC; ++i )
03158 {
03159 ii = IAC_idx[i];
03160
03161 if ( constraints.getType( ii ) != ST_UNBOUNDED )
03162 {
03163 delta_Ax[ii] = 0.0;
03164 for( j=0; j<nV; ++j )
03165 delta_Ax[ii] += A[ii*NVMAX + j] * delta_x[j];
03166
03167
03168 if ( constraints.isNoLower( ) == BT_FALSE )
03169 {
03170 if ( delta_lbA[ii] > delta_Ax[ii] )
03171 {
03172 if ( Ax[ii] > lbA[ii] )
03173 maxStepLength[nV+ii] = ( Ax[ii] - lbA[ii] ) / ( delta_lbA[ii] - delta_Ax[ii] );
03174 else
03175 maxStepLength[nV+ii] = 0.0;
03176 }
03177 }
03178
03179
03180 if ( constraints.isNoUpper( ) == BT_FALSE )
03181 {
03182 if ( delta_ubA[ii] < delta_Ax[ii] )
03183 {
03184 if ( Ax[ii] < ubA[ii] )
03185 maxStepLength[nV+nC+nV+ii] = ( Ax[ii] - ubA[ii] ) / ( delta_ubA[ii] - delta_Ax[ii] );
03186 else
03187 maxStepLength[nV+nC+nV+ii] = 0.0;
03188 }
03189 }
03190 }
03191 }
03192
03193
03194
03195
03196
03197 if ( bounds.isNoLower( ) == BT_FALSE )
03198 {
03199 for( i=0; i<nFR; ++i )
03200 {
03201 ii = FR_idx[i];
03202 if ( bounds.getType( ii ) != ST_UNBOUNDED )
03203 if ( delta_lb[ii] > delta_xFR[i] )
03204 {
03205 if ( x[ii] > lb[ii] )
03206 maxStepLength[ii] = ( x[ii] - lb[ii] ) / ( delta_lb[ii] - delta_xFR[i] );
03207 else
03208 maxStepLength[ii] = 0.0;
03209 }
03210 }
03211 }
03212
03213
03214 if ( bounds.isNoUpper( ) == BT_FALSE )
03215 {
03216 for( i=0; i<nFR; ++i )
03217 {
03218 ii = FR_idx[i];
03219 if ( bounds.getType( ii ) != ST_UNBOUNDED )
03220 if ( delta_ub[ii] < delta_xFR[i] )
03221 {
03222 if ( x[ii] < ub[ii] )
03223 maxStepLength[nV+nC+ii] = ( x[ii] - ub[ii] ) / ( delta_ub[ii] - delta_xFR[i] );
03224 else
03225 maxStepLength[nV+nC+ii] = 0.0;
03226 }
03227 }
03228 }
03229
03230
03231
03232 real_t tau_new = 1.0;
03233
03234 BC_idx = 0;
03235 BC_status = ST_UNDEFINED;
03236 BC_isBound = BT_FALSE;
03237
03238 for ( i=0; i<nV; ++i )
03239 {
03240
03241 if ( maxStepLength[i] < tau_new )
03242 {
03243 tau_new = maxStepLength[i];
03244 BC_idx = i;
03245 BC_isBound = BT_TRUE;
03246 if ( bounds.getStatus( i ) == ST_INACTIVE )
03247 BC_status = ST_LOWER;
03248 else
03249 BC_status = ST_INACTIVE;
03250 }
03251
03252
03253 if ( maxStepLength[nV+nC+i] < tau_new )
03254 {
03255 tau_new = maxStepLength[nV+nC+i];
03256 BC_idx = i;
03257 BC_isBound = BT_TRUE;
03258 BC_status = ST_UPPER;
03259 }
03260 }
03261
03262 for ( i=nV; i<nV+nC; ++i )
03263 {
03264
03265 if ( maxStepLength[i] < tau_new )
03266 {
03267 tau_new = maxStepLength[i];
03268 BC_idx = i-nV;
03269 BC_isBound = BT_FALSE;
03270 if ( constraints.getStatus( i-nV ) == ST_INACTIVE )
03271 BC_status = ST_LOWER;
03272 else
03273 BC_status = ST_INACTIVE;
03274 }
03275
03276
03277 if ( maxStepLength[nV+nC+i] < tau_new )
03278 {
03279 tau_new = maxStepLength[nV+nC+i];
03280 BC_idx = i-nV;
03281 BC_isBound = BT_FALSE;
03282 BC_status = ST_UPPER;
03283 }
03284 }
03285
03286
03287
03288
03289 if ( tau_new > EPS )
03290 cyclingManager.clearCyclingData( );
03291
03292
03293
03294 tau = tau_new;
03295
03296 #ifdef PC_DEBUG
03297 if ( printlevel == PL_HIGH )
03298 {
03299
03300 char messageString[80];
03301
03302 if ( BC_status == ST_UNDEFINED )
03303 sprintf( messageString,"Stepsize is %.6e!",tau );
03304 else
03305 sprintf( messageString,"Stepsize is %.6e! (BC_idx = %d, BC_isBound = %d, BC_status = %d)",tau,BC_idx,BC_isBound,BC_status );
03306
03307 getGlobalMessageHandler( )->throwInfo( RET_STEPSIZE_NONPOSITIVE,messageString,__FUNCTION__,__FILE__,__LINE__,VS_VISIBLE );
03308 }
03309 #endif
03310
03311 return SUCCESSFUL_RETURN;
03312 }
03313
03314
03315
03316
03317
03318 returnValue QProblem::hotstart_performStep( const int* const FR_idx, const int* const FX_idx, const int* const AC_idx, const int* const IAC_idx,
03319 const real_t* const delta_g, const real_t* const delta_lbA, const real_t* const delta_ubA,
03320 const real_t* const delta_lb, const real_t* const delta_ub,
03321 const real_t* const delta_xFX, const real_t* const delta_xFR,
03322 const real_t* const delta_yAC, const real_t* const delta_yFX,
03323 const real_t* const delta_Ax, int BC_idx, SubjectToStatus BC_status, BooleanType BC_isBound
03324 )
03325 {
03326 int i, j, ii;
03327 int nV = getNV( );
03328 int nC = getNC( );
03329 int nFR = getNFR( );
03330 int nFX = getNFX( );
03331 int nAC = getNAC( );
03332 int nIAC = getNIAC( );
03333
03334
03335
03336 if ( areBoundsConsistent( delta_lb,delta_ub,delta_lbA,delta_ubA ) == BT_FALSE )
03337 {
03338 infeasible = BT_TRUE;
03339 tau = 0.0;
03340
03341 return THROWERROR( RET_QP_INFEASIBLE );
03342 }
03343
03344
03345
03346 if ( tau > ZERO )
03347 {
03348
03349 for( i=0; i<nFR; ++i )
03350 {
03351 ii = FR_idx[i];
03352 x[ii] += tau*delta_xFR[i];
03353 }
03354
03355 for( i=0; i<nFX; ++i )
03356 {
03357 ii = FX_idx[i];
03358 x[ii] += tau*delta_xFX[i];
03359 y[ii] += tau*delta_yFX[i];
03360 }
03361
03362 for( i=0; i<nAC; ++i )
03363 {
03364 ii = AC_idx[i];
03365 y[nV+ii] += tau*delta_yAC[i];
03366 }
03367
03368
03369 for( i=0; i<nIAC; ++i )
03370 {
03371 ii = IAC_idx[i];
03372 if ( constraints.getType( ii ) != ST_UNBOUNDED )
03373 Ax[ii] += tau*delta_Ax[ii];
03374 }
03375 for( i=0; i<nAC; ++i )
03376 {
03377 ii = AC_idx[i];
03378
03379 Ax[ii] = 0.0;
03380 for( j=0; j<nV; ++j )
03381 Ax[ii] += A[ii*NVMAX + j] * x[j];
03382 }
03383
03384
03385 for( i=0; i<nV; ++i )
03386 {
03387 g[i] += tau*delta_g[i];
03388 lb[i] += tau*delta_lb[i];
03389 ub[i] += tau*delta_ub[i];
03390 }
03391
03392 for( i=0; i<nC; ++i )
03393 {
03394 lbA[i] += tau*delta_lbA[i];
03395 ubA[i] += tau*delta_ubA[i];
03396 }
03397 }
03398 else
03399 {
03400
03401 #ifdef PC_DEBUG
03402 char messageString[80];
03403 sprintf( messageString,"Stepsize is %.6e",tau );
03404 getGlobalMessageHandler( )->throwWarning( RET_STEPSIZE,messageString,__FUNCTION__,__FILE__,__LINE__,VS_VISIBLE );
03405 #endif
03406 }
03407
03408
03409
03410 #ifdef PC_DEBUG
03411 char messageString[80];
03412 VisibilityStatus visibilityStatus;
03413
03414 if ( printlevel == PL_HIGH )
03415 visibilityStatus = VS_VISIBLE;
03416 else
03417 visibilityStatus = VS_HIDDEN;
03418 #endif
03419
03420
03421
03422 switch ( BC_status )
03423 {
03424
03425 case ST_UNDEFINED:
03426 return RET_OPTIMAL_SOLUTION_FOUND;
03427
03428
03429
03430 case ST_INACTIVE:
03431 if ( BC_isBound == BT_TRUE )
03432 {
03433 #ifdef PC_DEBUG
03434 sprintf( messageString,"bound no. %d.", BC_idx );
03435 getGlobalMessageHandler( )->throwInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNCTION__,__FILE__,__LINE__,visibilityStatus );
03436 #endif
03437
03438 if ( removeBound( BC_idx,BT_TRUE ) != SUCCESSFUL_RETURN )
03439 return THROWERROR( RET_REMOVE_FROM_ACTIVESET_FAILED );
03440
03441 y[BC_idx] = 0.0;
03442 }
03443 else
03444 {
03445 #ifdef PC_DEBUG
03446 sprintf( messageString,"constraint no. %d.", BC_idx );
03447 getGlobalMessageHandler( )->throwInfo( RET_REMOVE_FROM_ACTIVESET,messageString,__FUNCTION__,__FILE__,__LINE__,visibilityStatus );
03448 #endif
03449
03450 if ( removeConstraint( BC_idx,BT_TRUE ) != SUCCESSFUL_RETURN )
03451 return THROWERROR( RET_REMOVE_FROM_ACTIVESET_FAILED );
03452
03453 y[nV+BC_idx] = 0.0;
03454 }
03455 break;
03456
03457
03458
03459 default:
03460 if ( BC_isBound == BT_TRUE )
03461 {
03462 #ifdef PC_DEBUG
03463 if ( BC_status == ST_LOWER )
03464 sprintf( messageString,"lower bound no. %d.", BC_idx );
03465 else
03466 sprintf( messageString,"upper bound no. %d.", BC_idx );
03467 getGlobalMessageHandler( )->throwInfo( RET_ADD_TO_ACTIVESET,messageString,__FUNCTION__,__FILE__,__LINE__,visibilityStatus );
03468 #endif
03469
03470 if ( addBound( BC_idx,BC_status,BT_TRUE ) != SUCCESSFUL_RETURN )
03471 return THROWERROR( RET_ADD_TO_ACTIVESET_FAILED );
03472 }
03473 else
03474 {
03475 #ifdef PC_DEBUG
03476 if ( BC_status == ST_LOWER )
03477 sprintf( messageString,"lower constraint's bound no. %d.", BC_idx );
03478 else
03479 sprintf( messageString,"upper constraint's bound no. %d.", BC_idx );
03480 getGlobalMessageHandler( )->throwInfo( RET_ADD_TO_ACTIVESET,messageString,__FUNCTION__,__FILE__,__LINE__,visibilityStatus );
03481 #endif
03482
03483 if ( addConstraint( BC_idx,BC_status,BT_TRUE ) != SUCCESSFUL_RETURN )
03484 return THROWERROR( RET_ADD_TO_ACTIVESET_FAILED );
03485 }
03486 break;
03487 }
03488
03489 return SUCCESSFUL_RETURN;
03490 }
03491
03492
03493
03494
03495
03496 BooleanType QProblem::areBoundsConsistent( const real_t* const delta_lb, const real_t* const delta_ub,
03497 const real_t* const delta_lbA, const real_t* const delta_ubA
03498 ) const
03499 {
03500 int i;
03501
03502
03503 if ( QProblemB::areBoundsConsistent( delta_lb,delta_ub ) == BT_FALSE )
03504 return BT_FALSE;
03505
03506
03507
03508
03509 for( i=0; i<getNC( ); ++i )
03510 if ( ( lbA[i] > ubA[i] - BOUNDTOL ) && ( delta_lbA[i] > delta_ubA[i] + EPS ) )
03511 return BT_FALSE;
03512
03513 return BT_TRUE;
03514 }
03515
03516
03517
03518
03519
03520 returnValue QProblem::setupQPdata( const real_t* const _H, const real_t* const _g, const real_t* const _A,
03521 const real_t* const _lb, const real_t* const _ub,
03522 const real_t* const _lbA, const real_t* const _ubA
03523 )
03524 {
03525 int i, j;
03526 int nV = getNV( );
03527 int nC = getNC( );
03528
03529
03530
03531 if ( QProblemB::setupQPdata( _H,_g,_lb,_ub ) != SUCCESSFUL_RETURN )
03532 return THROWERROR( RET_INVALID_ARGUMENTS );
03533
03534
03535 if ( ( nC > 0 ) && ( _A == 0 ) )
03536 return THROWERROR( RET_INVALID_ARGUMENTS );
03537
03538 if ( nC > 0 )
03539 {
03540 for( i=0; i<nC; ++i )
03541 for( j=0; j<nV; ++j )
03542 A[i*NVMAX + j] = _A[i*nV + j];
03543
03544
03545 if ( _lbA != 0 )
03546 {
03547 for( i=0; i<nC; ++i )
03548 lbA[i] = _lbA[i];
03549 }
03550 else
03551 {
03552
03553 for( i=0; i<nC; ++i )
03554 lbA[i] = -INFTY;
03555 }
03556
03557
03558 if ( _ubA != 0 )
03559 {
03560 for( i=0; i<nC; ++i )
03561 ubA[i] = _ubA[i];
03562 }
03563 else
03564 {
03565
03566 for( i=0; i<nC; ++i )
03567 ubA[i] = INFTY;
03568 }
03569 }
03570
03571
03572
03573
03574
03575
03576 return SUCCESSFUL_RETURN;
03577 }
03578
03579
03580
03581 #ifdef PC_DEBUG
03582
03583
03584
03585
03586 returnValue QProblem::printIteration( int iteration,
03587 int BC_idx, SubjectToStatus BC_status, BooleanType BC_isBound
03588 )
03589 {
03590 char myPrintfString[160];
03591
03592
03593 if ( iteration < 0 )
03594 return THROWERROR( RET_INVALID_ARGUMENTS );
03595
03596
03597 if ( printlevel != PL_MEDIUM )
03598 return SUCCESSFUL_RETURN;
03599
03600
03601
03602 if ( iteration == 0 )
03603 {
03604 sprintf( myPrintfString,"\n############## qpOASES -- QP NO.%4.1d ###############\n", count );
03605 myPrintf( myPrintfString );
03606
03607 sprintf( myPrintfString," Iter | StepLength | Info | nFX | nAC \n" );
03608 myPrintf( myPrintfString );
03609 }
03610
03611
03612 if ( BC_status == ST_UNDEFINED )
03613 {
03614 sprintf( myPrintfString," %4.1d | %1.5e | QP SOLVED | %4.1d | %4.1d \n", iteration,tau,getNFX( ),getNAC( ) );
03615 myPrintf( myPrintfString );
03616 }
03617 else
03618 {
03619 char info[8];
03620
03621 if ( BC_status == ST_INACTIVE )
03622 sprintf( info,"REM " );
03623 else
03624 sprintf( info,"ADD " );
03625
03626 if ( BC_isBound == BT_TRUE )
03627 sprintf( &(info[4]),"BND" );
03628 else
03629 sprintf( &(info[4]),"CON" );
03630
03631 sprintf( myPrintfString," %4.1d | %1.5e | %s%4.1d | %4.1d | %4.1d \n", iteration,tau,info,BC_idx,getNFX( ),getNAC( ) );
03632 myPrintf( myPrintfString );
03633 }
03634
03635 return SUCCESSFUL_RETURN;
03636 }
03637
03638
03639
03640
03641
03642 returnValue QProblem::printIteration( int iteration,
03643 int BC_idx, SubjectToStatus BC_status
03644 )
03645 {
03646 return printIteration( iteration,BC_idx,BC_status,BT_TRUE );
03647 }
03648
03649 #endif
03650
03651
03652
03653
03654
03655
03656 returnValue QProblem::checkKKTconditions( )
03657 {
03658 #ifdef __PERFORM_KKT_TEST__
03659
03660 int i, j, jj;
03661 int nV = getNV( );
03662 int nC = getNC( );
03663 int nAC = getNAC( );
03664
03665 real_t tmp;
03666 real_t maxKKTviolation = 0.0;
03667
03668 int AC_idx[NCMAX_ALLOC];
03669 constraints.getActive( )->getNumberArray( AC_idx );
03670
03671
03672 for( i=0; i<nV; ++i )
03673 {
03674 tmp = g[i];
03675
03676 for( j=0; j<nV; ++j )
03677 tmp += H[i*NVMAX + j] * x[j];
03678
03679 tmp -= y[i];
03680
03681
03682 for( j=0; j<nAC; ++j )
03683 {
03684 jj = AC_idx[j];
03685 tmp -= A[jj*NVMAX + i] * y[nV+jj];
03686 }
03687
03688 if ( getAbs( tmp ) > maxKKTviolation )
03689 maxKKTviolation = getAbs( tmp );
03690 }
03691
03692
03693
03694 for( i=0; i<nC; ++i )
03695 {
03696 if ( lbA[i] - Ax[i] > maxKKTviolation )
03697 maxKKTviolation = lbA[i] - Ax[i];
03698
03699 if ( Ax[i] - ubA[i] > maxKKTviolation )
03700 maxKKTviolation = Ax[i] - ubA[i];
03701 }
03702
03703
03704 for( i=0; i<nV; ++i )
03705 {
03706 if ( lb[i] - x[i] > maxKKTviolation )
03707 maxKKTviolation = lb[i] - x[i];
03708
03709 if ( x[i] - ub[i] > maxKKTviolation )
03710 maxKKTviolation = x[i] - ub[i];
03711 }
03712
03713
03714
03715 for( i=0; i<nV; ++i )
03716 {
03717 switch ( bounds.getStatus( i ) )
03718 {
03719 case ST_LOWER:
03720 if ( -y[i] > maxKKTviolation )
03721 maxKKTviolation = -y[i];
03722 if ( getAbs( x[i] - lb[i] ) > maxKKTviolation )
03723 maxKKTviolation = getAbs( x[i] - lb[i] );
03724 break;
03725
03726 case ST_UPPER:
03727 if ( y[i] > maxKKTviolation )
03728 maxKKTviolation = y[i];
03729 if ( getAbs( ub[i] - x[i] ) > maxKKTviolation )
03730 maxKKTviolation = getAbs( ub[i] - x[i] );
03731 break;
03732
03733 default:
03734 if ( getAbs( y[i] ) > maxKKTviolation )
03735 maxKKTviolation = getAbs( y[i] );
03736 break;
03737 }
03738 }
03739
03740
03741 for( i=0; i<nC; ++i )
03742 {
03743 switch ( constraints.getStatus( i ) )
03744 {
03745 case ST_LOWER:
03746 if ( -y[nV+i] > maxKKTviolation )
03747 maxKKTviolation = -y[nV+i];
03748 if ( getAbs( Ax[i] - lbA[i] ) > maxKKTviolation )
03749 maxKKTviolation = getAbs( Ax[i] - lbA[i] );
03750 break;
03751
03752 case ST_UPPER:
03753 if ( y[nV+i] > maxKKTviolation )
03754 maxKKTviolation = y[nV+i];
03755 if ( getAbs( ubA[i] - Ax[i] ) > maxKKTviolation )
03756 maxKKTviolation = getAbs( ubA[i] - Ax[i] );
03757 break;
03758
03759 default:
03760 if ( getAbs( y[nV+i] ) > maxKKTviolation )
03761 maxKKTviolation = getAbs( y[nV+i] );
03762 break;
03763 }
03764 }
03765
03766 if ( maxKKTviolation > CRITICALACCURACY )
03767 return RET_NO_SOLUTION;
03768
03769 if ( maxKKTviolation > DESIREDACCURACY )
03770 return RET_INACCURATE_SOLUTION;
03771
03772 #endif
03773
03774 return SUCCESSFUL_RETURN;
03775 }
03776
03777
03778
03779
03780