c_operator.cpp
Go to the documentation of this file.
00001 /*
00002  *    This file is part of ACADO Toolkit.
00003  *
00004  *    ACADO Toolkit -- A Toolkit for Automatic Control and Dynamic Optimization.
00005  *    Copyright (C) 2008-2014 by Boris Houska, Hans Joachim Ferreau,
00006  *    Milan Vukov, Rien Quirynen, KU Leuven.
00007  *    Developed within the Optimization in Engineering Center (OPTEC)
00008  *    under supervision of Moritz Diehl. All rights reserved.
00009  *
00010  *    ACADO Toolkit is free software; you can redistribute it and/or
00011  *    modify it under the terms of the GNU Lesser General Public
00012  *    License as published by the Free Software Foundation; either
00013  *    version 3 of the License, or (at your option) any later version.
00014  *
00015  *    ACADO Toolkit is distributed in the hope that it will be useful,
00016  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  *    Lesser General Public License for more details.
00019  *
00020  *    You should have received a copy of the GNU Lesser General Public
00021  *    License along with ACADO Toolkit; if not, write to the Free Software
00022  *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
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 // end of file.


acado
Author(s): Milan Vukov, Rien Quirynen
autogenerated on Thu Aug 27 2015 11:57:54