subtraction.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/symbolic_operator/symbolic_operator.hpp>
00037 
00038 
00039 
00040 BEGIN_NAMESPACE_ACADO
00041 
00042 
00043 
00044 Subtraction::Subtraction():BinaryOperator(){}
00045 
00046 Subtraction::Subtraction( Operator *_argument1, Operator *_argument2 )
00047             :BinaryOperator( _argument1, _argument2 ){
00048 
00049 }
00050 
00051 Subtraction::Subtraction( const Subtraction &arg ):BinaryOperator( arg ){ }
00052 
00053 Subtraction::~Subtraction(){ }
00054 
00055 
00056 
00057 Subtraction& Subtraction::operator=( const Subtraction &arg ){
00058 
00059     if( this != &arg ){
00060 
00061         BinaryOperator::operator=( arg );
00062     }
00063     return *this;
00064 }
00065 
00066 
00067 returnValue Subtraction::evaluate( int number, double *x, double *result ){
00068 
00069     if( number >= bufferSize ){
00070         bufferSize += number;
00071         argument1_result  = (double*)realloc( argument1_result,bufferSize*sizeof(double));
00072         argument2_result  = (double*)realloc( argument2_result,bufferSize*sizeof(double));
00073         dargument1_result = (double*)realloc(dargument1_result,bufferSize*sizeof(double));
00074         dargument2_result = (double*)realloc(dargument2_result,bufferSize*sizeof(double));
00075     }
00076 
00077     argument1->evaluate( number, x , &argument1_result[number] );
00078     argument2->evaluate( number, x , &argument2_result[number] );
00079 
00080     result[0] = argument1_result[number] - argument2_result[number];
00081 
00082     return SUCCESSFUL_RETURN;
00083 }
00084 
00085 
00086 returnValue Subtraction::evaluate( EvaluationBase *x ){
00087 
00088     x->subtraction(*argument1,*argument2);
00089     return SUCCESSFUL_RETURN;
00090 }
00091 
00092 
00093 Operator* Subtraction::differentiate( int index ){
00094 
00095   dargument1 = argument1->differentiate( index );
00096   dargument2 = argument2->differentiate( index );
00097 
00098   return mySubtract( dargument1, dargument2 );
00099 
00100 }
00101 
00102 
00103 Operator* Subtraction::AD_forward( int dim,
00104                                      VariableType *varType,
00105                                      int *component,
00106                                      Operator **seed,
00107                                      int &nNewIS,
00108                                      TreeProjection ***newIS ){
00109 
00110     if( dargument1 != 0 )
00111         delete dargument1;
00112 
00113     if( dargument2 != 0 )
00114         delete dargument2;
00115 
00116     dargument1 = argument1->AD_forward(dim,varType,component,seed,nNewIS,newIS);
00117     dargument2 = argument2->AD_forward(dim,varType,component,seed,nNewIS,newIS);
00118 
00119     return mySubtract( dargument1, dargument2 );
00120 }
00121 
00122 
00123 returnValue Subtraction::AD_backward( int           dim      , 
00124                                         VariableType *varType  , 
00125                                         int          *component, 
00126                                         Operator     *seed     , 
00127                                         Operator    **df       , 
00128                                         int           &nNewIS  , 
00129                                         TreeProjection ***newIS   ){
00130 
00131     TreeProjection tmp;
00132     tmp = *seed;
00133 
00134     argument1->AD_backward( dim, varType, component, tmp.clone(), df, nNewIS, newIS );
00135 
00136     if( seed->isOneOrZero() != NE_ZERO ){
00137         argument2->AD_backward( dim, varType, component,
00138                                 new Subtraction( new DoubleConstant( 0.0 , NE_ZERO ), tmp.clone() ), df, nNewIS, newIS );
00139     }
00140 
00141     delete seed;
00142     return SUCCESSFUL_RETURN;
00143 }
00144 
00145 
00146 returnValue Subtraction::AD_symmetric( int            dim       , 
00147                                         VariableType  *varType   , 
00148                                         int           *component , 
00149                                         Operator      *l         , 
00150                                         Operator     **S         , 
00151                                         int            dimS      , 
00152                                         Operator     **dfS       , 
00153                                         Operator     **ldf       , 
00154                                         Operator     **H         , 
00155                                       int            &nNewLIS  , 
00156                                       TreeProjection ***newLIS , 
00157                                       int            &nNewSIS  , 
00158                                       TreeProjection ***newSIS , 
00159                                       int            &nNewHIS  , 
00160                                       TreeProjection ***newHIS    ){
00161   
00162     TreeProjection dx,dy,dxx,dxy,dyy;
00163     
00164     dx  = DoubleConstant(1.0,NE_ONE );
00165     dy  = DoubleConstant(-1.0,NE_NEITHER_ONE_NOR_ZERO );
00166     dxx = DoubleConstant(0.0,NE_ZERO);
00167     dxy = DoubleConstant(0.0,NE_ZERO);
00168     dyy = DoubleConstant(0.0,NE_ZERO);
00169     
00170     return ADsymCommon2( argument1,argument2,dx,dy,dxx,dxy,dyy, dim, varType, component, l, S, dimS, dfS,
00171                           ldf, H, nNewLIS, newLIS, nNewSIS, newSIS, nNewHIS, newHIS );
00172 }
00173 
00174 
00175 Operator* Subtraction::substitute( int index, const Operator *sub ){
00176 
00177     return new Subtraction( argument1->substitute( index , sub ),
00178                             argument2->substitute( index , sub ) );
00179 
00180 }
00181 
00182 
00183 BooleanType Subtraction::isLinearIn( int dim,
00184                                        VariableType *varType,
00185                                        int *component,
00186                                        BooleanType   *implicit_dep ){
00187 
00188     if( argument1->isLinearIn( dim, varType, component, implicit_dep ) == BT_TRUE &&
00189         argument2->isLinearIn( dim, varType, component, implicit_dep ) == BT_TRUE ){
00190         return BT_TRUE;
00191     }
00192 
00193     return BT_FALSE;
00194 }
00195 
00196 
00197 BooleanType Subtraction::isPolynomialIn( int dim,
00198                                            VariableType *varType,
00199                                            int *component,
00200                                            BooleanType   *implicit_dep ){
00201 
00202     if( argument1->isPolynomialIn( dim, varType, component, implicit_dep ) == BT_TRUE &&
00203         argument2->isPolynomialIn( dim, varType, component, implicit_dep ) == BT_TRUE ){
00204         return BT_TRUE;
00205     }
00206 
00207     return BT_FALSE;
00208 }
00209 
00210 
00211 BooleanType Subtraction::isRationalIn( int dim,
00212                                          VariableType *varType,
00213                                          int *component,
00214                                          BooleanType   *implicit_dep ){
00215 
00216     if( argument1->isRationalIn( dim, varType, component, implicit_dep ) == BT_TRUE &&
00217         argument2->isRationalIn( dim, varType, component, implicit_dep ) == BT_TRUE ){
00218         return BT_TRUE;
00219     }
00220 
00221     return BT_FALSE;
00222 }
00223 
00224 
00225 MonotonicityType Subtraction::getMonotonicity( ){
00226 
00227     if( monotonicity != MT_UNKNOWN )  return monotonicity;
00228 
00229     MonotonicityType m1, m2;
00230 
00231     m1 = argument1->getMonotonicity();
00232     m2 = argument2->getMonotonicity();
00233 
00234     if( m1 == MT_CONSTANT ){
00235 
00236         if( m2 == MT_CONSTANT      )  return MT_CONSTANT     ;
00237         if( m2 == MT_NONDECREASING )  return MT_NONINCREASING;
00238         if( m2 == MT_NONINCREASING )  return MT_NONDECREASING;
00239 
00240         return MT_NONMONOTONIC;
00241     }
00242 
00243     if( m1 == MT_NONDECREASING ){
00244 
00245         if( m2 == MT_CONSTANT      )  return MT_NONDECREASING;
00246         if( m2 == MT_NONINCREASING )  return MT_NONDECREASING;
00247 
00248         return MT_NONMONOTONIC;
00249     }
00250 
00251     if( m1 == MT_NONINCREASING ){
00252 
00253         if( m2 == MT_CONSTANT      )  return MT_NONINCREASING;
00254         if( m2 == MT_NONDECREASING )  return MT_NONINCREASING;
00255 
00256         return MT_NONMONOTONIC;
00257     }
00258 
00259     return MT_NONMONOTONIC;
00260 }
00261 
00262 
00263 CurvatureType Subtraction::getCurvature( ){
00264 
00265     if( curvature != CT_UNKNOWN )  return curvature;
00266 
00267     CurvatureType c1, c2;
00268 
00269     c1 = argument1->getCurvature();
00270     c2 = argument2->getCurvature();
00271 
00272     if( c1 == CT_CONSTANT ){
00273 
00274         if( c2 == CT_CONSTANT )  return CT_CONSTANT;
00275         if( c2 == CT_AFFINE   )  return CT_AFFINE  ;
00276         if( c2 == CT_CONVEX   )  return CT_CONCAVE ;
00277         if( c2 == CT_CONCAVE  )  return CT_CONVEX  ;
00278     }
00279 
00280     if( c1 == CT_AFFINE ){
00281 
00282         if( c2 == CT_CONSTANT )  return CT_AFFINE  ;
00283         if( c2 == CT_AFFINE   )  return CT_AFFINE  ;
00284         if( c2 == CT_CONVEX   )  return CT_CONCAVE ;
00285         if( c2 == CT_CONCAVE  )  return CT_CONVEX  ;
00286     }
00287 
00288     if( c1 == CT_CONVEX ){
00289 
00290         if( c2 == CT_CONSTANT )  return CT_CONVEX  ;
00291         if( c2 == CT_AFFINE   )  return CT_CONVEX  ;
00292         if( c2 == CT_CONCAVE  )  return CT_CONVEX  ;
00293 
00294         return CT_NEITHER_CONVEX_NOR_CONCAVE;
00295     }
00296 
00297     if( c1 == CT_CONCAVE ){
00298 
00299         if( c2 == CT_CONSTANT )  return CT_CONCAVE ;
00300         if( c2 == CT_AFFINE   )  return CT_CONCAVE ;
00301         if( c2 == CT_CONVEX   )  return CT_CONCAVE ;
00302 
00303         return CT_NEITHER_CONVEX_NOR_CONCAVE;
00304     }
00305 
00306     return CT_NEITHER_CONVEX_NOR_CONCAVE;
00307 }
00308 
00309 
00310 double Subtraction::getValue() const
00311 { 
00312         if ( ( argument1 == 0 ) || ( argument2 == 0 ) )
00313                 return INFTY;
00314                 
00315         if ( ( acadoIsEqual( argument1->getValue(),INFTY ) == BT_TRUE ) ||
00316                  ( acadoIsEqual( argument2->getValue(),INFTY ) == BT_TRUE ) )
00317                 return INFTY;
00318                 
00319         return (argument1->getValue() - argument2->getValue());
00320 }
00321 
00322 
00323 returnValue Subtraction::AD_forward( int number, double *x, double *seed,
00324                                      double *f, double *df ){
00325 
00326     if( number >= bufferSize ){
00327         bufferSize += number;
00328         argument1_result  = (double*)realloc( argument1_result,bufferSize*sizeof(double));
00329         argument2_result  = (double*)realloc( argument2_result,bufferSize*sizeof(double));
00330         dargument1_result = (double*)realloc(dargument1_result,bufferSize*sizeof(double));
00331         dargument2_result = (double*)realloc(dargument2_result,bufferSize*sizeof(double));
00332     }
00333 
00334     argument1->AD_forward( number, x, seed, &argument1_result[number],
00335                            &dargument1_result[number] );
00336     argument2->AD_forward( number, x, seed, &argument2_result[number],
00337                            &dargument2_result[number] );
00338 
00339       f[0] =  argument1_result[number] -  argument2_result[number];
00340      df[0] = dargument1_result[number] - dargument2_result[number];
00341 
00342      return SUCCESSFUL_RETURN;
00343 }
00344 
00345 
00346 returnValue Subtraction::AD_forward( int number, double *seed, double *df ){
00347 
00348     argument1->AD_forward( number, seed, &dargument1_result[number] );
00349     argument2->AD_forward( number, seed, &dargument2_result[number] );
00350 
00351      df[0] = dargument1_result[number] - dargument2_result[number];
00352 
00353      return SUCCESSFUL_RETURN;
00354 }
00355 
00356 
00357 returnValue Subtraction::AD_backward( int number, double seed, double *df ){
00358 
00359     argument1->AD_backward( number,  seed, df );
00360     argument2->AD_backward( number, -seed, df );
00361 
00362     return SUCCESSFUL_RETURN;
00363 }
00364 
00365 
00366 returnValue Subtraction::AD_forward2( int number, double *seed, double *dseed,
00367                                       double *df, double *ddf ){
00368 
00369     double      ddargument1_result;
00370     double      ddargument2_result;
00371     double      dargument_result1 ;
00372     double      dargument_result2 ;
00373 
00374     argument1->AD_forward2( number, seed, dseed,
00375                             &dargument_result1, &ddargument1_result);
00376     argument2->AD_forward2( number, seed, dseed,
00377                             &dargument_result2, &ddargument2_result);
00378 
00379      df[0] =  dargument_result1         -  dargument_result2   ;
00380     ddf[0] = ddargument1_result         - ddargument2_result   ;
00381 
00382     return SUCCESSFUL_RETURN;
00383 }
00384 
00385 
00386 returnValue Subtraction::AD_backward2( int number, double seed1, double seed2,
00387                                        double *df, double *ddf ){
00388 
00389     argument1->AD_backward2( number,  seed1,  seed2, df, ddf );
00390     argument2->AD_backward2( number, -seed1, -seed2, df, ddf );
00391 
00392     return SUCCESSFUL_RETURN;
00393 }
00394 
00395 
00396 std::ostream& Subtraction::print( std::ostream &stream ) const{
00397 
00398     return stream << "(" << *argument1 << "-" << *argument2 << ")";
00399 }
00400 
00401 
00402 Operator* Subtraction::clone() const{
00403 
00404     return new Subtraction(*this);
00405 }
00406 
00407 
00408 //
00409 // PROTECTED MEMBER FUNCTIONS:
00410 // ---------------------------
00411 
00412 OperatorName Subtraction::getName(){
00413 
00414     return ON_SUBTRACTION;
00415 }
00416 
00417 
00418 CLOSE_NAMESPACE_ACADO
00419 
00420 // end of file.


acado
Author(s): Milan Vukov, Rien Quirynen
autogenerated on Sat Jun 8 2019 19:39:43