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/matrix_variables_grid.hpp>
00035 #include <acado/variables_grid/matrix_variable.hpp>
00036 #include <acado/variables_grid/variables_grid.hpp>
00037
00038 #include <iomanip>
00039
00040 using namespace std;
00041
00042 BEGIN_NAMESPACE_ACADO
00043
00044
00045
00046
00047
00048 MatrixVariablesGrid::MatrixVariablesGrid( ) : Grid( )
00049 {
00050 values = 0;
00051 }
00052
00053
00054 MatrixVariablesGrid::MatrixVariablesGrid( uint _nRows,
00055 uint _nCols,
00056 const Grid& _grid,
00057 VariableType _type,
00058 const char** const _names,
00059 const char** const _units,
00060 const DVector* const _scaling,
00061 const DVector* const _lb,
00062 const DVector* const _ub,
00063 const BooleanType* const _autoInit
00064 ) : Grid( )
00065 {
00066 values = 0;
00067 init( _nRows,_nCols,_grid,_type,_names,_units,_scaling,_lb,_ub,_autoInit );
00068 }
00069
00070
00071 MatrixVariablesGrid::MatrixVariablesGrid( uint _nRows,
00072 uint _nCols,
00073 uint _nPoints,
00074 VariableType _type,
00075 const char** const _names,
00076 const char** const _units,
00077 const DVector* const _scaling,
00078 const DVector* const _lb,
00079 const DVector* const _ub,
00080 const BooleanType* const _autoInit
00081 ) : Grid( )
00082 {
00083 values = 0;
00084 init( _nRows,_nCols,_nPoints,_type,_names,_units,_scaling,_lb,_ub,_autoInit );
00085 }
00086
00087
00088 MatrixVariablesGrid::MatrixVariablesGrid( uint _nRows,
00089 uint _nCols,
00090 double _firstTime,
00091 double _lastTime,
00092 uint _nPoints,
00093 VariableType _type,
00094 const char** const _names,
00095 const char** const _units,
00096 const DVector* const _scaling,
00097 const DVector* const _lb,
00098 const DVector* const _ub,
00099 const BooleanType* const _autoInit
00100 ) : Grid( )
00101 {
00102 values = 0;
00103 init( _nRows,_nCols,_firstTime,_lastTime,_nPoints,_type,_names,_units,_scaling,_lb,_ub,_autoInit );
00104 }
00105
00106
00107 MatrixVariablesGrid::MatrixVariablesGrid( const DMatrix& arg,
00108 const Grid& _grid,
00109 VariableType _type
00110 ) : Grid( )
00111 {
00112 values = 0;
00113 init( arg,_grid,_type );
00114 }
00115
00116 MatrixVariablesGrid::MatrixVariablesGrid( const MatrixVariablesGrid& rhs
00117 ) : Grid( rhs )
00118 {
00119 if ( nPoints > 0 )
00120 values = (MatrixVariable**) calloc( nPoints,sizeof(MatrixVariable*) );
00121 else
00122 values = 0;
00123
00124 for( uint i=0; i<nPoints; ++i )
00125 values[i] = new MatrixVariable( *(rhs.values[i]) );
00126 }
00127
00128
00129 MatrixVariablesGrid::~MatrixVariablesGrid( )
00130 {
00131 clearValues( );
00132 }
00133
00134
00135
00136 MatrixVariablesGrid& MatrixVariablesGrid::operator=( const MatrixVariablesGrid& rhs
00137 )
00138 {
00139 if ( this != &rhs )
00140 {
00141 clearValues( );
00142
00143 Grid::operator=( rhs );
00144
00145 if ( nPoints > 0 )
00146 values = (MatrixVariable**) calloc( nPoints,sizeof(MatrixVariable*) );
00147 else
00148 values = 0;
00149
00150 for( uint i=0; i<nPoints; ++i )
00151 values[i] = new MatrixVariable( *(rhs.values[i]) );
00152 }
00153
00154 return *this;
00155 }
00156
00157
00158 MatrixVariablesGrid& MatrixVariablesGrid::operator=( const DMatrix& rhs
00159 )
00160 {
00161 init( rhs.getNumCols()-1,1,rhs.getNumRows( ),getType() );
00162
00163 for( uint i=0; i<nPoints; ++i )
00164 {
00165 setTime( rhs( i,0 ) );
00166
00167 for( uint j=0; j<rhs.getNumCols( )-1; ++j )
00168 operator()( i,j,0 ) = rhs( i,j+1 );
00169 }
00170
00171 return *this;
00172 }
00173
00174
00175 returnValue MatrixVariablesGrid::init( )
00176 {
00177 clearValues( );
00178 Grid::init( );
00179
00180 return SUCCESSFUL_RETURN;
00181 }
00182
00183
00184 returnValue MatrixVariablesGrid::init( uint _nRows,
00185 uint _nCols,
00186 const Grid& _grid,
00187 VariableType _type,
00188 const char** const _names,
00189 const char** const _units,
00190 const DVector* const _scaling,
00191 const DVector* const _lb,
00192 const DVector* const _ub,
00193 const BooleanType* const _autoInit
00194 )
00195 {
00196 clearValues( );
00197 Grid::init( _grid );
00198
00199 if ( nPoints > 0 )
00200 values = (MatrixVariable**) calloc( nPoints,sizeof(MatrixVariable*) );
00201 else
00202 values = 0;
00203
00204 return initMatrixVariables( _nRows,_nCols,_type,_names,_units,_scaling,_lb,_ub,_autoInit );
00205 }
00206
00207
00208 returnValue MatrixVariablesGrid::init( uint _nRows,
00209 uint _nCols,
00210 uint _nPoints,
00211 VariableType _type,
00212 const char** const _names,
00213 const char** const _units,
00214 const DVector* const _scaling,
00215 const DVector* const _lb,
00216 const DVector* const _ub,
00217 const BooleanType* const _autoInit
00218 )
00219 {
00220 clearValues( );
00221 Grid::init( _nPoints );
00222
00223 if ( nPoints > 0 )
00224 values = (MatrixVariable**) calloc( nPoints,sizeof(MatrixVariable*) );
00225 else
00226 values = 0;
00227
00228 return initMatrixVariables( _nRows,_nCols,_type,_names,_units,_scaling,_lb,_ub,_autoInit );
00229 }
00230
00231
00232 returnValue MatrixVariablesGrid::init( uint _nRows,
00233 uint _nCols,
00234 double _firstTime,
00235 double _lastTime,
00236 uint _nPoints,
00237 VariableType _type,
00238 const char** const _names,
00239 const char** const _units,
00240 const DVector* const _scaling,
00241 const DVector* const _lb,
00242 const DVector* const _ub,
00243 const BooleanType* const _autoInit
00244 )
00245 {
00246 clearValues( );
00247 Grid::init( _firstTime,_lastTime,_nPoints );
00248
00249 if ( nPoints > 0 )
00250 values = (MatrixVariable**) calloc( nPoints,sizeof(MatrixVariable*) );
00251 else
00252 values = 0;
00253
00254 return initMatrixVariables( _nRows,_nCols,_type,_names,_units,_scaling,_lb,_ub,_autoInit );
00255 }
00256
00257
00258 returnValue MatrixVariablesGrid::init( const DMatrix& arg,
00259 const Grid& _grid,
00260 VariableType _type
00261 )
00262 {
00263 clearValues( );
00264 Grid::operator=( _grid );
00265
00266 if ( nPoints > 0 )
00267 values = (MatrixVariable**) calloc( nPoints,sizeof(MatrixVariable*) );
00268 else
00269 values = 0;
00270
00271 for( uint i=0; i<nPoints; ++i )
00272 values[i] = new MatrixVariable( arg );
00273
00274 return SUCCESSFUL_RETURN;
00275 }
00276
00277
00278
00279 returnValue MatrixVariablesGrid::addMatrix( const DMatrix& newMatrix,
00280 double newTime
00281 )
00282 {
00283 return addMatrix( MatrixVariable(newMatrix),newTime );
00284 }
00285
00286
00287
00288 returnValue MatrixVariablesGrid::setMatrix( uint pointIdx,
00289 const DMatrix& _value
00290 ) const
00291 {
00292 ASSERT( values != 0 );
00293
00294 if ( pointIdx >= getNumPoints( ) )
00295 return ACADOERROR( RET_INDEX_OUT_OF_BOUNDS );
00296
00297 *(values[pointIdx]) = _value;
00298
00299 return SUCCESSFUL_RETURN;
00300 }
00301
00302
00303 returnValue MatrixVariablesGrid::setAllMatrices( const DMatrix& _values
00304 )
00305 {
00306 for( uint i = 0; i < getNumPoints(); i++ )
00307 ACADO_TRY( setMatrix( i,_values ) );
00308
00309 return SUCCESSFUL_RETURN;
00310 }
00311
00312
00313 DMatrix MatrixVariablesGrid::getMatrix( uint pointIdx
00314 ) const
00315 {
00316 ASSERT( values != 0 );
00317
00318 if ( pointIdx >= getNumPoints( ) )
00319 return emptyMatrix;
00320
00321 return values[pointIdx]->getMatrix( );
00322 }
00323
00324
00325 DMatrix MatrixVariablesGrid::getFirstMatrix( ) const
00326 {
00327 if ( getNumPoints( ) <= 0 )
00328 return emptyMatrix;
00329
00330 return getMatrix( 0 );
00331 }
00332
00333
00334 DMatrix MatrixVariablesGrid::getLastMatrix( ) const
00335 {
00336 if ( getNumPoints( ) <= 0 )
00337 return emptyMatrix;
00338
00339 return getMatrix( getNumPoints( )-1 );
00340 }
00341
00342
00343
00344 returnValue MatrixVariablesGrid::appendTimes( const MatrixVariablesGrid& arg,
00345 MergeMethod _mergeMethod
00346 )
00347 {
00348 if ( arg.getNumPoints( ) == 0 )
00349 return SUCCESSFUL_RETURN;
00350
00351 if ( acadoIsGreater( getLastTime( ),arg.getFirstTime( ) ) == BT_TRUE )
00352 return ACADOERROR( RET_INVALID_ARGUMENTS );
00353
00354 if ( acadoIsEqual( getLastTime( ),arg.getFirstTime( ) ) == BT_FALSE )
00355 {
00356
00357 for( uint i=0; i<arg.getNumPoints( ); ++i )
00358 addMatrix( *(arg.values[i]),arg.getTime( i ) );
00359 }
00360 else
00361 {
00362
00363 switch ( _mergeMethod )
00364 {
00365 case MM_KEEP:
00366 break;
00367
00368 case MM_REPLACE:
00369 setMatrix( getLastIndex(),arg.getFirstMatrix( ) );
00370 break;
00371
00372 case MM_DUPLICATE:
00373 addMatrix( *(arg.values[0]),arg.getTime( 0 ) );
00374 break;
00375 }
00376
00377
00378 for( uint i=1; i<arg.getNumPoints( ); ++i )
00379 addMatrix( *(arg.values[i]),arg.getTime( i ) );
00380 }
00381
00382 return SUCCESSFUL_RETURN;
00383 }
00384
00385
00386 returnValue MatrixVariablesGrid::appendValues( const MatrixVariablesGrid& arg )
00387 {
00388 if ( getNumPoints( ) != arg.getNumPoints( ) )
00389 return ACADOERROR( RET_INVALID_ARGUMENTS );
00390
00391 DVector tmp1,tmp2;
00392
00393 for( uint i=0; i<getNumPoints(); ++i )
00394 {
00395 values[i]->appendRows( *(arg.values[i]) );
00396 values[i]->appendSettings( *(arg.values[i]) );
00397 }
00398
00399 return SUCCESSFUL_RETURN;
00400 }
00401
00402
00403
00404 returnValue MatrixVariablesGrid::merge( const MatrixVariablesGrid& arg,
00405 MergeMethod _mergeMethod,
00406 BooleanType keepOverlap
00407 )
00408 {
00409 if ( ( keepOverlap == BT_FALSE ) && ( _mergeMethod == MM_DUPLICATE ) )
00410 return ACADOERROR( RET_INVALID_ARGUMENTS );
00411
00412
00413 if ( arg.getNumPoints( ) == 0 )
00414 return SUCCESSFUL_RETURN;
00415
00416 if ( getNumPoints( ) == 0 )
00417 {
00418 *this = arg;
00419 return SUCCESSFUL_RETURN;
00420 }
00421
00422
00423 if ( acadoIsSmaller( getLastTime( ),arg.getFirstTime( ) ) == BT_TRUE )
00424 return appendTimes( arg,_mergeMethod );
00425
00426
00427
00428 MatrixVariablesGrid mergedGrid;
00429 uint j = 0;
00430 BooleanType overlapping = BT_FALSE;
00431
00432 for( uint i=0; i<getNumPoints( ); ++i )
00433 {
00434 if ( keepOverlap == BT_FALSE )
00435 overlapping = arg.isInInterval( getTime(i) );
00436
00437
00438
00439 while ( ( j < arg.getNumPoints( ) ) &&
00440 ( acadoIsStrictlySmaller( arg.getTime( j ),getTime( i ) ) == BT_TRUE ) )
00441 {
00442 if ( ( overlapping == BT_FALSE ) ||
00443 ( ( overlapping == BT_TRUE ) && ( _mergeMethod == MM_REPLACE ) ) )
00444 {
00445 mergedGrid.addMatrix( *(arg.values[j]),arg.getTime( j ) );
00446 }
00447
00448 ++j;
00449 }
00450
00451
00452 if ( acadoIsEqual( arg.getTime( j ),getTime( i ) ) == BT_TRUE )
00453 {
00454 switch ( _mergeMethod )
00455 {
00456 case MM_KEEP:
00457 mergedGrid.addMatrix( *(values[i]),getTime( i ) );
00458 break;
00459
00460 case MM_REPLACE:
00461 mergedGrid.addMatrix( *(arg.values[j]),arg.getTime( j ) );
00462 break;
00463
00464 case MM_DUPLICATE:
00465 mergedGrid.addMatrix( *(values[i]),getTime( i ) );
00466 mergedGrid.addMatrix( *(arg.values[j]),arg.getTime( j ) );
00467 break;
00468 }
00469 ++j;
00470 }
00471 else
00472 {
00473
00474 if ( ( overlapping == BT_FALSE ) ||
00475 ( ( overlapping == BT_TRUE ) && ( _mergeMethod == MM_KEEP ) ) )
00476 {
00477 mergedGrid.addMatrix( *(values[i]),getTime( i ) );
00478 }
00479 }
00480 }
00481
00482
00483 while ( j < arg.getNumPoints( ) )
00484 {
00485 if ( acadoIsStrictlyGreater( arg.getTime(j),getLastTime() ) == BT_TRUE )
00486 mergedGrid.addMatrix( *(arg.values[j]),arg.getTime( j ) );
00487
00488 ++j;
00489 }
00490
00491
00492 *this = mergedGrid;
00493
00494 return SUCCESSFUL_RETURN;
00495 }
00496
00497
00498
00499 MatrixVariablesGrid MatrixVariablesGrid::getTimeSubGrid( uint startIdx,
00500 uint endIdx
00501 ) const
00502 {
00503 MatrixVariablesGrid newVariablesGrid;
00504
00505 if ( ( startIdx >= getNumPoints( ) ) || ( endIdx >= getNumPoints( ) ) )
00506 return newVariablesGrid;
00507
00508 if ( startIdx > endIdx )
00509 return newVariablesGrid;
00510
00511 for( uint i=startIdx; i<=endIdx; ++i )
00512 newVariablesGrid.addMatrix( *(values[i]),getTime( i ) );
00513
00514 return newVariablesGrid;
00515 }
00516
00517
00518 MatrixVariablesGrid MatrixVariablesGrid::getValuesSubGrid( uint startIdx,
00519 uint endIdx
00520 ) const
00521 {
00522 MatrixVariablesGrid newVariablesGrid;
00523
00524 if ( ( startIdx >= getNumValues( ) ) || ( endIdx >= getNumValues( ) ) )
00525 return newVariablesGrid;
00526
00527 if ( startIdx > endIdx )
00528 return newVariablesGrid;
00529
00530 for( uint i=0; i<getNumPoints( ); ++i )
00531 newVariablesGrid.addMatrix( values[i]->getRows( startIdx,endIdx ),getTime( i ) );
00532
00533 return newVariablesGrid;
00534 }
00535
00536
00537
00538 returnValue MatrixVariablesGrid::refineGrid( const Grid& arg,
00539 InterpolationMode mode
00540 )
00541 {
00542
00543 if ( this->isEmpty( ) == BT_TRUE )
00544 return SUCCESSFUL_RETURN;
00545
00546 *this = getRefinedGrid( arg,mode );
00547
00548 if ( this->isEmpty( ) == BT_TRUE )
00549 return ACADOERROR( RET_INVALID_ARGUMENTS );
00550 else
00551 return SUCCESSFUL_RETURN;
00552 }
00553
00554
00555 returnValue MatrixVariablesGrid::coarsenGrid( const Grid& arg
00556 )
00557 {
00558
00559 if ( this->isEmpty( ) == BT_TRUE )
00560 return SUCCESSFUL_RETURN;
00561
00562 *this = getCoarsenedGrid( arg );
00563
00564 if ( this->isEmpty( ) == BT_TRUE)
00565 return ACADOERROR( RET_INVALID_ARGUMENTS );
00566 else
00567 return SUCCESSFUL_RETURN;
00568 }
00569
00570
00571 MatrixVariablesGrid MatrixVariablesGrid::getRefinedGrid( const Grid& arg,
00572 InterpolationMode mode
00573 ) const
00574 {
00575 MatrixVariablesGrid tmp;
00576
00577
00578 if ( this->isEmpty( ) == BT_TRUE )
00579 return tmp;
00580
00581 int count = -1;
00582
00583
00584 if ( Grid::operator==( arg ) == BT_TRUE )
00585 return *this;
00586
00587
00588
00589
00590 if ( mode != IM_CONSTANT )
00591 return tmp;
00592
00593 for( uint i=0; i<arg.getNumPoints( ); ++i )
00594 {
00595 if ( hasTime( arg.getTime( i ) ) == BT_TRUE )
00596 count = acadoMin( count+1,(int)getNumPoints()-1 );
00597
00598 if ( count < 0 )
00599 tmp.addMatrix( *(values[0]),arg.getTime( i ) );
00600 else
00601 tmp.addMatrix( *(values[count]),arg.getTime( i ) );
00602 }
00603
00604 return tmp;
00605 }
00606
00607
00608 MatrixVariablesGrid MatrixVariablesGrid::getCoarsenedGrid( const Grid& arg
00609 ) const
00610 {
00611 MatrixVariablesGrid tmp;
00612
00613
00614 if ( this->isEmpty( ) == BT_TRUE )
00615 return tmp;
00616
00617
00618 if ( Grid::operator==( arg ) == BT_TRUE )
00619 return *this;
00620
00621 if ( Grid::operator>=( arg ) == BT_FALSE )
00622 return tmp;
00623
00624 for( uint i=0; i<arg.getNumPoints( ); ++i )
00625 {
00626 int idx = findLastTime( arg.getTime( i ) );
00627
00628 if ( idx >= 0 )
00629 tmp.addMatrix( *(values[idx]),arg.getTime( i ) );
00630 else
00631 {
00632 tmp.init( );
00633 return tmp;
00634 }
00635 }
00636
00637 return tmp;
00638 }
00639
00640
00641
00642 MatrixVariablesGrid& MatrixVariablesGrid::shiftTimes( double timeShift
00643 )
00644 {
00645 Grid::shiftTimes( timeShift );
00646 return *this;
00647 }
00648
00649
00650 MatrixVariablesGrid& MatrixVariablesGrid::shiftBackwards( DMatrix lastValue )
00651 {
00652 if ( getNumPoints() < 2 ){
00653 if( lastValue.isEmpty() == BT_FALSE )
00654 *(values[getNumIntervals()]) = lastValue;
00655 return *this;
00656 }
00657
00658 for( uint i=1; i<getNumPoints( ); ++i )
00659 *(values[i-1]) = *(values[i]);
00660
00661 if( lastValue.isEmpty() == BT_FALSE )
00662 *(values[getNumIntervals()]) = lastValue;
00663
00664 return *this;
00665 }
00666
00667
00668
00669 DVector MatrixVariablesGrid::linearInterpolation( double time ) const
00670 {
00671 uint idx1 = getFloorIndex( time );
00672 uint idx2 = getCeilIndex ( time );
00673
00674 ASSERT( values != 0 );
00675 ASSERT( idx1 < getNumPoints( ) );
00676 ASSERT( idx2 < getNumPoints( ) );
00677
00678 DVector tmp1( values[idx1]->getCol( 0 ) );
00679 DVector tmp2( values[idx2]->getCol( 0 ) );
00680
00681 double t1 = getTime( idx1 );
00682 double t2 = getTime( idx2 );
00683
00684 if( fabs( t2 - t1 ) < SQRT_EPS ) return tmp1;
00685
00686 tmp1 *= (t2 - time);
00687 tmp2 *= (time - t1);
00688
00689 DVector tmp = tmp1 + tmp2;
00690 tmp /= (t2 - t1);
00691
00692 return tmp;
00693 }
00694
00695 returnValue MatrixVariablesGrid::print( std::ostream& stream,
00696 const char* const name,
00697 const char* const startString,
00698 const char* const endString,
00699 uint width,
00700 uint precision,
00701 const char* const colSeparator,
00702 const char* const rowSeparator
00703 ) const
00704 {
00705 if (name != NULL && strlen(name) > 0)
00706 stream << name << " = ";
00707 if (startString != NULL && strlen(startString) > 0)
00708 stream << startString;
00709
00710 if ( precision > 0 )
00711 stream << setw( width ) << setprecision( precision ) << scientific;
00712 else
00713 stream << setw( width );
00714
00715 for (unsigned k = 0; k < getNumPoints(); ++k)
00716 {
00717 if ( precision > 0 )
00718 stream << getTime( k );
00719 else
00720 stream << (int)getTime( k );
00721
00722 if (colSeparator != NULL && strlen(colSeparator) > 0)
00723 stream << colSeparator;
00724
00725 values[k]->print(stream, "", "", "", width, precision, colSeparator, colSeparator);
00726
00727 if (k < (getNumPoints() - 1) && rowSeparator != NULL && strlen(rowSeparator) > 0)
00728 stream << rowSeparator;
00729 }
00730 if (endString != NULL && strlen(endString) > 0)
00731 stream << endString;
00732
00733 return SUCCESSFUL_RETURN;
00734 }
00735
00736 returnValue MatrixVariablesGrid::print( const char* const filename,
00737 const char* const name,
00738 const char* const startString,
00739 const char* const endString,
00740 uint width,
00741 uint precision,
00742 const char* const colSeparator,
00743 const char* const rowSeparator
00744 ) const
00745 {
00746 ofstream stream( filename );
00747 returnValue status;
00748
00749 if (stream.is_open() == true)
00750 status = print(stream, name, startString, endString, width, precision,
00751 colSeparator, rowSeparator);
00752 else
00753 return ACADOERROR( RET_FILE_CAN_NOT_BE_OPENED );
00754
00755 stream.close();
00756
00757 return status;
00758 }
00759
00760 returnValue MatrixVariablesGrid::print( const char* const filename,
00761 const char* const name,
00762 PrintScheme printScheme
00763 ) const
00764 {
00765 ofstream stream(filename);
00766 returnValue status;
00767
00768 if (stream.is_open())
00769 status = print(stream, name, printScheme);
00770 else
00771 return ACADOERROR( RET_FILE_CAN_NOT_BE_OPENED );
00772
00773 stream.close();
00774
00775 return status;
00776 }
00777
00778 returnValue MatrixVariablesGrid::print( std::ostream& stream,
00779 const char* const name,
00780 PrintScheme printScheme
00781 ) const
00782 {
00783
00784
00785 switch (printScheme) {
00786 case PS_MATLAB_BINARY:
00787
00788 ACADOFATAL( RET_NOT_IMPLEMENTED_YET );
00789
00790 break;
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800 default:
00801 char* startString = 0;
00802 char* endString = 0;
00803 uint width = 0;
00804 uint precision = 0;
00805 char* colSeparator = 0;
00806 char* rowSeparator = 0;
00807
00808 returnValue ret = getGlobalStringDefinitions(printScheme, &startString,
00809 &endString, width, precision, &colSeparator, &rowSeparator);
00810
00811 returnValue status;
00812 if (status == SUCCESSFUL_RETURN)
00813 status = print(stream, name, startString, endString, width, precision,
00814 colSeparator, rowSeparator);
00815
00816 if (startString != 0)
00817 delete[] startString;
00818 if (endString != 0)
00819 delete[] endString;
00820 if (colSeparator != 0)
00821 delete[] colSeparator;
00822 if (rowSeparator != 0)
00823 delete[] rowSeparator;
00824
00825 return status;
00826 }
00827
00828 return SUCCESSFUL_RETURN;
00829 }
00830
00831 returnValue MatrixVariablesGrid::read( std::istream& stream )
00832 {
00833 vector< vector< double > > data;
00834 stream >> data;
00835
00836 if (data.size() == 0)
00837 return SUCCESSFUL_RETURN;
00838
00839
00840 unsigned nc = data[ 0 ].size();
00841 unsigned nr = data.size();
00842 for (unsigned row = 0; row < nr; ++row)
00843 if (data[ row ].size() != nc)
00844 return ACADOERROR( RET_INVALID_ARGUMENTS );
00845
00846
00847 init(nc - 1, 1, nr, getType());
00848
00849 for (unsigned row = 0; row < nr; ++row)
00850 setTime( data[ row ][ 0 ] );
00851
00852 for (unsigned row = 0; row < nr; ++row)
00853 for (unsigned col = 0; col < nc - 1; ++col)
00854 operator()(row, col, 0) = data[ row ][col + 1];
00855
00856 return SUCCESSFUL_RETURN;
00857 }
00858
00859 returnValue MatrixVariablesGrid::read( const char* const filename )
00860 {
00861 ifstream stream( filename );
00862 returnValue status;
00863
00864 if (stream.is_open())
00865 status = read( stream );
00866 else
00867 return ACADOERROR( RET_FILE_CAN_NOT_BE_OPENED );
00868
00869 stream.close();
00870
00871 return status;
00872 }
00873
00874 std::ostream& operator<<(std::ostream& stream, const MatrixVariablesGrid& arg)
00875 {
00876 if (arg.print( stream ) != SUCCESSFUL_RETURN)
00877 ACADOERRORTEXT(RET_INVALID_ARGUMENTS, "Cannot write to output stream.");
00878
00879 return stream;
00880 }
00881
00882 std::istream& operator>>(std::istream& stream, MatrixVariablesGrid& arg)
00883 {
00884 if (arg.read( stream ) != SUCCESSFUL_RETURN)
00885 ACADOERRORTEXT(RET_INVALID_ARGUMENTS, "Cannot read from input stream.");
00886
00887 return stream;
00888 }
00889
00890
00891
00892
00893
00894 returnValue MatrixVariablesGrid::clearValues( )
00895 {
00896 if ( values != 0 )
00897 {
00898 for( uint i=0; i<nPoints; ++i )
00899 {
00900 if ( values[i] != 0 )
00901 delete values[i];
00902 }
00903
00904 free( values );
00905 values = 0;
00906 }
00907
00908 return SUCCESSFUL_RETURN;
00909 }
00910
00911
00912 returnValue MatrixVariablesGrid::initMatrixVariables( uint _nRows,
00913 uint _nCols,
00914 VariableType _type,
00915 const char** const _names,
00916 const char** const _units,
00917 const DVector* const _scaling,
00918 const DVector* const _lb,
00919 const DVector* const _ub,
00920 const BooleanType* const _autoInit
00921 )
00922 {
00923 DVector currentScaling,currentLb,currentUb;
00924
00925 for( uint i=0; i<nPoints; ++i )
00926 {
00927 if ( _scaling != 0 )
00928 currentScaling = _scaling[i];
00929 else
00930 currentScaling.init( );
00931
00932 if ( _lb != 0 )
00933 currentLb = _lb[i];
00934 else
00935 currentLb.init( );
00936
00937 if ( _ub != 0 )
00938 currentUb = _ub[i];
00939 else
00940 currentUb.init( );
00941
00942 values[i] = new MatrixVariable( _nRows,_nCols,_type,_names,_units,currentScaling,currentLb,currentUb );
00943 }
00944
00945 return SUCCESSFUL_RETURN;
00946 }
00947
00948
00949 returnValue MatrixVariablesGrid::addMatrix( const MatrixVariable& newMatrix,
00950 double newTime
00951 )
00952 {
00953 if ( ( isInfty( newTime ) == BT_TRUE ) && ( getNumPoints( ) > 0 ) )
00954 newTime = getLastTime( ) + 1.0;
00955
00956 if ( Grid::addTime( newTime ) != SUCCESSFUL_RETURN )
00957 return RET_INVALID_ARGUMENTS;
00958
00959 values = (MatrixVariable**) realloc( values,nPoints*sizeof(MatrixVariable*) );
00960 values[nPoints-1] = new MatrixVariable( newMatrix );
00961
00962 return SUCCESSFUL_RETURN;
00963 }
00964
00965 returnValue MatrixVariablesGrid::sprint( std::ostream& stream
00966 )
00967 {
00968 uint run1, run2, run3;
00969
00970 unsigned tmpSize = getNumPoints() * (getNumRows() + 1);
00971 double *tmp = new double[tmpSize];
00972
00973 if( times == 0 ) return ACADOERROR(RET_MEMBER_NOT_INITIALISED);
00974
00975 for( run1 = 0; run1 < getNumPoints(); run1++ ){
00976 tmp[run1*(getNumValues()+1)] = getTime(run1);
00977
00978 for( run2 = 0; run2 < getNumRows(); run2++ ){
00979 for( run3 = 0; run3 < getNumCols(); run3++ ){
00980 tmp[run1*(getNumValues()+1)+1+run2*getNumCols() + run3] = operator()( run1,run2,run3 );
00981 }
00982 }
00983 }
00984
00985 unsigned nRows = getNumPoints();
00986 unsigned nCols = getNumValues() + 1;
00987 for (run1 = 0; run1 < nRows; run1++) {
00988 for (run2 = 0; run2 < nCols; run2++) {
00989 if (tmp[nCols * run1 + run2] <= ACADO_NAN - 1.0)
00990 stream << scientific << tmp[nCols * run1 + run2] << TEXT_SEPARATOR;
00991 else
00992 stream << NOT_A_NUMBER << TEXT_SEPARATOR;
00993 }
00994 stream << LINE_SEPARATOR;
00995 }
00996 stream << LINE_SEPARATOR;
00997
00998 delete[] tmp;
00999
01000 return SUCCESSFUL_RETURN;
01001 }
01002
01003 #ifdef WIN32
01004 #pragma warning( disable : 4390 )
01005 #endif
01006
01007
01008
01009
01010
01011
01012 double& MatrixVariablesGrid::operator()( uint pointIdx, uint rowIdx, uint colIdx )
01013 {
01014 ASSERT( values != 0 );
01015 ASSERT( pointIdx < getNumPoints( ) );
01016
01017 return values[pointIdx]->operator()( rowIdx,colIdx );
01018 }
01019
01020
01021 double MatrixVariablesGrid::operator()( uint pointIdx, uint rowIdx, uint colIdx ) const
01022 {
01023 ASSERT( values != 0 );
01024 ASSERT( pointIdx < getNumPoints( ) );
01025
01026 return values[pointIdx]->operator()( rowIdx,colIdx );
01027 }
01028
01029
01030
01031 MatrixVariablesGrid MatrixVariablesGrid::operator()( const uint rowIdx
01032 ) const
01033 {
01034 ASSERT( values != 0 );
01035 if ( rowIdx >= getNumRows( ) )
01036 {
01037 ACADOERROR( RET_INVALID_ARGUMENTS );
01038 return MatrixVariablesGrid();
01039 }
01040
01041 Grid tmpGrid;
01042 getGrid( tmpGrid );
01043
01044 MatrixVariablesGrid rowGrid( 1,1,tmpGrid,getType( ) );
01045
01046 for( uint run1 = 0; run1 < getNumPoints(); run1++ )
01047 rowGrid( run1,0,0 ) = values[run1]->operator()( rowIdx,0 );
01048
01049 return rowGrid;
01050 }
01051
01052
01053 MatrixVariablesGrid MatrixVariablesGrid::operator[]( const uint pointIdx
01054 ) const
01055 {
01056 ASSERT( values != 0 );
01057 if ( pointIdx >= getNumPoints( ) )
01058 {
01059 ACADOERROR( RET_INVALID_ARGUMENTS );
01060 return MatrixVariablesGrid();
01061 }
01062
01063 MatrixVariablesGrid pointGrid;
01064 pointGrid.addMatrix( *(values[pointIdx]),getTime( pointIdx ) );
01065
01066 return pointGrid;
01067 }
01068
01069
01070
01071 MatrixVariablesGrid MatrixVariablesGrid::operator+( const MatrixVariablesGrid& arg
01072 ) const
01073 {
01074 ASSERT( getNumPoints( ) == arg.getNumPoints( ) );
01075
01076 MatrixVariablesGrid tmp( *this );
01077
01078 for( uint i=0; i<getNumPoints( ); ++i )
01079 *(tmp.values[i]) += *(arg.values[i]);
01080
01081 return tmp;
01082 }
01083
01084
01085
01086
01087
01088 MatrixVariablesGrid& MatrixVariablesGrid::operator+=( const MatrixVariablesGrid& arg
01089 )
01090 {
01091 ASSERT( getNumPoints( ) == arg.getNumPoints( ) );
01092
01093 for( uint i=0; i<getNumPoints( ); ++i )
01094 *(values[i]) += *(arg.values[i]);
01095
01096 return *this;
01097 }
01098
01099
01100
01101 MatrixVariablesGrid MatrixVariablesGrid::operator-( const MatrixVariablesGrid& arg
01102 ) const
01103 {
01104 ASSERT( getNumPoints( ) == arg.getNumPoints( ) );
01105
01106 MatrixVariablesGrid tmp( *this );
01107
01108 for( uint i=0; i<getNumPoints( ); ++i )
01109 *(tmp.values[i]) -= *(arg.values[i]);
01110
01111 return tmp;
01112 }
01113
01114
01115 MatrixVariablesGrid& MatrixVariablesGrid::operator-=( const MatrixVariablesGrid& arg
01116 )
01117 {
01118 ASSERT( getNumPoints( ) == arg.getNumPoints( ) );
01119
01120 for( uint i=0; i<getNumPoints( ); ++i )
01121 *(values[i]) -= *(arg.values[i]);
01122
01123 return *this;
01124 }
01125
01126
01127
01128 uint MatrixVariablesGrid::getDim( ) const
01129 {
01130 uint totalDim = 0;
01131
01132 for( uint i=0; i<getNumPoints( ); ++i )
01133 totalDim += values[i]->getDim( );
01134
01135 return totalDim;
01136 }
01137
01138
01139
01140 uint MatrixVariablesGrid::getNumRows( ) const
01141 {
01142 if ( values == 0 )
01143 return 0;
01144
01145 return getNumRows( 0 );
01146 }
01147
01148
01149 uint MatrixVariablesGrid::getNumCols( ) const
01150 {
01151 if ( values == 0 )
01152 return 0;
01153
01154 return getNumCols( 0 );
01155 }
01156
01157
01158 uint MatrixVariablesGrid::getNumValues( ) const
01159 {
01160 if ( values == 0 )
01161 return 0;
01162
01163 return getNumValues( 0 );
01164 }
01165
01166
01167 uint MatrixVariablesGrid::getNumRows( uint pointIdx
01168 ) const
01169 {
01170 if( values == 0 )
01171 return 0;
01172
01173 ASSERT( pointIdx < getNumPoints( ) );
01174
01175 return values[pointIdx]->getNumRows( );
01176 }
01177
01178
01179 uint MatrixVariablesGrid::getNumCols( uint pointIdx
01180 ) const
01181 {
01182 if( values == 0 )
01183 return 0;
01184
01185 ASSERT( pointIdx < getNumPoints( ) );
01186
01187 return values[pointIdx]->getNumCols( );
01188 }
01189
01190
01191 uint MatrixVariablesGrid::getNumValues( uint pointIdx
01192 ) const
01193 {
01194 if( values == 0 )
01195 return 0;
01196
01197 ASSERT( pointIdx < getNumPoints( ) );
01198
01199 return values[pointIdx]->getDim( );
01200 }
01201
01202
01203
01204 VariableType MatrixVariablesGrid::getType( ) const
01205 {
01206 if ( getNumPoints() == 0 )
01207 return VT_UNKNOWN;
01208
01209 return getType( 0 );
01210 }
01211
01212
01213 returnValue MatrixVariablesGrid::setType( VariableType _type
01214 )
01215 {
01216 for( uint i=0; i<getNumPoints( ); ++i )
01217 setType( i,_type );
01218
01219 return SUCCESSFUL_RETURN;
01220 }
01221
01222
01223 VariableType MatrixVariablesGrid::getType( uint pointIdx
01224 ) const
01225 {
01226 if ( pointIdx >= getNumPoints( ) )
01227 return VT_UNKNOWN;
01228
01229 return values[pointIdx]->getType( );
01230 }
01231
01232
01233 returnValue MatrixVariablesGrid::setType( uint pointIdx,
01234 VariableType _type
01235 )
01236 {
01237 if ( pointIdx >= getNumPoints( ) )
01238 return ACADOERROR( RET_INDEX_OUT_OF_BOUNDS );
01239
01240 return values[pointIdx]->setType( _type );
01241 }
01242
01243
01244
01245 returnValue MatrixVariablesGrid::getName( uint pointIdx,
01246 uint idx,
01247 char* const _name
01248 ) const
01249 {
01250 if( pointIdx >= getNumPoints( ) )
01251 return ACADOERROR( RET_INDEX_OUT_OF_BOUNDS );
01252
01253 return values[pointIdx]->getName( idx,_name );
01254 }
01255
01256
01257 returnValue MatrixVariablesGrid::setName( uint pointIdx,
01258 uint idx,
01259 const char* const _name
01260 )
01261 {
01262 if( pointIdx >= getNumPoints( ) )
01263 return ACADOERROR( RET_INDEX_OUT_OF_BOUNDS );
01264
01265 return values[pointIdx]->setName( idx,_name );
01266 }
01267
01268
01269
01270 returnValue MatrixVariablesGrid::getUnit( uint pointIdx,
01271 uint idx,
01272 char* const _unit
01273 ) const
01274 {
01275 if( pointIdx >= getNumPoints( ) )
01276 return ACADOERROR( RET_INDEX_OUT_OF_BOUNDS );
01277
01278 return values[pointIdx]->getUnit( idx,_unit );
01279 }
01280
01281
01282 returnValue MatrixVariablesGrid::setUnit( uint pointIdx,
01283 uint idx,
01284 const char* const _unit
01285 )
01286 {
01287 if( pointIdx >= getNumPoints( ) )
01288 return ACADOERROR( RET_INDEX_OUT_OF_BOUNDS );
01289
01290 return values[pointIdx]->setUnit( idx,_unit );
01291 }
01292
01293
01294
01295 DVector MatrixVariablesGrid::getScaling( uint pointIdx
01296 ) const
01297 {
01298 if( pointIdx >= getNumPoints( ) )
01299 return emptyVector;
01300
01301 return values[pointIdx]->getScaling( );
01302 }
01303
01304
01305 returnValue MatrixVariablesGrid::setScaling( uint pointIdx,
01306 const DVector& _scaling
01307 )
01308 {
01309 if ( pointIdx >= getNumPoints( ) )
01310 return ACADOERROR(RET_INDEX_OUT_OF_BOUNDS);
01311
01312 return values[pointIdx]->setScaling( _scaling );
01313 }
01314
01315
01316 double MatrixVariablesGrid::getScaling( uint pointIdx,
01317 uint valueIdx
01318 ) const
01319 {
01320 if( pointIdx >= getNumPoints( ) )
01321 return -1.0;
01322
01323 return values[pointIdx]->getScaling( valueIdx );
01324 }
01325
01326
01327 returnValue MatrixVariablesGrid::setScaling( uint pointIdx,
01328 uint valueIdx,
01329 double _scaling
01330 )
01331 {
01332 if( pointIdx >= getNumPoints( ) )
01333 return ACADOERROR( RET_INDEX_OUT_OF_BOUNDS );
01334
01335 if( valueIdx >= values[pointIdx]->getDim( ) )
01336 return ACADOERROR( RET_INDEX_OUT_OF_BOUNDS );
01337
01338 values[pointIdx]->setScaling( valueIdx,_scaling );
01339 return SUCCESSFUL_RETURN;
01340 }
01341
01342
01343
01344 DVector MatrixVariablesGrid::getLowerBounds( uint pointIdx
01345 ) const
01346 {
01347 if( pointIdx >= getNumPoints( ) )
01348 return emptyVector;
01349
01350 return values[pointIdx]->getLowerBounds( );
01351 }
01352
01353
01354 returnValue MatrixVariablesGrid::setLowerBounds( uint pointIdx,
01355 const DVector& _lb
01356 )
01357 {
01358 if( pointIdx >= nPoints )
01359 return ACADOERROR(RET_INDEX_OUT_OF_BOUNDS);
01360
01361 return values[pointIdx]->setLowerBounds( _lb );
01362 }
01363
01364
01365 double MatrixVariablesGrid::getLowerBound( uint pointIdx,
01366 uint valueIdx
01367 ) const
01368 {
01369 if( pointIdx >= getNumPoints( ) )
01370 return -INFTY;
01371
01372 return values[pointIdx]->getLowerBound( valueIdx );
01373 }
01374
01375
01376 returnValue MatrixVariablesGrid::setLowerBound( uint pointIdx,
01377 uint valueIdx,
01378 double _lb
01379 )
01380 {
01381 if( pointIdx >= getNumPoints( ) )
01382 return ACADOERROR( RET_INDEX_OUT_OF_BOUNDS );
01383
01384 if( valueIdx >= values[pointIdx]->getDim( ) )
01385 return ACADOERROR( RET_INDEX_OUT_OF_BOUNDS );
01386
01387 values[pointIdx]->setLowerBound( valueIdx,_lb );
01388 return SUCCESSFUL_RETURN;
01389 }
01390
01391
01392
01393 DVector MatrixVariablesGrid::getUpperBounds( uint pointIdx
01394 ) const
01395 {
01396 if( pointIdx >= getNumPoints( ) )
01397 return emptyVector;
01398
01399 return values[pointIdx]->getUpperBounds( );
01400 }
01401
01402
01403 returnValue MatrixVariablesGrid::setUpperBounds( uint pointIdx,
01404 const DVector& _ub
01405 )
01406 {
01407 if( pointIdx >= getNumPoints( ) )
01408 return ACADOERROR(RET_INDEX_OUT_OF_BOUNDS);
01409
01410 return values[pointIdx]->setUpperBounds( _ub );
01411 }
01412
01413
01414 double MatrixVariablesGrid::getUpperBound( uint pointIdx,
01415 uint valueIdx
01416 ) const
01417 {
01418 if( pointIdx >= getNumPoints( ) )
01419 return INFTY;
01420
01421 return values[pointIdx]->getUpperBound( valueIdx );
01422 }
01423
01424
01425 returnValue MatrixVariablesGrid::setUpperBound( uint pointIdx,
01426 uint valueIdx,
01427 double _ub
01428 )
01429 {
01430 if( pointIdx >= getNumPoints( ) )
01431 return ACADOERROR( RET_INDEX_OUT_OF_BOUNDS );
01432
01433 if( valueIdx >= values[pointIdx]->getDim( ) )
01434 return ACADOERROR( RET_INDEX_OUT_OF_BOUNDS );
01435
01436 values[pointIdx]->setUpperBound( valueIdx,_ub );
01437 return SUCCESSFUL_RETURN;
01438 }
01439
01440
01441
01442 BooleanType MatrixVariablesGrid::getAutoInit( uint pointIdx
01443 ) const
01444 {
01445 if ( pointIdx >= getNumPoints( ) )
01446 {
01447 ACADOERROR( RET_INDEX_OUT_OF_BOUNDS );
01448 return defaultAutoInit;
01449 }
01450
01451 return values[pointIdx]->getAutoInit( );
01452 }
01453
01454
01455 returnValue MatrixVariablesGrid::setAutoInit( uint pointIdx,
01456 BooleanType _autoInit
01457 )
01458 {
01459 if ( pointIdx >= getNumPoints( ) )
01460 return ACADOERROR( RET_INDEX_OUT_OF_BOUNDS );
01461
01462 return values[pointIdx]->setAutoInit( _autoInit );
01463 }
01464
01465
01466 returnValue MatrixVariablesGrid::disableAutoInit( )
01467 {
01468 for( uint i=0; i<getNumPoints( ); ++i )
01469 values[i]->setAutoInit( BT_FALSE );
01470
01471 return SUCCESSFUL_RETURN;
01472 }
01473
01474
01475 returnValue MatrixVariablesGrid::enableAutoInit( )
01476 {
01477 for( uint i=0; i<getNumPoints( ); ++i )
01478 values[i]->setAutoInit( BT_TRUE );
01479
01480 return SUCCESSFUL_RETURN;
01481 }
01482
01483
01484
01485 BooleanType MatrixVariablesGrid::hasNames( ) const
01486 {
01487 for( uint i=0; i<getNumPoints( ); ++i )
01488 {
01489 if ( values[i]->hasNames( ) == BT_TRUE )
01490 return BT_TRUE;
01491 }
01492
01493 return BT_FALSE;
01494 }
01495
01496
01497 BooleanType MatrixVariablesGrid::hasUnits( ) const
01498 {
01499 for( uint i=0; i<getNumPoints( ); ++i )
01500 {
01501 if ( values[i]->hasUnits( ) == BT_TRUE )
01502 return BT_TRUE;
01503 }
01504
01505 return BT_FALSE;
01506 }
01507
01508
01509 BooleanType MatrixVariablesGrid::hasScaling( ) const
01510 {
01511 for( uint i=0; i<getNumPoints( ); ++i )
01512 {
01513 if ( values[i]->hasScaling( ) == BT_TRUE )
01514 return BT_TRUE;
01515 }
01516
01517 return BT_FALSE;
01518 }
01519
01520
01521 BooleanType MatrixVariablesGrid::hasLowerBounds( ) const
01522 {
01523 for( uint i=0; i<getNumPoints( ); ++i )
01524 {
01525 if ( values[i]->hasLowerBounds( ) == BT_TRUE )
01526 return BT_TRUE;
01527 }
01528
01529 return BT_FALSE;
01530 }
01531
01532
01533 BooleanType MatrixVariablesGrid::hasUpperBounds( ) const
01534 {
01535 for( uint i=0; i<getNumPoints( ); ++i )
01536 {
01537 if ( values[i]->hasUpperBounds( ) == BT_TRUE )
01538 return BT_TRUE;
01539 }
01540
01541 return BT_FALSE;
01542 }
01543
01544
01545
01546 double MatrixVariablesGrid::getMax( ) const
01547 {
01548 double maxValue = -INFTY;
01549
01550 for( uint i=0; i<getNumPoints( ); ++i )
01551 {
01552 if ( values[i]->getMax( ) > maxValue )
01553 maxValue = values[i]->getMax( );
01554 }
01555
01556 return maxValue;
01557 }
01558
01559
01560 double MatrixVariablesGrid::getMin( ) const
01561 {
01562 double minValue = INFTY;
01563
01564 for( uint i=0; i<getNumPoints( ); ++i )
01565 {
01566 if ( values[i]->getMin( ) < minValue )
01567 minValue = values[i]->getMin( );
01568 }
01569
01570 return minValue;
01571 }
01572
01573
01574 double MatrixVariablesGrid::getMean( ) const
01575 {
01576 double meanValue = 0.0;
01577
01578 if ( getNumPoints( ) == 0 )
01579 return meanValue;
01580
01581 for( uint i=0; i<getNumPoints( ); ++i )
01582 meanValue += values[i]->getMean( );
01583
01584 return ( meanValue / (double)getNumPoints( ) );
01585 }
01586
01587
01588
01589 returnValue MatrixVariablesGrid::setZero( )
01590 {
01591 for( uint i=0; i<getNumPoints( ); ++i )
01592 values[i]->setZero( );
01593
01594 return SUCCESSFUL_RETURN;
01595 }
01596
01597
01598 returnValue MatrixVariablesGrid::setAll( double _value
01599 )
01600 {
01601 for( uint i = 0; i<getNumPoints( ); ++i )
01602 values[i]->setAll( _value );
01603
01604 return SUCCESSFUL_RETURN;
01605 }
01606
01607
01608
01609 returnValue MatrixVariablesGrid::getGrid( Grid& _grid
01610 ) const
01611 {
01612 return _grid.init( getNumPoints(),times );
01613 }
01614
01615
01616 Grid MatrixVariablesGrid::getTimePoints( ) const
01617 {
01618 Grid tmp;
01619 getGrid( tmp );
01620 return tmp;
01621 }
01622
01623
01624 CLOSE_NAMESPACE_ACADO
01625
01626
01627
01628
01629