00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00035 #include <acado/function/function.hpp>
00036 #include <acado/constraint/constraint.hpp>
00037
00038
00039
00040 BEGIN_NAMESPACE_ACADO
00041
00042
00043
00044
00045
00046
00047
00048
00049 Constraint::Constraint( )
00050 :BoxConstraint(){
00051
00052 boundary_constraint = 0;
00053 coupled_path_constraint = 0;
00054 path_constraint = 0;
00055 algebraic_consistency_constraint = 0;
00056 point_constraints = 0;
00057 }
00058
00059
00060
00061 Constraint::Constraint( const Constraint& rhs )
00062 :BoxConstraint(rhs){
00063
00064 uint run1;
00065
00066 if( rhs.boundary_constraint != 0 )
00067 boundary_constraint = new BoundaryConstraint(*rhs.boundary_constraint);
00068 else boundary_constraint = 0 ;
00069
00070 if( rhs.coupled_path_constraint != 0 )
00071 coupled_path_constraint = new CoupledPathConstraint(*rhs.coupled_path_constraint);
00072 else coupled_path_constraint = 0 ;
00073
00074 if( rhs.path_constraint != 0 )
00075 path_constraint = new PathConstraint(*rhs.path_constraint);
00076 else path_constraint = 0 ;
00077
00078 if( rhs.algebraic_consistency_constraint != 0 )
00079 algebraic_consistency_constraint = new AlgebraicConsistencyConstraint(*rhs.algebraic_consistency_constraint);
00080 else algebraic_consistency_constraint = 0;
00081
00082 if( rhs.point_constraints != 0 ){
00083 point_constraints = new PointConstraint*[grid.getNumPoints()];
00084 for( run1 = 0; run1 < grid.getNumPoints(); run1++ ){
00085 if( rhs.point_constraints[run1] != 0 ){
00086 point_constraints[run1] = new PointConstraint(*rhs.point_constraints[run1]);
00087 }
00088 else point_constraints[run1] = 0;
00089 }
00090 }
00091 else point_constraints = 0;
00092 }
00093
00094
00095 Constraint::~Constraint( ){
00096
00097 deleteAll();
00098 }
00099
00100
00101 void Constraint::deleteAll(){
00102
00103 uint run1;
00104
00105 if( boundary_constraint != 0 )
00106 delete boundary_constraint;
00107
00108 if( coupled_path_constraint != 0 )
00109 delete coupled_path_constraint;
00110
00111 if( path_constraint != 0 )
00112 delete path_constraint;
00113
00114 if( algebraic_consistency_constraint != 0 )
00115 delete algebraic_consistency_constraint;
00116
00117 if( point_constraints != 0 ){
00118
00119 for( run1 = 0; run1 < grid.getNumPoints(); run1++ )
00120 if( point_constraints[run1] != 0 )
00121 delete point_constraints[run1];
00122
00123 delete[] point_constraints;
00124 }
00125 }
00126
00127
00128
00129 returnValue Constraint::init( const Grid& grid_, const int& numberOfStages_ ){
00130
00131 deleteAll();
00132
00133 BoxConstraint::init( grid_ );
00134
00135 uint run1;
00136
00137 boundary_constraint = new BoundaryConstraint (grid );
00138 coupled_path_constraint = new CoupledPathConstraint (grid );
00139 path_constraint = new PathConstraint (grid );
00140 algebraic_consistency_constraint = new AlgebraicConsistencyConstraint(grid,numberOfStages_);
00141 point_constraints = new PointConstraint*[grid.getNumPoints()];
00142
00143 for( run1 = 0; run1 < grid.getNumPoints(); run1++ )
00144 point_constraints[run1] = 0;
00145
00146 return SUCCESSFUL_RETURN;
00147 }
00148
00149
00150
00151 Constraint& Constraint::operator=( const Constraint& rhs ){
00152
00153 uint run1;
00154
00155 if( this != &rhs ){
00156
00157 deleteAll();
00158
00159 BoxConstraint::operator=(rhs);
00160
00161 if( rhs.boundary_constraint != 0 )
00162 boundary_constraint = new BoundaryConstraint(*rhs.boundary_constraint);
00163 else boundary_constraint = 0 ;
00164
00165 if( rhs.coupled_path_constraint != 0 )
00166 coupled_path_constraint = new CoupledPathConstraint(*rhs.coupled_path_constraint);
00167 else coupled_path_constraint = 0 ;
00168
00169 if( rhs.path_constraint != 0 )
00170 path_constraint = new PathConstraint(*rhs.path_constraint);
00171 else path_constraint = 0 ;
00172
00173 if( rhs.algebraic_consistency_constraint != 0 )
00174 algebraic_consistency_constraint = new AlgebraicConsistencyConstraint(*rhs.algebraic_consistency_constraint);
00175 else algebraic_consistency_constraint = 0;
00176
00177 if( rhs.point_constraints != 0 ){
00178 point_constraints = new PointConstraint*[grid.getNumPoints()];
00179 for( run1 = 0; run1 < grid.getNumPoints(); run1++ ){
00180 if( rhs.point_constraints[run1] != 0 ){
00181 point_constraints[run1] = new PointConstraint(*rhs.point_constraints[run1]);
00182 }
00183 else point_constraints[run1] = 0;
00184 }
00185 }
00186 else point_constraints = 0;
00187
00188 }
00189 return *this;
00190 }
00191
00192
00193
00194 returnValue Constraint::add( const double lb_, const Expression& arg, const double ub_ ){
00195
00196 DVector tmp_lb(grid.getNumPoints());
00197 DVector tmp_ub(grid.getNumPoints());
00198
00199 tmp_lb.setAll(lb_);
00200 tmp_ub.setAll(ub_);
00201
00202 return add( tmp_lb, arg, tmp_ub );
00203 }
00204
00205
00206
00207 returnValue Constraint::add( const DVector lb_, const Expression& arg, const double ub_ ){
00208
00209 DVector tmp_ub(grid.getNumPoints());
00210 tmp_ub.setAll(ub_);
00211
00212 return add( lb_, arg, tmp_ub );
00213 }
00214
00215
00216 returnValue Constraint::add( const double lb_, const Expression& arg, const DVector ub_ ){
00217
00218 DVector tmp_lb(grid.getNumPoints());
00219 tmp_lb.setAll(lb_);
00220
00221 return add( tmp_lb, arg, ub_ );
00222 }
00223
00224
00225 returnValue Constraint::add( const DVector lb_, const Expression &arg, const DVector ub_ ){
00226
00227
00228
00229 if( lb_.getDim() != ub_.getDim() ) return ACADOERROR(RET_INFEASIBLE_CONSTRAINT);
00230 if( lb_.getDim() != grid.getNumPoints() ) return ACADOERROR(RET_INFEASIBLE_CONSTRAINT);
00231 if( (lb_ <= (const DVector&)ub_) == BT_FALSE ) return ACADOERROR(RET_INFEASIBLE_CONSTRAINT);
00232
00233
00234
00235
00236 VariableType varType = arg.getVariableType();
00237 int component = arg.getComponent(0) ;
00238
00239 if( arg.isVariable( ) == BT_TRUE ){
00240 if( varType != VT_INTERMEDIATE_STATE ){
00241
00242 nb++;
00243 var = (VariableType*)realloc(var , nb*sizeof(VariableType));
00244 index = (int* )realloc(index, nb*sizeof(int ));
00245 blb = (DVector** )realloc(blb , nb*sizeof(DVector* ));
00246 bub = (DVector** )realloc(bub , nb*sizeof(DVector* ));
00247
00248 var [nb-1] = varType ;
00249 index[nb-1] = component;
00250 blb [nb-1] = new DVector( lb_ );
00251 bub [nb-1] = new DVector( ub_ );
00252
00253 return SUCCESSFUL_RETURN;
00254 }
00255 }
00256
00257
00258
00259
00260 return path_constraint->add( lb_, arg, ub_ );
00261 }
00262
00263
00264 returnValue Constraint::add( const double lb_, const Expression *arguments, const double ub_ ){
00265
00266
00267
00268 if( lb_ > ub_ + EPS ) return ACADOERROR(RET_INFEASIBLE_CONSTRAINT);
00269
00270 return coupled_path_constraint->add( lb_, arguments, ub_ );
00271 }
00272
00273
00274 returnValue Constraint::add( const uint& endOfStage_ ,
00275 const DifferentialEquation& dae ){
00276
00277 return algebraic_consistency_constraint->add( endOfStage_, dae );
00278 }
00279
00280
00281 returnValue Constraint::add( const ConstraintComponent& component ){
00282
00283
00284 DVector tmp_ub(grid.getNumPoints());
00285 DVector tmp_lb(grid.getNumPoints());
00286
00287 uint run1;
00288
00289 if( component.hasLBgrid() == 0 ){
00290
00291 for( run1 = 0; run1 < grid.getNumPoints(); run1++ ){
00292 if( (component.getLB()).getDim() == 1 )
00293 tmp_lb(run1) = (component.getLB()).operator()(0);
00294 else{
00295 if( (component.getLB()).getDim() <= run1 )
00296 return ACADOWARNING(RET_INFEASIBLE_CONSTRAINT);
00297 tmp_lb(run1) = (component.getLB()).operator()(run1);
00298 }
00299 }
00300 }
00301 else{
00302
00303 VariablesGrid LBgrid = component.getLBgrid();
00304
00305 for( run1 = 0; run1 < grid.getNumPoints(); run1++ ){
00306 DVector tmp = LBgrid.linearInterpolation( grid.getTime(run1) );
00307 tmp_lb(run1) = tmp(0);
00308 }
00309 }
00310
00311
00312 if( component.hasUBgrid() == 0 ){
00313 for( run1 = 0; run1 < grid.getNumPoints(); run1++ ){
00314 if( (component.getUB()).getDim() == 1 )
00315 tmp_ub(run1) = (component.getUB()).operator()(0);
00316 else{
00317 if( (component.getUB()).getDim() <= run1 )
00318 return ACADOWARNING(RET_INFEASIBLE_CONSTRAINT);
00319 tmp_ub(run1) = (component.getUB()).operator()(run1);
00320 }
00321 }
00322 }
00323 else{
00324
00325 VariablesGrid UBgrid = component.getUBgrid();
00326
00327 for( run1 = 0; run1 < grid.getNumPoints(); run1++ ){
00328 DVector tmp = UBgrid.linearInterpolation( grid.getTime(run1) );
00329 tmp_ub(run1) = tmp(0);
00330 }
00331 }
00332
00333 return add( tmp_lb, component.getExpression(), tmp_ub );
00334 }
00335
00336
00337 returnValue Constraint::add( const int index_, const ConstraintComponent& component ){
00338
00339 DVector tmp_ub(grid.getNumPoints());
00340 DVector tmp_lb(grid.getNumPoints());
00341
00342 if ( !(index_ < (int) grid.getNumPoints()) )
00343 return ACADOERRORTEXT(RET_ASSERTION,
00344 "The constraint component can not be set as the associated "
00345 "discretization point is not in the time horizon.");
00346
00347 uint run1;
00348
00349 if( component.hasLBgrid() == 0 ){
00350
00351 for( run1 = 0; run1 < grid.getNumPoints(); run1++ ){
00352 if( (component.getLB()).getDim() == 1 )
00353 tmp_lb(run1) = (component.getLB()).operator()(0);
00354 else{
00355 if( (component.getLB()).getDim() <= run1 )
00356 return ACADOWARNING(RET_INFEASIBLE_CONSTRAINT);
00357 tmp_lb(run1) = (component.getLB()).operator()(run1);
00358 }
00359 }
00360 }
00361 else{
00362
00363 VariablesGrid LBgrid = component.getLBgrid();
00364
00365 for( run1 = 0; run1 < grid.getNumPoints(); run1++ ){
00366 DVector tmp = LBgrid.linearInterpolation( grid.getTime(run1) );
00367 tmp_lb(run1) = tmp(0);
00368 }
00369 }
00370
00371
00372 if( component.hasUBgrid() == 0 ){
00373 for( run1 = 0; run1 < grid.getNumPoints(); run1++ ){
00374 if( (component.getUB()).getDim() == 1 )
00375 tmp_ub(run1) = (component.getUB()).operator()(0);
00376 else{
00377 if( (component.getUB()).getDim() <= run1 )
00378 return ACADOWARNING(RET_INFEASIBLE_CONSTRAINT);
00379 tmp_ub(run1) = (component.getUB()).operator()(run1);
00380 }
00381 }
00382 }
00383 else{
00384
00385 VariablesGrid UBgrid = component.getUBgrid();
00386
00387 for( run1 = 0; run1 < grid.getNumPoints(); run1++ ){
00388 DVector tmp = UBgrid.linearInterpolation( grid.getTime(run1) );
00389 tmp_ub(run1) = tmp(0);
00390 }
00391 }
00392
00393 ACADO_TRY( add( index_, tmp_lb(index_), component.getExpression(), tmp_ub(index_) ) );
00394
00395 return SUCCESSFUL_RETURN;
00396 }
00397
00398
00399 returnValue Constraint::evaluate( const OCPiterate& iter ){
00400
00401
00402 if( grid.getNumPoints() == 0 ) return ACADOERROR(RET_MEMBER_NOT_INITIALISED);
00403
00404 uint run1;
00405 returnValue returnvalue;
00406
00407
00408
00409
00410
00411 if( boundary_constraint->getNC() != 0 ){
00412 returnvalue = boundary_constraint->init( iter );
00413 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00414 returnvalue = boundary_constraint->evaluate( iter );
00415 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00416 }
00417
00418
00419
00420
00421
00422 if( coupled_path_constraint->getNC() != 0 ){
00423 returnvalue = coupled_path_constraint->init( iter );
00424 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00425 returnvalue = coupled_path_constraint->evaluate( iter );
00426 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00427 }
00428
00429
00430
00431
00432
00433 if( path_constraint->getNC() != 0 ){
00434 returnvalue = path_constraint->init( iter );
00435 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00436 returnvalue = path_constraint->evaluate( iter );
00437 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00438 }
00439
00440
00441
00442
00443
00444 if( algebraic_consistency_constraint->getNC() != 0 ){
00445 returnvalue = algebraic_consistency_constraint->init( iter );
00446 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00447 returnvalue = algebraic_consistency_constraint->evaluate( iter );
00448 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00449 }
00450
00451
00452
00453
00454
00455 if( point_constraints != 0 ){
00456 for( run1 = 0; run1 < grid.getNumPoints(); run1++ ){
00457 if( point_constraints[run1] != 0 ){
00458 returnvalue = point_constraints[run1]->init( iter );
00459 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00460 returnvalue = point_constraints[run1]->evaluate( iter );
00461 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00462 }
00463 }
00464 }
00465
00466
00467
00468
00469
00470 return evaluateBounds( iter );
00471 }
00472
00473
00474
00475 returnValue Constraint::evaluateSensitivities( ){
00476
00477 uint run1;
00478 returnValue returnvalue;
00479
00480
00481
00482
00483
00484 if( boundary_constraint->getNC() != 0 ){
00485 returnvalue = boundary_constraint->evaluateSensitivities( );
00486 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00487 }
00488
00489
00490
00491
00492
00493 if( coupled_path_constraint->getNC() != 0 ){
00494 returnvalue = coupled_path_constraint->evaluateSensitivities( );
00495 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00496 }
00497
00498
00499
00500
00501
00502 if( path_constraint->getNC() != 0 ){
00503 returnvalue = path_constraint->evaluateSensitivities( );
00504 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00505 }
00506
00507
00508
00509
00510
00511 if( algebraic_consistency_constraint->getNC() != 0 ){
00512 returnvalue = algebraic_consistency_constraint->evaluateSensitivities( );
00513 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00514 }
00515
00516
00517
00518
00519 if( point_constraints != 0 ){
00520 for( run1 = 0; run1 < grid.getNumPoints(); run1++ ){
00521 if( point_constraints[run1] != 0 ){
00522 returnvalue = point_constraints[run1]->evaluateSensitivities( );
00523 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00524 }
00525 }
00526 }
00527
00528 return SUCCESSFUL_RETURN;
00529 }
00530
00531
00532 returnValue Constraint::evaluateSensitivities( const BlockMatrix &seed, BlockMatrix &hessian ){
00533
00534
00535 uint run1 ;
00536 int count;
00537 returnValue returnvalue;
00538
00539 count = 0;
00540 DMatrix tmp;
00541
00542
00543
00544
00545 if( boundary_constraint->getNC() != 0 ){
00546 seed.getSubBlock( count, 0, tmp, boundary_constraint->getNC(), 1 );
00547 returnvalue = boundary_constraint->evaluateSensitivities( tmp, hessian );
00548 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00549 count++;
00550 }
00551
00552
00553
00554
00555
00556 if( coupled_path_constraint->getNC() != 0 ){
00557 seed.getSubBlock( count, 0, tmp, coupled_path_constraint->getNC(), 1 );
00558 returnvalue = coupled_path_constraint->evaluateSensitivities( tmp, hessian );
00559 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00560 count++;
00561 }
00562
00563
00564
00565
00566
00567 if( path_constraint->getNC() != 0 ){
00568 returnvalue = path_constraint->evaluateSensitivities( count, seed, hessian );
00569 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00570 }
00571
00572
00573
00574
00575
00576 if( algebraic_consistency_constraint->getNC() != 0 ){
00577 returnvalue = algebraic_consistency_constraint->evaluateSensitivities( count, seed, hessian );
00578 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00579 }
00580
00581
00582
00583
00584 if( point_constraints != 0 ){
00585 for( run1 = 0; run1 < grid.getNumPoints(); run1++ ){
00586 if( point_constraints[run1] != 0 ){
00587 seed.getSubBlock( count, 0, tmp, point_constraints[run1]->getNC(), 1 );
00588 returnvalue = point_constraints[run1]->evaluateSensitivities( tmp, hessian );
00589 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00590 count++;
00591 }
00592 }
00593 }
00594 return SUCCESSFUL_RETURN;
00595 }
00596
00597
00598
00599 returnValue Constraint::setForwardSeed( BlockMatrix *xSeed_ ,
00600 BlockMatrix *xaSeed_,
00601 BlockMatrix *pSeed_ ,
00602 BlockMatrix *uSeed_ ,
00603 BlockMatrix *wSeed_ ,
00604 int order ){
00605
00606 uint run1;
00607 returnValue returnvalue;
00608
00609
00610
00611
00612
00613 if( boundary_constraint->getNC() != 0 ){
00614 returnvalue = boundary_constraint->setForwardSeed( xSeed_, xaSeed_, pSeed_, uSeed_, wSeed_, order );
00615 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00616 }
00617
00618
00619
00620
00621
00622 if( coupled_path_constraint->getNC() != 0 ){
00623 returnvalue = coupled_path_constraint->setForwardSeed( xSeed_, xaSeed_, pSeed_, uSeed_, wSeed_, order );
00624 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00625 }
00626
00627
00628
00629
00630
00631 if( path_constraint->getNC() != 0 ){
00632 returnvalue = path_constraint->setForwardSeed( xSeed_, xaSeed_, pSeed_, uSeed_, wSeed_, order );
00633 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00634 }
00635
00636
00637
00638
00639
00640 if( algebraic_consistency_constraint->getNC() != 0 ){
00641 returnvalue = algebraic_consistency_constraint->setForwardSeed( xSeed_, xaSeed_, pSeed_, uSeed_, wSeed_, order );
00642 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00643 }
00644
00645
00646
00647
00648
00649 if( point_constraints != 0 ){
00650 for( run1 = 0; run1 < grid.getNumPoints(); run1++ ){
00651 if( point_constraints[run1] != 0 ){
00652 returnvalue = point_constraints[run1]->setForwardSeed( xSeed_, xaSeed_, pSeed_, uSeed_, wSeed_, order );
00653 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00654 }
00655 }
00656 }
00657
00658 return SUCCESSFUL_RETURN;
00659 }
00660
00661
00662 returnValue Constraint::setUnitForwardSeed( ){
00663
00664 uint run1;
00665 returnValue returnvalue;
00666
00667
00668
00669
00670
00671 if( boundary_constraint->getNC() != 0 ){
00672 returnvalue = boundary_constraint->setUnitForwardSeed();
00673 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00674 }
00675
00676
00677
00678
00679
00680 if( coupled_path_constraint->getNC() != 0 ){
00681 returnvalue = coupled_path_constraint->setUnitForwardSeed();
00682 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00683 }
00684
00685
00686
00687
00688
00689 if( path_constraint->getNC() != 0 ){
00690 returnvalue = path_constraint->setUnitForwardSeed();
00691 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00692 }
00693
00694
00695
00696
00697 if( algebraic_consistency_constraint->getNC() != 0 ){
00698 returnvalue = algebraic_consistency_constraint->setUnitForwardSeed();
00699 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00700 }
00701
00702
00703
00704
00705
00706 if( point_constraints != 0 ){
00707 for( run1 = 0; run1 < grid.getNumPoints(); run1++ ){
00708 if( point_constraints[run1] != 0 ){
00709 returnvalue = point_constraints[run1]->setUnitForwardSeed();
00710 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00711 }
00712 }
00713 }
00714
00715 return SUCCESSFUL_RETURN;
00716 }
00717
00718
00719 returnValue Constraint::setBackwardSeed( BlockMatrix *seed, int order ){
00720
00721 return SUCCESSFUL_RETURN;
00722 }
00723
00724
00725 returnValue Constraint::setUnitBackwardSeed( ){
00726
00727
00728 uint run1;
00729 returnValue returnvalue;
00730
00731 const uint N = grid.getNumPoints();
00732
00733
00734
00735
00736 if( boundary_constraint->getNC() != 0 ){
00737 BlockMatrix seed( 1, 1 );
00738 seed.setIdentity( 0, 0, boundary_constraint->getNC() );
00739 returnvalue = boundary_constraint->setBackwardSeed( &seed, 1 );
00740 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00741 }
00742
00743
00744
00745
00746
00747 if( coupled_path_constraint->getNC() != 0 ){
00748 BlockMatrix seed( 1, 1 );
00749 seed.setIdentity( 0, 0, coupled_path_constraint->getNC() );
00750 returnvalue = coupled_path_constraint->setBackwardSeed( &seed, 1 );
00751 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00752 }
00753
00754
00755
00756
00757
00758 if( path_constraint->getNC() != 0 ){
00759 BlockMatrix seed( 1, N );
00760 for( run1 = 0; run1 < N; run1++ )
00761 seed.setIdentity( 0, run1, path_constraint->getDim(run1) );
00762 returnvalue = path_constraint->setBackwardSeed( &seed, 1 );
00763 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00764 }
00765
00766
00767
00768
00769 if( algebraic_consistency_constraint->getNC() != 0 ){
00770 BlockMatrix seed( 1, N );
00771 for( run1 = 0; run1 < N; run1++ )
00772 seed.setIdentity( 0, run1, algebraic_consistency_constraint->getDim(run1) );
00773 returnvalue = algebraic_consistency_constraint->setBackwardSeed( &seed, 1 );
00774 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00775 }
00776
00777
00778
00779
00780
00781 if( point_constraints != 0 ){
00782 for( run1 = 0; run1 < grid.getNumPoints(); run1++ ){
00783 if( point_constraints[run1] != 0 ){
00784 BlockMatrix seed( 1, 1 );
00785 seed.setIdentity( 0, 0, point_constraints[run1]->getNC() );
00786 returnvalue = point_constraints[run1]->setBackwardSeed( &seed, 1 );
00787 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00788 }
00789 }
00790 }
00791
00792 return SUCCESSFUL_RETURN;
00793 }
00794
00795
00796
00797 returnValue Constraint::getConstraintResiduum( BlockMatrix &lowerRes, BlockMatrix &upperRes ){
00798
00799 const int N = grid.getNumPoints();
00800
00801 returnValue returnvalue;
00802
00803 BlockMatrix residuumL;
00804 BlockMatrix residuumU;
00805
00806 residuumL.init( getNumberOfBlocks(), 1 );
00807 residuumU.init( getNumberOfBlocks(), 1 );
00808
00809 int nc, run1;
00810
00811 nc = 0;
00812
00813
00814
00815
00816 if( boundary_constraint->getNC() != 0 ){
00817 BlockMatrix resL, resU;
00818 returnvalue = boundary_constraint->getResiduum( resL, resU );
00819 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00820 DMatrix resL_;
00821 DMatrix resU_;
00822 resL.getSubBlock( 0, 0, resL_ );
00823 resU.getSubBlock( 0, 0, resU_ );
00824 residuumL.setDense( nc, 0, resL_ );
00825 residuumU.setDense( nc, 0, resU_ );
00826 nc++;
00827 }
00828
00829
00830
00831
00832
00833 if( coupled_path_constraint->getNC() != 0 ){
00834 BlockMatrix resL, resU;
00835 returnvalue = coupled_path_constraint->getResiduum( resL, resU );
00836 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00837 DMatrix resL_;
00838 DMatrix resU_;
00839 resL.getSubBlock( 0, 0, resL_ );
00840 resU.getSubBlock( 0, 0, resU_ );
00841 residuumL.setDense( nc, 0, resL_ );
00842 residuumU.setDense( nc, 0, resU_ );
00843 nc++;
00844 }
00845
00846
00847
00848
00849
00850 if( path_constraint->getNC() != 0 ){
00851 BlockMatrix resL, resU;
00852 returnvalue = path_constraint->getResiduum( resL, resU );
00853 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00854 DMatrix resL_;
00855 DMatrix resU_;
00856 for( run1 = 0; run1 < N; run1++ ){
00857 resL.getSubBlock( run1, 0, resL_ );
00858 resU.getSubBlock( run1, 0, resU_ );
00859 residuumL.setDense( nc, 0, resL_ );
00860 residuumU.setDense( nc, 0, resU_ );
00861 nc++;
00862 }
00863 }
00864
00865
00866
00867
00868 if( algebraic_consistency_constraint->getNC() != 0 ){
00869 BlockMatrix resL, resU;
00870 returnvalue = algebraic_consistency_constraint->getResiduum( resL, resU );
00871 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00872 DMatrix resL_;
00873 DMatrix resU_;
00874 for( run1 = 0; run1 < N; run1++ ){
00875 resL.getSubBlock( run1, 0, resL_ );
00876 resU.getSubBlock( run1, 0, resU_ );
00877 residuumL.setDense( nc, 0, resL_ );
00878 residuumU.setDense( nc, 0, resU_ );
00879 nc++;
00880 }
00881 }
00882
00883
00884
00885
00886 if( point_constraints != 0 ){
00887 for( run1 = 0; run1 < (int) grid.getNumPoints(); run1++ ){
00888 if( point_constraints[run1] != 0 ){
00889 BlockMatrix resL, resU;
00890 returnvalue = point_constraints[run1]->getResiduum( resL, resU );
00891 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00892 DMatrix resL_;
00893 DMatrix resU_;
00894 resL.getSubBlock( 0, 0, resL_ );
00895 resU.getSubBlock( 0, 0, resU_ );
00896 residuumL.setDense( nc, 0, resL_ );
00897 residuumU.setDense( nc, 0, resU_ );
00898 nc++;
00899 }
00900 }
00901 }
00902
00903 lowerRes = residuumL;
00904 upperRes = residuumU;
00905
00906 return SUCCESSFUL_RETURN;
00907 }
00908
00909
00910 returnValue Constraint::getBoundResiduum( BlockMatrix &lowerRes,
00911 BlockMatrix &upperRes ){
00912
00913
00914 int run1;
00915 const int N = grid.getNumPoints();
00916
00917 lowerRes.init( 4*N+1, 1 );
00918 upperRes.init( 4*N+1, 1 );
00919
00920 for( run1 = 0; run1 < N; run1++ ){
00921
00922 lowerRes.setDense( run1, 0, residuumXL[run1] );
00923 upperRes.setDense( run1, 0, residuumXU[run1] );
00924
00925 lowerRes.setDense( N+run1, 0, residuumXAL[run1] );
00926 upperRes.setDense( N+run1, 0, residuumXAU[run1] );
00927
00928 lowerRes.setDense( 2*N+1+run1, 0, residuumUL[run1] );
00929 upperRes.setDense( 2*N+1+run1, 0, residuumUU[run1] );
00930
00931 lowerRes.setDense( 3*N+1+run1, 0, residuumWL[run1] );
00932 upperRes.setDense( 3*N+1+run1, 0, residuumWU[run1] );
00933 }
00934 lowerRes.setDense( 2*N, 0, residuumPL[0] );
00935 upperRes.setDense( 2*N, 0, residuumPU[0] );
00936
00937 return SUCCESSFUL_RETURN;
00938 }
00939
00940
00941 returnValue Constraint::getForwardSensitivities( BlockMatrix &D, int order ){
00942
00943 const int N = grid.getNumPoints();
00944
00945 returnValue returnvalue;
00946 BlockMatrix result;
00947
00948 result.init( getNumberOfBlocks(), 5*N );
00949
00950 int nc, run1, run2;
00951 nc = 0;
00952
00953
00954
00955
00956 if( boundary_constraint->getNC() != 0 ){
00957 BlockMatrix res;
00958 returnvalue = boundary_constraint->getForwardSensitivities( &res, order );
00959 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00960 DMatrix res_;
00961 for( run2 = 0; run2 < 5*N; run2++ ){
00962 res.getSubBlock( 0 , run2, res_ );
00963 if( res_.getDim() > 0 )
00964 result.setDense( nc, run2, res_ );
00965 }
00966 nc++;
00967 }
00968
00969
00970
00971
00972 if( coupled_path_constraint->getNC() != 0 ){
00973 BlockMatrix res;
00974 returnvalue = coupled_path_constraint->getForwardSensitivities( &res, order );
00975 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00976 DMatrix res_;
00977 for( run2 = 0; run2 < 5*N; run2++ ){
00978 res.getSubBlock( 0 , run2, res_ );
00979 if( res_.getDim() > 0 )
00980 result.setDense( nc, run2, res_ );
00981 }
00982 nc++;
00983 }
00984
00985
00986
00987
00988
00989 if( path_constraint->getNC() != 0 ){
00990 BlockMatrix res;
00991 returnvalue = path_constraint->getForwardSensitivities( &res, order );
00992 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
00993 DMatrix res_;
00994 for( run1 = 0; run1 < N; run1++ ){
00995 for( run2 = 0; run2 < 5*N; run2++ ){
00996 res.getSubBlock( run1, run2, res_ );
00997 if( res_.getDim() > 0 )
00998 result.setDense( nc , run2, res_ );
00999 }
01000 nc++;
01001 }
01002 }
01003
01004
01005
01006
01007
01008 if( algebraic_consistency_constraint->getNC() != 0 ){
01009 BlockMatrix res;
01010 returnvalue = algebraic_consistency_constraint->getForwardSensitivities( &res, order );
01011 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
01012 DMatrix res_;
01013 for( run1 = 0; run1 < N; run1++ ){
01014 for( run2 = 0; run2 < 5*N; run2++ ){
01015 res.getSubBlock( run1, run2, res_ );
01016 if( res_.getDim() > 0 )
01017 result.setDense( nc , run2, res_ );
01018 }
01019 nc++;
01020 }
01021 }
01022
01023
01024
01025
01026
01027
01028 if( point_constraints != 0 ){
01029 for( run1 = 0; run1 < (int) grid.getNumPoints(); run1++ ){
01030 if( point_constraints[run1] != 0 ){
01031 BlockMatrix res;
01032 returnvalue = point_constraints[run1]->getForwardSensitivities( &res, order );
01033 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
01034 DMatrix res_;
01035 for( run2 = 0; run2 < 5*N; run2++ ){
01036 res.getSubBlock( 0 , run2, res_ );
01037 if( res_.getDim() > 0 )
01038 result.setDense( nc, run2, res_ );
01039 }
01040 nc++;
01041 }
01042 }
01043 }
01044
01045 D = result;
01046
01047 return SUCCESSFUL_RETURN;
01048 }
01049
01050
01051 returnValue Constraint::getBackwardSensitivities( BlockMatrix &D, int order ){
01052
01053 const int N = grid.getNumPoints();
01054
01055 returnValue returnvalue;
01056 BlockMatrix result;
01057
01058 result.init( getNumberOfBlocks(), 5*N );
01059
01060 int nc, run1, run2;
01061 nc = 0;
01062
01063
01064
01065
01066
01067 if( boundary_constraint->getNC() != 0 ){
01068 BlockMatrix res;
01069 returnvalue = boundary_constraint->getBackwardSensitivities( &res, order );
01070 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
01071 DMatrix res_;
01072 for( run2 = 0; run2 < 5*N; run2++ ){
01073 res.getSubBlock( 0 , run2, res_ );
01074 if( res_.getDim() > 0 )
01075 result.setDense( nc, run2, res_ );
01076 }
01077 nc++;
01078 }
01079
01080
01081
01082
01083
01084 if( coupled_path_constraint->getNC() != 0 ){
01085 BlockMatrix res;
01086 returnvalue = coupled_path_constraint->getBackwardSensitivities( &res, order );
01087 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
01088 DMatrix res_;
01089 for( run2 = 0; run2 < 5*N; run2++ ){
01090 res.getSubBlock( 0 , run2, res_ );
01091 if( res_.getDim() > 0 )
01092 result.setDense( nc, run2, res_ );
01093 }
01094 nc++;
01095 }
01096
01097
01098
01099
01100
01101 if( path_constraint->getNC() != 0 ){
01102 BlockMatrix res;
01103 returnvalue = path_constraint->getBackwardSensitivities( &res, order );
01104 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
01105 DMatrix res_;
01106 for( run1 = 0; run1 < N; run1++ ){
01107 for( run2 = 0; run2 < 5*N; run2++ ){
01108 res.getSubBlock( run1, run2, res_ );
01109 if( res_.getDim() > 0 )
01110 result.setDense( nc , run2, res_ );
01111 }
01112 nc++;
01113 }
01114 }
01115
01116
01117
01118
01119
01120 if( algebraic_consistency_constraint->getNC() != 0 ){
01121 BlockMatrix res;
01122 returnvalue = algebraic_consistency_constraint->getBackwardSensitivities( &res, order );
01123 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
01124 DMatrix res_;
01125 for( run1 = 0; run1 < N; run1++ ){
01126 for( run2 = 0; run2 < 5*N; run2++ ){
01127 res.getSubBlock( run1, run2, res_ );
01128 if( res_.getDim() > 0 )
01129 result.setDense( nc , run2, res_ );
01130 }
01131 nc++;
01132 }
01133 }
01134
01135
01136
01137
01138
01139
01140 if( point_constraints != 0 ){
01141 for( run1 = 0; run1 < (int) grid.getNumPoints(); run1++ ){
01142 if( point_constraints[run1] != 0 ){
01143 BlockMatrix res;
01144 returnvalue = point_constraints[run1]->getBackwardSensitivities( &res, order );
01145 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOERROR(returnvalue);
01146 DMatrix res_;
01147 for( run2 = 0; run2 < 5*N; run2++ ){
01148 res.getSubBlock( 0 , run2, res_ );
01149 if( res_.getDim() > 0 )
01150 result.setDense( nc, run2, res_ );
01151 }
01152 nc++;
01153 }
01154 }
01155 }
01156
01157 D = result;
01158
01159 return SUCCESSFUL_RETURN;
01160 }
01161
01162
01163
01164 BooleanType Constraint::isEmpty() const{
01165
01166 if( nb == 0 &&
01167 boundary_constraint == 0 &&
01168 coupled_path_constraint == 0 &&
01169 path_constraint == 0 &&
01170 algebraic_consistency_constraint == 0 &&
01171 point_constraints == 0 ) return BT_TRUE;
01172
01173 return BT_FALSE;
01174 }
01175
01176
01177
01178
01179
01180
01181
01182 returnValue Constraint::add( const int index_, const double lb_,
01183 const Expression &arg, const double ub_ ){
01184
01185 if( index_ >= (int) grid.getNumPoints() ) return ACADOERROR(RET_INDEX_OUT_OF_BOUNDS);
01186 if( index_ < 0 ) return ACADOERROR(RET_INDEX_OUT_OF_BOUNDS);
01187
01188
01189
01190
01191 if( lb_ > ub_ + EPS ) return ACADOERROR(RET_INFEASIBLE_CONSTRAINT);
01192
01193 if( point_constraints[index_] == 0 )
01194 point_constraints[index_] = new PointConstraint(grid,index_);
01195
01196 return point_constraints[index_]->add( lb_, arg, ub_ );
01197 }
01198
01199
01200 returnValue Constraint::add( const double lb_, const Expression& arg1,
01201 const Expression& arg2, const double ub_ ){
01202
01203
01204
01205 if( lb_ > ub_ + EPS ) return ACADOERROR(RET_INFEASIBLE_CONSTRAINT);
01206
01207 return boundary_constraint->add( lb_, arg1, arg2, ub_ );
01208 }
01209
01210
01211 returnValue Constraint::getBounds( const OCPiterate& iter ){
01212
01213 returnValue returnvalue;
01214 returnvalue = BoxConstraint::getBounds( iter );
01215
01216 if( returnvalue != SUCCESSFUL_RETURN ) return ACADOWARNING(returnvalue);
01217
01218 if( point_constraints != 0 )
01219 {
01220 for( uint i=0; i<grid.getNumPoints(); ++i )
01221 if( point_constraints[i] != 0 )
01222 returnvalue = point_constraints[i]->getBounds( iter );
01223 }
01224
01225 return returnvalue;
01226 }
01227
01228 returnValue Constraint::getPathConstraints(Function& function_, DMatrix& lb_, DMatrix& ub_) const
01229 {
01230 return path_constraint->get(function_, lb_, ub_);
01231 }
01232
01233 returnValue Constraint::getPointConstraint(const unsigned index_, Function& function_, DMatrix& lb_, DMatrix& ub_) const
01234 {
01235 if (point_constraints[ index_ ] == 0)
01236 {
01237 Function tmp;
01238
01239 function_ = tmp;
01240
01241 lb_.init(0, 0);
01242 ub_.init(0, 0);
01243
01244 return SUCCESSFUL_RETURN;
01245 }
01246
01247 return point_constraints[ index_ ]->get(function_, lb_, ub_);
01248 }
01249
01250 CLOSE_NAMESPACE_ACADO
01251
01252