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/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
00410
00411
00412 OperatorName Subtraction::getName(){
00413
00414 return ON_SUBTRACTION;
00415 }
00416
00417
00418 CLOSE_NAMESPACE_ACADO
00419
00420