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/utils/acado_utils.hpp>
00036 #include <acado/function/c_function.hpp>
00037 #include <acado/function/c_operator.hpp>
00038
00039
00040
00041 BEGIN_NAMESPACE_ACADO
00042
00043
00044 int COperator::counter = 0;
00045
00046 COperator::COperator( ) :SmoothOperator( )
00047 {
00048 result = 0;
00049 d_result = 0;
00050 cresult = 0;
00051 d_cresult = 0;
00052 component = -1;
00053 bufferSize = 0;
00054 idx = 0;
00055
00056 first = BT_FALSE;
00057 globalTypeID = counter ;
00058
00059 nCount = 0;
00060 }
00061
00062
00063 COperator::COperator( const CFunction &fcn, const Expression &arg, int component_ ) :SmoothOperator( )
00064 {
00065
00066 uint run1;
00067
00068 cFunction = fcn;
00069 argument = arg;
00070
00071 component = component_;
00072
00073 first = BT_FALSE;
00074 globalTypeID = counter;
00075
00076 idx = new int[cFunction.getDim()];
00077
00078 bufferSize = 1;
00079
00080 result = (double**)calloc(bufferSize,sizeof(double*));
00081 d_result = (double**)calloc(bufferSize,sizeof(double*));
00082
00083 for( run1 = 0; run1 < bufferSize; run1++ ){
00084 result [run1] = new double[argument.getDim()];
00085 d_result[run1] = new double[argument.getDim()];
00086 }
00087
00088 cresult = (double**)calloc(bufferSize,sizeof(double*));
00089 d_cresult = (double**)calloc(bufferSize,sizeof(double*));
00090
00091 for( run1 = 0; run1 < bufferSize; run1++ ){
00092 cresult [run1] = new double[cFunction.getDim()];
00093 d_cresult[run1] = new double[cFunction.getDim()];
00094 }
00095
00096 nCount = 0;
00097 }
00098
00099
00100 COperator::COperator( const COperator &arg ){ copy(arg); }
00101
00102 COperator::~COperator(){ deleteAll(); }
00103
00104
00105 COperator& COperator::operator=( const COperator &arg ){
00106
00107 if( this != &arg ){
00108
00109 deleteAll( );
00110 copy (arg);
00111 }
00112 return *this;
00113 }
00114
00115
00116 int COperator::increaseID(){ return counter++; }
00117
00118
00119 void COperator::copy( const COperator &arg ){
00120
00121 uint run1, run2;
00122
00123 bufferSize = arg.bufferSize ;
00124 cFunction = arg.cFunction ;
00125 argument = arg.argument ;
00126 component = arg.component ;
00127
00128 first = arg.first ;
00129 globalTypeID = arg.globalTypeID ;
00130
00131 idx = new int[cFunction.getDim()];
00132 for( run1 = 0; run1 < cFunction.getDim(); run1++ )
00133 idx[run1] = arg.idx[run1];
00134
00135 result = (double**)calloc(bufferSize,sizeof(double*));
00136 d_result = (double**)calloc(bufferSize,sizeof(double*));
00137
00138 for( run1 = 0; run1 < bufferSize; run1++ ){
00139
00140 result [run1] = new double[argument.getDim()];
00141 d_result[run1] = new double[argument.getDim()];
00142
00143 for( run2 = 0; run2 < argument.getDim(); run2++ ){
00144 result[run1][run2] = arg.result [run1][run2];
00145 d_result[run1][run2] = arg.d_result[run1][run2];
00146 }
00147 }
00148
00149 cresult = (double**)calloc(bufferSize,sizeof(double*));
00150 d_cresult = (double**)calloc(bufferSize,sizeof(double*));
00151
00152 for( run1 = 0; run1 < bufferSize; run1++ ){
00153
00154 cresult [run1] = new double[cFunction.getDim()];
00155 d_cresult[run1] = new double[cFunction.getDim()];
00156
00157 for( run2 = 0; run2 < cFunction.getDim(); run2++ ){
00158 cresult[run1][run2] = arg.cresult [run1][run2];
00159 d_cresult[run1][run2] = arg.d_cresult[run1][run2];
00160 }
00161 }
00162
00163 nCount = 0;
00164 }
00165
00166
00167 void COperator::deleteAll(){
00168
00169 uint run1;
00170
00171 for( run1 = 0; run1 < bufferSize; run1++ ){
00172 delete[] result [run1];
00173 delete[] d_result[run1];
00174 }
00175
00176 free( result );
00177 free( d_result );
00178
00179 for( run1 = 0; run1 < bufferSize; run1++ ){
00180 delete[] cresult [run1];
00181 delete[] d_cresult[run1];
00182 }
00183
00184 free( cresult );
00185 free( d_cresult );
00186
00187 delete[] idx;
00188 }
00189
00190
00191 returnValue COperator::evaluate( int number, double *x, double *result_ ){
00192
00193 uint run1;
00194
00195 ASSERT( component >= 0 );
00196
00197 if( first == BT_FALSE ){
00198 result_[0] = x[idx[component]];
00199 }
00200 else{
00201
00202 if( number >= (int) bufferSize ){
00203
00204 int oldSize = bufferSize;
00205 bufferSize += number;
00206 result = (double**)realloc(result ,bufferSize*sizeof(double*));
00207 d_result = (double**)realloc(d_result ,bufferSize*sizeof(double*));
00208 cresult = (double**)realloc(cresult ,bufferSize*sizeof(double*));
00209 d_cresult = (double**)realloc(d_cresult,bufferSize*sizeof(double*));
00210
00211 for( run1 = oldSize; run1 < bufferSize; run1++ ){
00212 result [run1] = new double[argument.getDim() ];
00213 d_result [run1] = new double[argument.getDim() ];
00214 cresult [run1] = new double[cFunction.getDim()];
00215 d_cresult[run1] = new double[cFunction.getDim()];
00216 }
00217 }
00218
00219 for( run1 = 0; run1 < argument.getDim(); run1++ )
00220 argument.element[run1]->evaluate( number, x , &result[number][run1] );
00221 cFunction.evaluate( number, result[number], cresult[number] );
00222 result_[0] = cresult[number][component];
00223 for( run1 = 0; run1 < cFunction.getDim(); run1++ )
00224 x[idx[run1]] = cresult[number][run1];
00225 }
00226 return SUCCESSFUL_RETURN;
00227 }
00228
00229
00230 returnValue COperator::evaluate( EvaluationBase *x ){
00231
00232 ASSERT( 1 == 0 );
00233 return ACADOERROR(RET_ASSERTION);
00234 }
00235
00236
00237
00238 Operator* COperator::differentiate( int index ){
00239
00240 ASSERT( 1 == 0 );
00241 ACADOERROR(RET_ASSERTION);
00242 return 0;
00243 }
00244
00245
00246
00247 Operator* COperator::AD_forward( int dim,
00248 VariableType *varType,
00249 int *component_,
00250 Operator **seed,
00251 int &nNewIS,
00252 TreeProjection ***newIS ){
00253
00254 ASSERT( 1 == 0 );
00255 ACADOERROR(RET_ASSERTION);
00256 return 0;
00257 }
00258
00259
00260 returnValue COperator::AD_backward( int dim ,
00261 VariableType *varType ,
00262 int *component_,
00263 Operator *seed ,
00264 Operator **df ,
00265 int &nNewIS ,
00266 TreeProjection ***newIS_ ){
00267
00268 ASSERT( 1 == 0 );
00269 return ACADOERROR(RET_ASSERTION);
00270 }
00271
00272
00273 returnValue COperator::AD_symmetric( int dim ,
00274 VariableType *varType ,
00275 int *component_,
00276 Operator *l ,
00277 Operator **S ,
00278 int dimS ,
00279 Operator **dfS ,
00280 Operator **ldf ,
00281 Operator **H ,
00282 int &nNewLIS ,
00283 TreeProjection ***newLIS ,
00284 int &nNewSIS ,
00285 TreeProjection ***newSIS ,
00286 int &nNewHIS ,
00287 TreeProjection ***newHIS ){
00288
00289 ASSERT( 1 == 0 );
00290 return ACADOERROR(RET_ASSERTION);
00291 }
00292
00293
00294 Operator* COperator::substitute( int index, const Operator *sub ){
00295
00296 ACADOERROR( RET_NOT_IMPLEMENTED_YET );
00297 return 0;
00298 }
00299
00300
00301 NeutralElement COperator::isOneOrZero() const{
00302
00303 return NE_NEITHER_ONE_NOR_ZERO;
00304 }
00305
00306
00307
00308 BooleanType COperator::isDependingOn( VariableType var ) const{
00309
00310 uint run1;
00311
00312 for( run1 = 0; run1 < argument.getDim(); run1++ )
00313 if( argument.element[run1]->isDependingOn(var) == BT_TRUE )
00314 return BT_TRUE;
00315 return BT_FALSE;
00316 }
00317
00318
00319 BooleanType COperator::isDependingOn( int dim,
00320 VariableType *varType,
00321 int *component_,
00322 BooleanType *implicit_dep ){
00323
00324 uint run1;
00325
00326 for( run1 = 0; run1 < argument.getDim(); run1++ )
00327 if( argument.element[run1]->isDependingOn( dim, varType, component_, implicit_dep ) == BT_TRUE )
00328 return BT_TRUE;
00329 return BT_FALSE;
00330 }
00331
00332
00333 BooleanType COperator::isLinearIn( int dim,
00334 VariableType *varType,
00335 int *component_,
00336 BooleanType *implicit_dep ){
00337
00338 return BT_FALSE;
00339 }
00340
00341
00342 BooleanType COperator::isPolynomialIn( int dim,
00343 VariableType *varType,
00344 int *component_,
00345 BooleanType *implicit_dep ){
00346
00347 return BT_FALSE;
00348 }
00349
00350
00351 BooleanType COperator::isRationalIn( int dim,
00352 VariableType *varType,
00353 int *component_,
00354 BooleanType *implicit_dep ){
00355
00356 return BT_FALSE;
00357 }
00358
00359
00360 MonotonicityType COperator::getMonotonicity( ){
00361
00362 return MT_NONMONOTONIC;
00363 }
00364
00365
00366 CurvatureType COperator::getCurvature( ){
00367
00368 return CT_UNKNOWN;
00369 }
00370
00371
00372 returnValue COperator::setMonotonicity( MonotonicityType monotonicity_ ){
00373
00374 return ACADOERROR( RET_UNKNOWN_BUG );
00375 }
00376
00377
00378 returnValue COperator::setCurvature( CurvatureType curvature_ ){
00379
00380 return ACADOERROR( RET_UNKNOWN_BUG );
00381 }
00382
00383
00384 returnValue COperator::AD_forward( int number, double *x, double *seed,
00385 double *f, double *df ){
00386
00387 uint run1;
00388
00389 ASSERT( component >= 0 );
00390
00391 if( first == BT_FALSE ){
00392 f[0] = x[idx[component]];
00393 df[0] = seed[idx[component]];
00394 }
00395 else{
00396
00397 if( number >= (int) bufferSize ){
00398
00399 int oldSize = bufferSize;
00400 bufferSize += number;
00401 result = (double**)realloc(result ,bufferSize*sizeof(double*));
00402 d_result = (double**)realloc(d_result ,bufferSize*sizeof(double*));
00403 cresult = (double**)realloc(cresult ,bufferSize*sizeof(double*));
00404 d_cresult = (double**)realloc(d_cresult,bufferSize*sizeof(double*));
00405
00406 for( run1 = oldSize; run1 < bufferSize; run1++ ){
00407 result [run1] = new double[argument.getDim() ];
00408 d_result [run1] = new double[argument.getDim() ];
00409 cresult [run1] = new double[cFunction.getDim()];
00410 d_cresult[run1] = new double[cFunction.getDim()];
00411 }
00412 }
00413
00414 for( run1 = 0; run1 < argument.getDim(); run1++ )
00415 argument.element[run1]->AD_forward( number, x, seed, &result[number][run1], &d_result[number][run1] );
00416 cFunction.AD_forward( number, result[number], d_result[number], cresult[number], d_cresult[number] );
00417 f[0] = cresult[number][component];
00418 df[0] = d_cresult[number][component];
00419 for( run1 = 0; run1 < cFunction.getDim(); run1++ ){
00420 x [idx[run1]] = cresult[number][run1];
00421 seed[idx[run1]] = d_cresult[number][run1];
00422 }
00423 }
00424 return SUCCESSFUL_RETURN;
00425 }
00426
00427
00428
00429 returnValue COperator::AD_forward( int number, double *seed, double *df ){
00430
00431 uint run1;
00432
00433 ASSERT( component >= 0 );
00434
00435 if( first == BT_FALSE ){
00436 df[0] = seed[idx[component]];
00437 }
00438 else{
00439 for( run1 = 0; run1 < argument.getDim(); run1++ )
00440 argument.element[run1]->AD_forward( number, seed, &d_result[number][run1] );
00441 cFunction.AD_forward( number, d_result[number], d_cresult[number] );
00442 df[0] = d_cresult[number][component];
00443 for( run1 = 0; run1 < cFunction.getDim(); run1++ )
00444 seed[idx[run1]] = d_cresult[number][run1];
00445 }
00446 return SUCCESSFUL_RETURN;
00447 }
00448
00449
00450 returnValue COperator::AD_backward( int number, double seed, double *df ){
00451
00452 return ACADOERROR( RET_NOT_IMPLEMENTED_YET );
00453 }
00454
00455
00456 returnValue COperator::AD_forward2( int number, double *seed, double *dseed,
00457 double *df, double *ddf ){
00458
00459 uint run1;
00460
00461 ASSERT( component >= 0 );
00462
00463 if( first == BT_FALSE ){
00464 df[0] = seed[idx[component]];
00465 ddf[0] = dseed[idx[component]];
00466 }
00467 else{
00468
00469 double *d_result2 = new double[argument.getDim() ];
00470 double *d_cresult2 = new double[cFunction.getDim()];
00471
00472 double *dd_result = new double[argument.getDim() ];
00473 double *dd_cresult = new double[cFunction.getDim()];
00474
00475 for( run1 = 0; run1 < argument.getDim(); run1++ )
00476 argument.element[run1]->AD_forward2( number, seed, dseed, &d_result2[run1], &dd_result[run1] );
00477
00478 cFunction.AD_forward2( number, d_result2, dd_result, d_cresult2, dd_cresult );
00479
00480 df[0] = d_cresult2[component];
00481 ddf[0] = dd_cresult[component];
00482
00483 for( run1 = 0; run1 < cFunction.getDim(); run1++ ){
00484 seed[idx[run1]] = d_cresult2[run1];
00485 dseed[idx[run1]] = dd_cresult[run1];
00486 }
00487
00488 delete[] d_result2 ;
00489 delete[] d_cresult2 ;
00490 delete[] dd_result ;
00491 delete[] dd_cresult ;
00492 }
00493 return SUCCESSFUL_RETURN;
00494 }
00495
00496
00497 returnValue COperator::AD_backward2( int number, double seed1, double seed2,
00498 double *df, double *ddf ){
00499
00500 return ACADOERROR( RET_NOT_IMPLEMENTED_YET );
00501 }
00502
00503
00504 std::ostream& COperator::print( std::ostream& stream ) const
00505 {
00506 return stream << "C functions can not be printed";
00507 }
00508
00509
00510
00511 Operator* COperator::clone() const{
00512
00513 return new COperator(*this);
00514 }
00515
00516
00517 returnValue COperator::clearBuffer(){
00518
00519 if( bufferSize > 1 ){
00520 bufferSize = 1;
00521 result = (double**)realloc(result ,bufferSize*sizeof(double*));
00522 d_result = (double**)realloc(d_result ,bufferSize*sizeof(double*));
00523 cresult = (double**)realloc(cresult ,bufferSize*sizeof(double*));
00524 d_cresult = (double**)realloc(d_cresult,bufferSize*sizeof(double*));
00525 }
00526 return cFunction.clearBuffer();
00527 }
00528
00529
00530 returnValue COperator::enumerateVariables( SymbolicIndexList *indexList ){
00531
00532 uint run1;
00533 returnValue returnvalue;
00534
00535 for( run1 = 0; run1 < argument.getDim(); run1++ ){
00536
00537 returnvalue = argument.element[run1]->enumerateVariables( indexList );
00538 if( returnvalue != SUCCESSFUL_RETURN ) return returnvalue;
00539 }
00540
00541 first = indexList->determineCExpressionIndices( cFunction.getDim(), globalTypeID, idx );
00542
00543 return SUCCESSFUL_RETURN;
00544 }
00545
00546
00547 OperatorName COperator::getName(){
00548
00549 return ON_CEXPRESSION;
00550 }
00551
00552
00553 BooleanType COperator::isVariable( VariableType &varType, int &component_ ) const{
00554
00555 return BT_FALSE;
00556 }
00557
00558
00559 returnValue COperator::loadIndices( SymbolicIndexList *indexList ){
00560
00561 uint run1;
00562 returnValue returnvalue;
00563
00564 for( run1 = 0; run1 < argument.getDim(); run1++ ){
00565 returnvalue = argument.element[run1]->loadIndices( indexList );
00566 if( returnvalue != SUCCESSFUL_RETURN ) return returnvalue;
00567 }
00568
00569 return SUCCESSFUL_RETURN;
00570 }
00571
00572
00573 BooleanType COperator::isSymbolic() const{
00574
00575 return BT_FALSE;
00576 }
00577
00578
00579 CLOSE_NAMESPACE_ACADO
00580
00581