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
00034 #include <acado/variables_grid/variables_grid.hpp>
00035 #include <acado/variables_grid/matrix_variable.hpp>
00036
00037
00038 BEGIN_NAMESPACE_ACADO
00039
00040
00041
00042
00043
00044
00045
00046 VariablesGrid::VariablesGrid( ) : MatrixVariablesGrid( )
00047 {
00048 }
00049
00050
00051 VariablesGrid::VariablesGrid( uint _dim,
00052 const Grid& _grid,
00053 VariableType _type,
00054 const char** const _names,
00055 const char** const _units,
00056 const DVector* const _scaling,
00057 const DVector* const _lb,
00058 const DVector* const _ub,
00059 const BooleanType* const _autoInit
00060 ) : MatrixVariablesGrid( _dim,1,_grid,_type,_names,_units,_scaling,_lb,_ub,_autoInit )
00061 {
00062 }
00063
00064
00065 VariablesGrid::VariablesGrid( uint _dim,
00066 uint _nPoints,
00067 VariableType _type,
00068 const char** const _names,
00069 const char** const _units,
00070 const DVector* const _scaling,
00071 const DVector* const _lb,
00072 const DVector* const _ub,
00073 const BooleanType* const _autoInit
00074 ) : MatrixVariablesGrid( _dim,1,_nPoints,_type,_names,_units,_scaling,_lb,_ub,_autoInit )
00075 {
00076 }
00077
00078
00079 VariablesGrid::VariablesGrid( uint _dim,
00080 double _firstTime,
00081 double _lastTime,
00082 uint _nPoints,
00083 VariableType _type,
00084 const char** const _names,
00085 const char** const _units,
00086 const DVector* const _scaling,
00087 const DVector* const _lb,
00088 const DVector* const _ub,
00089 const BooleanType* const _autoInit
00090 ) : MatrixVariablesGrid( _dim,1,_firstTime,_lastTime,_nPoints,_type,_names,_units,_scaling,_lb,_ub,_autoInit )
00091 {
00092 }
00093
00094
00095 VariablesGrid::VariablesGrid( const DVector& arg,
00096 const Grid& _grid,
00097 VariableType _type
00098 ) : MatrixVariablesGrid( DMatrix(arg),_grid,_type )
00099 {
00100 }
00101
00102
00103 VariablesGrid::VariablesGrid( const DMatrix& arg,
00104 VariableType _type
00105 ) : MatrixVariablesGrid( arg.getNumCols()-1,1,arg.getNumRows(),_type )
00106 {
00107 uint i,j;
00108
00109 for( i=0; i<arg.getNumRows(); ++i )
00110 {
00111 setTime( i,arg( i,0 ) );
00112
00113 for( j=1; j<arg.getNumCols(); ++j )
00114 operator()( i,j-1 ) = arg( i,j );
00115 }
00116 }
00117
00118
00119 VariablesGrid::VariablesGrid( const VariablesGrid& rhs
00120 ) : MatrixVariablesGrid( rhs )
00121 {
00122 }
00123
00124
00125 VariablesGrid::VariablesGrid( const MatrixVariablesGrid& rhs
00126 ) : MatrixVariablesGrid( rhs )
00127 {
00128 ASSERT( rhs.getNumCols() <= 1 );
00129 }
00130
00131
00132
00133 VariablesGrid::~VariablesGrid( )
00134 {
00135 }
00136
00137
00138 VariablesGrid& VariablesGrid::operator=( const VariablesGrid& rhs )
00139 {
00140 if ( this != &rhs )
00141 {
00142 MatrixVariablesGrid::operator=( rhs );
00143 }
00144
00145 return *this;
00146 }
00147
00148
00149 VariablesGrid& VariablesGrid::operator=( const MatrixVariablesGrid& rhs )
00150 {
00151 ASSERT( rhs.getNumCols() <= 1 );
00152
00153 if ( this != &rhs )
00154 {
00155 MatrixVariablesGrid::operator=( rhs );
00156 }
00157
00158 return *this;
00159 }
00160
00161
00162 VariablesGrid& VariablesGrid::operator=( const DMatrix& rhs )
00163 {
00164 MatrixVariablesGrid::operator=( rhs );
00165 return *this;
00166 }
00167
00168
00169 VariablesGrid VariablesGrid::operator()( const uint rowIdx
00170 ) const
00171 {
00172 ASSERT( values != 0 );
00173 if ( rowIdx >= getNumRows( ) )
00174 {
00175 ACADOERROR( RET_INDEX_OUT_OF_BOUNDS );
00176 return VariablesGrid();
00177 }
00178
00179 Grid tmpGrid;
00180 getGrid( tmpGrid );
00181
00182 VariablesGrid rowGrid( 1,tmpGrid,getType( ) );
00183
00184 for( uint run1 = 0; run1 < getNumPoints(); run1++ )
00185 rowGrid( run1,0 ) = values[run1]->operator()( rowIdx,0 );
00186
00187 return rowGrid;
00188 }
00189
00190
00191 VariablesGrid VariablesGrid::operator[]( const uint pointIdx
00192 ) const
00193 {
00194 ASSERT( values != 0 );
00195 if ( pointIdx >= getNumPoints( ) )
00196 {
00197 ACADOERROR( RET_INVALID_ARGUMENTS );
00198 return VariablesGrid();
00199 }
00200
00201 VariablesGrid pointGrid;
00202 pointGrid.addMatrix( *(values[pointIdx]),getTime( pointIdx ) );
00203
00204 return pointGrid;
00205 }
00206
00207
00208 returnValue VariablesGrid::init( )
00209 {
00210 return MatrixVariablesGrid::init( );
00211 }
00212
00213
00214 returnValue VariablesGrid::init( uint _dim,
00215 const Grid& _grid,
00216 VariableType _type,
00217 const char** const _names,
00218 const char** const _units,
00219 const DVector* const _scaling,
00220 const DVector* const _lb,
00221 const DVector* const _ub,
00222 const BooleanType* const _autoInit
00223 )
00224 {
00225 return MatrixVariablesGrid::init( _dim,1,_grid,_type,_names,_units,_scaling,_lb,_ub,_autoInit );
00226 }
00227
00228
00229 returnValue VariablesGrid::init( uint _dim,
00230 uint _nPoints,
00231 VariableType _type,
00232 const char** const _names,
00233 const char** const _units,
00234 const DVector* const _scaling,
00235 const DVector* const _lb,
00236 const DVector* const _ub,
00237 const BooleanType* const _autoInit
00238 )
00239 {
00240 return MatrixVariablesGrid::init( _dim,1,_nPoints,_type,_names,_units,_scaling,_lb,_ub,_autoInit );
00241 }
00242
00243
00244 returnValue VariablesGrid::init( uint _dim,
00245 double _firstTime,
00246 double _lastTime,
00247 uint _nPoints,
00248 VariableType _type,
00249 const char** const _names,
00250 const char** const _units,
00251 const DVector* const _scaling,
00252 const DVector* const _lb,
00253 const DVector* const _ub,
00254 const BooleanType* const _autoInit
00255 )
00256 {
00257 return MatrixVariablesGrid::init( _dim,1,_firstTime,_lastTime,_nPoints,_type,_names,_units,_scaling,_lb,_ub,_autoInit );
00258 }
00259
00260
00261 returnValue VariablesGrid::init( const DVector& arg,
00262 const Grid& _grid,
00263 VariableType _type
00264 )
00265 {
00266 return MatrixVariablesGrid::init( DMatrix(arg),_grid,_type );
00267 }
00268
00269
00270
00271 returnValue VariablesGrid::addVector( const DVector& newVector,
00272 double newTime
00273 )
00274 {
00275 return MatrixVariablesGrid::addMatrix( DMatrix(newVector),newTime );
00276 }
00277
00278
00279 returnValue VariablesGrid::setVector( uint pointIdx,
00280 const DVector& _values
00281 )
00282 {
00283 if ( pointIdx >= getNumPoints( ) )
00284 return ACADOERROR( RET_INDEX_OUT_OF_BOUNDS );
00285
00286 if ( _values.getDim( ) != getNumRows( pointIdx ) )
00287 return ACADOERROR( RET_VECTOR_DIMENSION_MISMATCH );
00288
00289 for( uint j=0; j<getNumRows( ); ++j )
00290 operator()( pointIdx,j ) = _values( j );
00291
00292 return SUCCESSFUL_RETURN;
00293 }
00294
00295
00296 returnValue VariablesGrid::setAllVectors( const DVector& _values
00297 )
00298 {
00299 for( uint i = 0; i < getNumPoints(); i++ )
00300 ACADO_TRY( setVector( i,_values ) );
00301
00302 return SUCCESSFUL_RETURN;
00303 }
00304
00305
00306 DVector VariablesGrid::getVector( uint pointIdx
00307 ) const
00308 {
00309 if ( ( values == 0 ) || ( pointIdx >= getNumPoints() ) )
00310 return emptyVector;
00311
00312 return values[pointIdx]->getCol( 0 );
00313 }
00314
00315
00316 DVector VariablesGrid::getFirstVector( ) const
00317 {
00318 if ( getNumPoints( ) <= 0 )
00319 return emptyVector;
00320
00321 return getVector( 0 );
00322 }
00323
00324
00325 DVector VariablesGrid::getLastVector( ) const
00326 {
00327 if ( getNumPoints( ) <= 0 )
00328 return emptyVector;
00329
00330 return getVector( getNumPoints( )-1 );
00331 }
00332
00333
00334
00335 VariablesGrid& VariablesGrid::shiftTimes( double timeShift
00336 )
00337 {
00338 Grid::shiftTimes( timeShift );
00339 return *this;
00340 }
00341
00342
00343 VariablesGrid& VariablesGrid::shiftBackwards( DVector lastValue )
00344 {
00345
00346 if( lastValue.isEmpty() == BT_FALSE ){
00347
00348 DMatrix aux( lastValue.getDim(), 1 );
00349 aux.setCol( 0, lastValue );
00350
00351 MatrixVariablesGrid::shiftBackwards( aux );
00352 return *this;
00353 }
00354
00355
00356 MatrixVariablesGrid::shiftBackwards( );
00357 return *this;
00358 }
00359
00360
00361
00362 returnValue VariablesGrid::appendTimes( const VariablesGrid& arg,
00363 MergeMethod _mergeMethod
00364 )
00365 {
00366
00367 if ( arg.getNumPoints( ) == 0 )
00368 return SUCCESSFUL_RETURN;
00369
00370 if ( getNumPoints( ) == 0 )
00371 {
00372 *this = arg;
00373 return SUCCESSFUL_RETURN;
00374 }
00375
00376
00377 if ( acadoIsGreater( arg.getFirstTime( ),getLastTime( ) ) == BT_FALSE )
00378 return ACADOERROR( RET_INVALID_ARGUMENTS );
00379
00380 if ( acadoIsEqual( getLastTime( ),arg.getFirstTime( ) ) == BT_FALSE )
00381 {
00382
00383 for( uint i=0; i<arg.getNumPoints( ); ++i )
00384 addMatrix( *(arg.values[i]),arg.getTime( i ) );
00385 }
00386 else
00387 {
00388
00389 switch ( _mergeMethod )
00390 {
00391 case MM_KEEP:
00392 break;
00393
00394 case MM_REPLACE:
00395 setVector( getLastIndex(),arg.getFirstVector( ) );
00396 break;
00397
00398 case MM_DUPLICATE:
00399 addMatrix( *(arg.values[0]),arg.getTime( 0 ) );
00400 break;
00401 }
00402
00403
00404 for( uint i=1; i<arg.getNumPoints( ); ++i )
00405 addMatrix( *(arg.values[i]),arg.getTime( i ) );
00406 }
00407
00408 return SUCCESSFUL_RETURN;
00409 }
00410
00411
00412 returnValue VariablesGrid::appendTimes( const DMatrix& arg,
00413 MergeMethod _mergeMethod
00414 )
00415 {
00416 VariablesGrid tmp = arg;
00417 return appendTimes( tmp,_mergeMethod );
00418 }
00419
00420
00421 returnValue VariablesGrid::appendValues( const VariablesGrid& arg )
00422 {
00423
00424 if ( getNumPoints( ) == 0 )
00425 {
00426 *this = arg;
00427 return SUCCESSFUL_RETURN;
00428 }
00429
00430 if ( getNumPoints( ) != arg.getNumPoints( ) )
00431 return ACADOERROR( RET_INVALID_ARGUMENTS );
00432
00433 DVector tmp1,tmp2;
00434
00435 for( uint i=0; i<getNumPoints(); ++i )
00436 {
00437 values[i]->appendRows( *(arg.values[i]) );
00438 values[i]->appendSettings( *(arg.values[i]) );
00439 }
00440
00441 return SUCCESSFUL_RETURN;
00442 }
00443
00444
00445
00446 returnValue VariablesGrid::merge( const VariablesGrid& arg,
00447 MergeMethod _mergeMethod,
00448 BooleanType keepOverlap
00449 )
00450 {
00451 if ( ( keepOverlap == BT_FALSE ) && ( _mergeMethod == MM_DUPLICATE ) )
00452 return ACADOERROR( RET_INVALID_ARGUMENTS );
00453
00454
00455 if ( arg.getNumPoints( ) == 0 )
00456 return SUCCESSFUL_RETURN;
00457
00458 if ( getNumPoints( ) == 0 )
00459 {
00460 *this = arg;
00461 return SUCCESSFUL_RETURN;
00462 }
00463
00464
00465 if ( acadoIsSmaller( getLastTime( ),arg.getFirstTime( ) ) == BT_TRUE )
00466 return appendTimes( arg,_mergeMethod );
00467
00468
00469
00470 VariablesGrid mergedGrid;
00471 uint j = 0;
00472 BooleanType overlapping = BT_FALSE;
00473
00474 for( uint i=0; i<getNumPoints( ); ++i )
00475 {
00476 if ( keepOverlap == BT_FALSE )
00477 overlapping = arg.isInInterval( getTime(i) );
00478
00479
00480
00481 while ( ( j < arg.getNumPoints( ) ) &&
00482 ( acadoIsStrictlySmaller( arg.getTime( j ),getTime( i ) ) == BT_TRUE ) )
00483 {
00484 if ( ( overlapping == BT_FALSE ) ||
00485 ( ( overlapping == BT_TRUE ) && ( _mergeMethod == MM_REPLACE ) ) )
00486 {
00487 mergedGrid.addMatrix( *(arg.values[j]),arg.getTime( j ) );
00488 }
00489
00490 ++j;
00491 }
00492
00493
00494 if ( acadoIsEqual( arg.getTime( j ),getTime( i ) ) == BT_TRUE )
00495 {
00496 switch ( _mergeMethod )
00497 {
00498 case MM_KEEP:
00499 mergedGrid.addMatrix( *(values[i]),getTime( i ) );
00500 break;
00501
00502 case MM_REPLACE:
00503 mergedGrid.addMatrix( *(arg.values[j]),arg.getTime( j ) );
00504 break;
00505
00506 case MM_DUPLICATE:
00507 mergedGrid.addMatrix( *(values[i]),getTime( i ) );
00508 mergedGrid.addMatrix( *(arg.values[j]),arg.getTime( j ) );
00509 break;
00510 }
00511 ++j;
00512 }
00513 else
00514 {
00515
00516 if ( ( overlapping == BT_FALSE ) ||
00517 ( ( overlapping == BT_TRUE ) && ( _mergeMethod == MM_KEEP ) ) )
00518 {
00519 mergedGrid.addMatrix( *(values[i]),getTime( i ) );
00520 }
00521 }
00522 }
00523
00524
00525 while ( j < arg.getNumPoints( ) )
00526 {
00527 if ( acadoIsStrictlyGreater( arg.getTime(j),getLastTime() ) == BT_TRUE )
00528 mergedGrid.addMatrix( *(arg.values[j]),arg.getTime( j ) );
00529
00530 ++j;
00531 }
00532
00533
00534 *this = mergedGrid;
00535
00536 return SUCCESSFUL_RETURN;
00537 }
00538
00539
00540
00541
00542 VariablesGrid VariablesGrid::getTimeSubGrid( uint startIdx,
00543 uint endIdx
00544 ) const
00545 {
00546 VariablesGrid newVariablesGrid;
00547
00548 if ( ( startIdx >= getNumPoints( ) ) || ( endIdx >= getNumPoints( ) ) )
00549 return newVariablesGrid;
00550
00551 if ( startIdx > endIdx )
00552 return newVariablesGrid;
00553
00554 for( uint i=startIdx; i<=endIdx; ++i )
00555 newVariablesGrid.addMatrix( *(values[i]),getTime( i ) );
00556
00557 return newVariablesGrid;
00558 }
00559
00560
00561 VariablesGrid VariablesGrid::getTimeSubGrid( double startTime,
00562 double endTime
00563 ) const
00564 {
00565 uint startIdx = getCeilIndex( startTime );
00566 uint endIdx = getFloorIndex( endTime );
00567
00568 VariablesGrid newVariablesGrid;
00569
00570 if ( ( isInInterval( startTime ) == BT_FALSE ) || ( isInInterval( endTime ) == BT_FALSE ) )
00571 return newVariablesGrid;
00572
00573 if ( ( startIdx >= getNumPoints( ) ) || ( endIdx >= getNumPoints( ) ) )
00574 return newVariablesGrid;
00575
00576
00577
00578
00579
00580 if ( ( hasTime( startTime ) == BT_FALSE ) && ( startIdx > 0 ) )
00581 newVariablesGrid.addMatrix( *(values[ startIdx-1 ]),startTime );
00582
00583 for( uint i=startIdx; i<=endIdx; ++i )
00584 newVariablesGrid.addMatrix( *(values[i]),getTime( i ) );
00585
00586 if ( hasTime( endTime ) == BT_FALSE )
00587 newVariablesGrid.addMatrix( *(values[ endIdx ]),endTime );
00588
00589 return newVariablesGrid;
00590 }
00591
00592
00593 VariablesGrid VariablesGrid::getValuesSubGrid( uint startIdx,
00594 uint endIdx
00595 ) const
00596 {
00597 VariablesGrid newVariablesGrid;
00598
00599 if ( ( startIdx >= getNumValues( ) ) || ( endIdx >= getNumValues( ) ) )
00600 return newVariablesGrid;
00601
00602 if ( startIdx > endIdx )
00603 return newVariablesGrid;
00604
00605 for( uint i=0; i<getNumPoints( ); ++i )
00606 newVariablesGrid.addMatrix( values[i]->getRows( startIdx,endIdx ),getTime( i ) );
00607
00608 return newVariablesGrid;
00609 }
00610
00611
00612
00613 returnValue VariablesGrid::getSum( DVector& sum
00614 ) const
00615 {
00616 sum.setZero();
00617
00618 for( uint i=0; i<getNumPoints( ); ++i )
00619 sum += getVector( i );
00620
00621 return SUCCESSFUL_RETURN;
00622 }
00623
00624
00625 returnValue VariablesGrid::getIntegral( InterpolationMode mode,
00626 DVector& value
00627 ) const
00628 {
00629 value.setZero();
00630
00631 switch( mode )
00632 {
00633 case IM_CONSTANT:
00634 for( uint i=0; i<getNumIntervals( ); ++i )
00635 {
00636 for( uint j=0; j<getNumValues( ); ++j )
00637 {
00638
00639 value(j) += getIntervalLength( i ) * operator()( i,j );
00640 }
00641 }
00642 break;
00643
00644 case IM_LINEAR:
00645 for( uint i=0; i<getNumIntervals( ); ++i )
00646 {
00647 for( uint j=0; j<getNumValues( ); ++j )
00648 {
00649
00650 value(j) += getIntervalLength( i ) * ( operator()( i,j ) + operator()( i+1,j ) ) / 2.0;
00651 }
00652 }
00653 break;
00654
00655 default:
00656 return ACADOERROR( RET_NOT_YET_IMPLEMENTED );
00657 }
00658
00659 return SUCCESSFUL_RETURN;
00660 }
00661
00662
00663
00664
00665
00666 returnValue VariablesGrid::initializeFromBounds( )
00667 {
00668 uint run1, run2;
00669
00670 for( run1 = 0; run1 < getNumPoints(); run1++ ){
00671 for( run2 = 0; run2 < getNumValues(); run2++ ){
00672
00673 if( fabs( getLowerBound(run1,run2) ) < 0.999*INFTY &&
00674 fabs( getUpperBound(run1,run2) ) < 0.999*INFTY ){
00675
00676 operator()(run1,run2) = 0.5*( getLowerBound(run1,run2) + getUpperBound(run1,run2) );
00677
00678 }
00679
00680 if( fabs( getLowerBound(run1,run2) ) >= 0.999*INFTY &&
00681 fabs( getUpperBound(run1,run2) ) < 0.999*INFTY ){
00682
00683 operator()(run1,run2) = getUpperBound(run1,run2);
00684 }
00685
00686 if( fabs( getLowerBound(run1,run2) ) < 0.999*INFTY &&
00687 fabs( getUpperBound(run1,run2) ) >= 0.999*INFTY ){
00688
00689 operator()(run1,run2) = getLowerBound(run1,run2);
00690 }
00691
00692 if( fabs( getLowerBound(run1,run2) ) >= 0.999*INFTY &&
00693 fabs( getUpperBound(run1,run2) ) >= 0.999*INFTY ){
00694
00695 operator()(run1,run2) = 0.0;
00696 }
00697 }
00698 }
00699
00700 return SUCCESSFUL_RETURN;
00701 }
00702
00703 VariablesGrid::operator DMatrix() const
00704 {
00705 DMatrix tmp(getNumPoints( ), getNumValues( ) + 1);
00706
00707 for (uint run1 = 0; run1 < getNumPoints(); ++run1)
00708 {
00709 tmp(run1, 0) = getTime(run1);
00710
00711 for (uint run2 = 0; run2 < getNumValues(); ++run2)
00712 tmp(run1, 1 + run2) = operator()(run1, run2);
00713 }
00714
00715 return tmp;
00716 }
00717
00718
00719 CLOSE_NAMESPACE_ACADO
00720
00721
00722
00723
00724