quotient.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ACADO Toolkit.
3  *
4  * ACADO Toolkit -- A Toolkit for Automatic Control and Dynamic Optimization.
5  * Copyright (C) 2008-2014 by Boris Houska, Hans Joachim Ferreau,
6  * Milan Vukov, Rien Quirynen, KU Leuven.
7  * Developed within the Optimization in Engineering Center (OPTEC)
8  * under supervision of Moritz Diehl. All rights reserved.
9  *
10  * ACADO Toolkit is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 3 of the License, or (at your option) any later version.
14  *
15  * ACADO Toolkit is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with ACADO Toolkit; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23  *
24  */
25 
26 
27 
37 
38 
39 
41 
42 
43 
44 
46  derivative0 = 0;
47  derivative1 = 0;
48  derivative2 = 0;
49 }
50 
51 Quotient::Quotient( Operator *_argument1, Operator *_argument2 )
52  :BinaryOperator( _argument1, _argument2 ){
53 
54  derivative0 = 0;
55  derivative1 = 0;
56  derivative2 = 0;
57 }
58 
59 
61 
62  derivative0 = 0;
63  derivative1 = 0;
64  derivative2 = 0;
65  if( arg.derivative0 != 0 && arg.derivative1 != 0 && arg.derivative2 != 0 ) {
66  derivative0 = arg.derivative0->clone();
67  derivative1 = arg.derivative1->clone();
68  derivative2 = arg.derivative2->clone();
69  }
70 }
71 
72 
74 
75  if( derivative2 != 0 ) {
76  delete derivative2;
77  }
78  if( derivative1 != 0 ) {
79  delete derivative1;
80  }
81  if( derivative0 != 0 ) {
82  delete derivative0;
83  }
84  derivative0 = 0;
85  derivative1 = 0;
86  derivative2 = 0;
87 }
88 
90 
91  if( this != &arg ){
92 
94  }
95  return *this;
96 }
97 
98 
99 
100 returnValue Quotient::evaluate( int number, double *x, double *result ){
101 
102  if( number >= bufferSize ){
103  bufferSize += number;
104  argument1_result = (double*)realloc( argument1_result,bufferSize*sizeof(double));
105  argument2_result = (double*)realloc( argument2_result,bufferSize*sizeof(double));
106  dargument1_result = (double*)realloc(dargument1_result,bufferSize*sizeof(double));
107  dargument2_result = (double*)realloc(dargument2_result,bufferSize*sizeof(double));
108  }
109 
110  argument1->evaluate( number, x , &argument1_result[number] );
111  argument2->evaluate( number, x , &argument2_result[number] );
112 
113  result[0] = argument1_result[number] / argument2_result[number];
114 
115  return SUCCESSFUL_RETURN;
116 }
117 
118 
120 
122  return SUCCESSFUL_RETURN;
123 }
124 
125 
127 
128  dargument1 = argument1->differentiate( index );
129  dargument2 = argument2->differentiate( index );
130 
131  Operator* prodTmp = myProd( dargument1, derivative0 );
132  Operator* prodTmp2 = myProd( argument1, dargument2 );
133  Operator* prodTmp3 = myProd( prodTmp2, derivative1 );
134  Operator* result = mySubtract( prodTmp, prodTmp3 );
135 
136  delete prodTmp;
137  delete prodTmp2;
138  delete prodTmp3;
139 
140  return result;
141 }
142 
143 
144 
145 
147  VariableType *varType,
148  int *component,
149  Operator **seed,
150  int &nNewIS,
151  TreeProjection ***newIS ){
152 
153  if( dargument1 != 0 )
154  delete dargument1;
155 
156  if( dargument2 != 0 )
157  delete dargument2;
158 
159  dargument1 = argument1->AD_forward(dim,varType,component,seed,nNewIS,newIS);
160  dargument2 = argument2->AD_forward(dim,varType,component,seed,nNewIS,newIS);
161 
162  Operator* prodTmp = myProd( dargument1, derivative0 );
163  Operator* prodTmp2 = myProd( argument1, dargument2 );
164  Operator* prodTmp3 = myProd( prodTmp2, derivative1 );
165  Operator* result = mySubtract( prodTmp, prodTmp3 );
166 
167  delete prodTmp;
168  delete prodTmp2;
169  delete prodTmp3;
170 
171  return result;
172 }
173 
174 
176  VariableType *varType ,
177  int *component,
178  Operator *seed ,
179  Operator **df ,
180  int &nNewIS ,
181  TreeProjection ***newIS ){
182 
183  if( seed->isOneOrZero() != NE_ZERO ){
184 
185  TreeProjection tmp;
186  tmp = *seed;
187 
188  Operator *prodTmp = myProd( &tmp, derivative0 );
189 
190  argument1->AD_backward( dim, varType, component, prodTmp->clone(), df, nNewIS, newIS );
191 
192  Operator *prodTmp2 = myProd( argument1, &tmp );
193  Operator *prodTmp3 = myProd( prodTmp2, derivative1 );
194  Operator *zeroTmp = new DoubleConstant( 0.0, NE_ZERO );
195  Operator *subTmp = mySubtract( zeroTmp, prodTmp3 );
196 
197  argument2->AD_backward( dim, varType, component, subTmp->clone(), df, nNewIS, newIS );
198 
199  delete zeroTmp;
200  delete prodTmp;
201  delete prodTmp2;
202  delete prodTmp3;
203  delete subTmp;
204  }
205 
206  delete seed;
207  return SUCCESSFUL_RETURN;
208 }
209 
210 
212  VariableType *varType ,
213  int *component ,
214  Operator *l ,
215  Operator **S ,
216  int dimS ,
217  Operator **dfS ,
218  Operator **ldf ,
219  Operator **H ,
220  int &nNewLIS ,
221  TreeProjection ***newLIS ,
222  int &nNewSIS ,
223  TreeProjection ***newSIS ,
224  int &nNewHIS ,
225  TreeProjection ***newHIS ){
226 
227  TreeProjection dy,dxx,dxy,dyy;
228 
231  dxx = DoubleConstant(0.0,NE_ZERO);
232  dy = Product( dxy.clone(), argument1->clone() );
234  argument1->clone() );
235 
236  return ADsymCommon2( argument1,argument2,dx,dy,dxx,dxy,dyy, dim, varType, component, l, S, dimS, dfS,
237  ldf, H, nNewLIS, newLIS, nNewSIS, newSIS, nNewHIS, newHIS );
238 }
239 
240 
242 
243  if( initialized ) return SUCCESSFUL_RETURN;
245 
249 
251  return argument2->initDerivative();
252 }
253 
254 
255 Operator* Quotient::substitute( int index, const Operator *sub ){
256 
257  return new Quotient( argument1->substitute( index , sub ),
258  argument2->substitute( index , sub ) );
259 
260 }
261 
262 
264  VariableType *varType,
265  int *component,
266  BooleanType *implicit_dep ){
267 
268  if( argument1->isLinearIn( dim, varType, component, implicit_dep ) == BT_TRUE &&
269  argument2->isDependingOn( dim, varType, component, implicit_dep ) == BT_FALSE ){
270  return BT_TRUE;
271  }
272 
273  return BT_FALSE;
274 }
275 
276 
278  VariableType *varType,
279  int *component,
280  BooleanType *implicit_dep ){
281 
282  if( argument1->isPolynomialIn( dim, varType, component, implicit_dep ) == BT_TRUE &&
283  argument2->isDependingOn( dim, varType, component, implicit_dep ) == BT_FALSE ){
284  return BT_TRUE;
285  }
286 
287  return BT_FALSE;
288 }
289 
290 
292  VariableType *varType,
293  int *component,
294  BooleanType *implicit_dep ){
295 
296  if( argument1->isRationalIn( dim, varType, component, implicit_dep ) == BT_TRUE &&
297  argument2->isRationalIn( dim, varType, component, implicit_dep ) == BT_TRUE ){
298  return BT_TRUE;
299  }
300 
301  return BT_FALSE;
302 }
303 
304 
306 
307  if( monotonicity != MT_UNKNOWN ) return monotonicity;
308 
309  MonotonicityType m1, m2;
310 
311  m1 = argument1->getMonotonicity();
312  m2 = argument2->getMonotonicity();
313 
314  if( m2 == MT_CONSTANT ){
315 
316  if( m1 == MT_CONSTANT ) return MT_CONSTANT;
317 
318  double res;
319  argument2->evaluate(0,0,&res);
320 
321  if( res >= 0.0 ) return m1;
322 
323  if( m1 == MT_NONDECREASING ) return MT_NONINCREASING;
324  if( m1 == MT_NONINCREASING ) return MT_NONDECREASING;
325 
326  return MT_NONMONOTONIC;
327  }
328 
329  return MT_NONMONOTONIC;
330 }
331 
332 
334 
335  if( curvature != CT_UNKNOWN ) return curvature;
336 
337  CurvatureType c1, c2;
338 
339  c1 = argument1->getCurvature();
340  c2 = argument2->getCurvature();
341 
342  if( c2 == CT_CONSTANT ){
343 
344  if( c1 == CT_CONSTANT ) return CT_CONSTANT;
345 
346  double res;
347  argument2->evaluate(0,0,&res);
348 
349  if( res >= 0.0 ) return c1;
350 
351  if( c1 == CT_AFFINE ) return CT_AFFINE ;
352  if( c1 == CT_CONVEX ) return CT_CONCAVE;
353  if( c1 == CT_CONCAVE ) return CT_CONVEX ;
354 
356  }
357 
359 }
360 
361 
362 double Quotient::getValue() const
363 {
364  if ( ( argument1 == 0 ) || ( argument2 == 0 ) )
365  return INFTY;
366 
367  if ( ( acadoIsEqual( argument1->getValue(),INFTY ) == BT_TRUE ) ||
369  return INFTY;
370 
371  if (acadoIsZero( argument2->getValue() ) == BT_TRUE)
373 
374  return (argument1->getValue() / argument2->getValue());
375 }
376 
377 returnValue Quotient::AD_forward( int number, double *x, double *seed,
378  double *f, double *df ){
379 
380  if( number >= bufferSize ){
381  bufferSize += number;
382  argument1_result = (double*)realloc( argument1_result,bufferSize*sizeof(double));
383  argument2_result = (double*)realloc( argument2_result,bufferSize*sizeof(double));
384  dargument1_result = (double*)realloc(dargument1_result,bufferSize*sizeof(double));
385  dargument2_result = (double*)realloc(dargument2_result,bufferSize*sizeof(double));
386  }
387 
388  argument1->AD_forward( number, x, seed, &argument1_result[number],
389  &dargument1_result[number] );
390  argument2->AD_forward( number,
391  x, seed, &argument2_result[number], &dargument2_result[number] );
392 
393  f[0] = argument1_result[number]/argument2_result[number];
394  df[0] = dargument1_result[number]/argument2_result[number]
395  -(argument1_result[number]*dargument2_result[number])/
396  (argument2_result[number]*argument2_result[number] );
397 
398  return SUCCESSFUL_RETURN;
399 }
400 
401 
402 
403 returnValue Quotient::AD_forward( int number, double *seed, double *df ){
404 
405  argument1->AD_forward( number, seed, &dargument1_result[number] );
406  argument2->AD_forward( number, seed, &dargument2_result[number] );
407 
408  df[0] = dargument1_result[number]/argument2_result[number]
409  -(argument1_result[number]*dargument2_result[number])/
410  (argument2_result[number]*argument2_result[number] );
411 
412  return SUCCESSFUL_RETURN;
413 }
414 
415 
416 returnValue Quotient::AD_backward( int number, double seed, double *df ){
417 
418  argument1->AD_backward( number, seed/argument2_result[number], df );
419  argument2->AD_backward( number, -argument1_result[number]*seed/
420  (argument2_result[number]*argument2_result[number]), df );
421 
422  return SUCCESSFUL_RETURN;
423 }
424 
425 
426 returnValue Quotient::AD_forward2( int number, double *seed, double *dseed,
427  double *df, double *ddf ){
428 
429  double ddargument1_result;
430  double ddargument2_result;
431  double dargument_result1;
432  double dargument_result2;
433 
434  argument1->AD_forward2( number, seed, dseed,
435  &dargument_result1, &ddargument1_result);
436  argument2->AD_forward2( number, seed, dseed,
437  &dargument_result2, &ddargument2_result);
438 
439  const double gg = argument2_result[number]*argument2_result[number];
440  const double ggg = dargument_result2/gg;
441 
442  df[0] = dargument_result1/argument2_result[number]
443  -argument1_result[number]*ggg;
444 
445  ddf[0] = ddargument1_result/argument2_result[number]
446  -argument1_result[number]*ddargument2_result/gg
447  -dargument_result2*dargument1_result[number]/gg
448  -dargument_result1*dargument2_result[number]/gg
449  +2.0*argument1_result[number]/(gg*argument2_result[number])
450  *dargument_result2*dargument2_result[number];
451 
452  return SUCCESSFUL_RETURN;
453 }
454 
455 
456 returnValue Quotient::AD_backward2( int number, double seed1, double seed2,
457  double *df, double *ddf ){
458 
459  const double gg = argument2_result[number]*argument2_result[number];
460  const double ggg = argument1_result[number]/gg;
461 
462  argument1->AD_backward2( number, seed1/argument2_result[number],
463  seed2/argument2_result[number] -
464  seed1*dargument2_result[number]/gg, df, ddf );
465 
466  argument2->AD_backward2( number, -seed1*ggg,
467  -seed2*ggg
468  -seed1*dargument1_result[number]/gg
469  +2.0*ggg/argument2_result[number]
470  *seed1*dargument2_result[number],
471  df, ddf );
472 
473  return SUCCESSFUL_RETURN;
474 }
475 
476 
477 std::ostream& Quotient::print( std::ostream &stream ) const{
478 
479  return stream << "(" << *argument1 << "/" << *argument2 << ")";
480 }
481 
482 
484 
485  return new Quotient(*this);
486 }
487 
488 
490 
491  return ON_QUOTIENT;
492 }
493 
494 
496 
497 // end of file.
OperatorName
Definition: acado_types.hpp:72
Operator * dargument1
virtual returnValue AD_forward2(int number, double *seed1, double *seed2, double *df, double *ddf)=0
virtual MonotonicityType getMonotonicity()=0
Operator * dargument2
TreeProjection * derivative1
Definition: quotient.hpp:342
virtual returnValue AD_backward2(int number, double seed1, double seed2, double *df, double *ddf)
Definition: quotient.cpp:456
Abstract base class for all scalar-valued binary operators within the symbolic operators family...
Quotient()
Definition: quotient.cpp:45
Abstract base class for all scalar-valued symbolic operators.
Definition: operator.hpp:60
virtual BooleanType isDependingOn(VariableType var) const =0
BooleanType acadoIsEqual(double x, double y, double TOL)
Definition: acado_utils.cpp:88
const double INFTY
virtual NeutralElement isOneOrZero() const =0
virtual Operator * clone() const
Definition: quotient.cpp:483
CurvatureType curvature
double * argument1_result
virtual returnValue evaluate(int number, double *x, double *result)
Definition: quotient.cpp:100
virtual Operator * differentiate(int index)=0
Allows to pass back messages to the calling function.
virtual Operator * clone() const =0
virtual BooleanType isRationalIn(int dim, VariableType *varType, int *component, BooleanType *implicit_dep)
Definition: quotient.cpp:291
virtual Operator * substitute(int index, const Operator *sub)=0
virtual std::ostream & print(std::ostream &stream) const
Definition: quotient.cpp:477
Operator * argument2
virtual double getValue() const
Definition: operator.cpp:211
virtual returnValue AD_backward(int dim, VariableType *varType, int *component, Operator *seed, Operator **df, int &nNewIS, TreeProjection ***newIS)
Definition: quotient.cpp:175
#define CLOSE_NAMESPACE_ACADO
virtual void quotient(Operator &arg1, Operator &arg2)=0
VariableType
Definition: acado_types.hpp:95
BooleanType initialized
Definition: operator.hpp:642
virtual BooleanType isPolynomialIn(int dim, VariableType *varType, int *component, BooleanType *implicit_dep)
Definition: quotient.cpp:277
double * dargument2_result
virtual Operator * mySubtract(Operator *a, Operator *b)
Definition: operator.cpp:263
#define ACADOFATAL(retval)
virtual Operator * AD_forward(int dim, VariableType *varType, int *component, Operator **seed, int &nNewIS, TreeProjection ***newIS)=0
returnValue ADsymCommon2(Operator *a, Operator *b, TreeProjection &dx, TreeProjection &dy, TreeProjection &dxx, TreeProjection &dxy, TreeProjection &dyy, int dim, VariableType *varType, int *component, Operator *l, Operator **S, int dimS, Operator **dfS, Operator **ldf, Operator **H, int &nNewLIS, TreeProjection ***newLIS, int &nNewSIS, TreeProjection ***newSIS, int &nNewHIS, TreeProjection ***newHIS)
Definition: operator.cpp:387
virtual returnValue initDerivative()
Definition: quotient.cpp:241
Operator * argument1
virtual returnValue AD_backward2(int number, double seed1, double seed2, double *df, double *ddf)=0
virtual Operator * AD_forward(int dim, VariableType *varType, int *component, Operator **seed, int &nNewIS, TreeProjection ***newIS)
Definition: quotient.cpp:146
MonotonicityType monotonicity
TreeProjection * derivative0
Definition: quotient.hpp:341
virtual returnValue AD_forward2(int number, double *seed1, double *seed2, double *df, double *ddf)
Definition: quotient.cpp:426
virtual Operator * myProd(Operator *a, Operator *b)
Definition: operator.cpp:232
double * argument2_result
virtual returnValue AD_backward(int dim, VariableType *varType, int *component, Operator *seed, Operator **df, int &nNewIS, TreeProjection ***newIS)=0
double * dargument1_result
virtual Operator * substitute(int index, const Operator *sub)
Definition: quotient.cpp:255
virtual returnValue initDerivative()
Definition: operator.cpp:519
TreeProjection * derivative2
Definition: quotient.hpp:343
virtual MonotonicityType getMonotonicity()
Definition: quotient.cpp:305
virtual BooleanType isLinearIn(int dim, VariableType *varType, int *component, BooleanType *implicit_dep)=0
virtual returnValue evaluate(int number, double *x, double *result)=0
virtual OperatorName getName()
Definition: quotient.cpp:489
#define BT_TRUE
Definition: acado_types.hpp:47
BooleanType acadoIsZero(double x, double TOL)
virtual BooleanType isPolynomialIn(int dim, VariableType *varType, int *component, BooleanType *implicit_dep)=0
Implements the scalar quotient operator within the symbolic operators family.
Definition: quotient.hpp:55
MonotonicityType
Implements the tree-projection operator within the family of SymbolicOperators.
CurvatureType
virtual TreeProjection * convert2TreeProjection(Operator *a) const
Definition: operator.cpp:312
BinaryOperator & operator=(const BinaryOperator &arg)
#define BEGIN_NAMESPACE_ACADO
virtual returnValue AD_symmetric(int dim, VariableType *varType, int *component, Operator *l, Operator **S, int dimS, Operator **dfS, Operator **ldf, Operator **H, int &nNewLIS, TreeProjection ***newLIS, int &nNewSIS, TreeProjection ***newSIS, int &nNewHIS, TreeProjection ***newHIS)
Definition: quotient.cpp:211
Abstract base class for templated evaluation of operators.
#define BT_FALSE
Definition: acado_types.hpp:49
virtual CurvatureType getCurvature()=0
virtual BooleanType isRationalIn(int dim, VariableType *varType, int *component, BooleanType *implicit_dep)=0
virtual double getValue() const
Definition: quotient.cpp:362
virtual TreeProjection * clone() const
virtual CurvatureType getCurvature()
Definition: quotient.cpp:333
Quotient & operator=(const Quotient &arg)
Definition: quotient.cpp:89
~Quotient()
Definition: quotient.cpp:73
Implements a scalar constant within the symbolic operators family.
virtual BooleanType isLinearIn(int dim, VariableType *varType, int *component, BooleanType *implicit_dep)
Definition: quotient.cpp:263
virtual Operator * differentiate(int index)
Definition: quotient.cpp:126
Implements the scalar product operator within the symbolic operators family.
Definition: product.hpp:55


acado
Author(s): Milan Vukov, Rien Quirynen
autogenerated on Mon Jun 10 2019 12:35:02