power.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 
47  derivative01 = 0;
48  derivative02 = 0;
49  derivative12 = 0;
50  derivative21 = 0;
51  derivative22 = 0;
52  derivative23 = 0;
53 }
54 
55 Power::Power( Operator *_argument1, Operator *_argument2 )
56  :BinaryOperator( _argument1, _argument2 ){
57 
58  derivative01 = 0;
59  derivative02 = 0;
60  derivative12 = 0;
61  derivative21 = 0;
62  derivative22 = 0;
63  derivative23 = 0;
64 }
65 
66 Power::Power( const Power &arg ):BinaryOperator( arg ){
67 
68  derivative01 = 0;
69  derivative02 = 0;
70  derivative12 = 0;
71  derivative21 = 0;
72  derivative22 = 0;
73  derivative23 = 0;
74  if( arg.derivative01 != 0 ) {
81  }
82 }
83 
84 
86 
87  if( derivative01 != 0 ) {
88  delete derivative01;
89  }
90  if( derivative02 != 0 ) {
91  delete derivative02;
92  }
93  if( derivative12 != 0 ) {
94  delete derivative12;
95  }
96  if( derivative21 != 0 ) {
97  delete derivative21;
98  }
99  if( derivative22 != 0 ) {
100  delete derivative22;
101  }
102  if( derivative23 != 0 ) {
103  delete derivative23;
104  }
105  derivative01 = 0;
106  derivative02 = 0;
107  derivative12 = 0;
108  derivative21 = 0;
109  derivative22 = 0;
110  derivative23 = 0;
111 }
112 
113 
114 Power& Power::operator=( const Power &arg ){
115 
116  if( this != &arg ){
117 
119  }
120  return *this;
121 }
122 
123 
124 returnValue Power::evaluate( int number, double *x, double *result ){
125 
126  if( number >= bufferSize ){
127  bufferSize += number;
128  argument1_result = (double*)realloc( argument1_result,bufferSize*sizeof(double));
129  argument2_result = (double*)realloc( argument2_result,bufferSize*sizeof(double));
130  dargument1_result = (double*)realloc(dargument1_result,bufferSize*sizeof(double));
131  dargument2_result = (double*)realloc(dargument2_result,bufferSize*sizeof(double));
132  }
133 
134  argument1->evaluate( number, x , &argument1_result[number] );
135  argument2->evaluate( number, x , &argument2_result[number] );
136 
137  result[0] = pow( argument1_result[number], argument2_result[number] );
138 
139  return SUCCESSFUL_RETURN;
140 }
141 
142 
144 
145  x->power(*argument1,*argument2);
146  return SUCCESSFUL_RETURN;
147 }
148 
149 
151 
152  dargument1 = argument1->differentiate( index );
153  dargument2 = argument2->differentiate( index );
154 
155  Operator *prodTmp1 = myProd( this, derivative02);
156  Operator *prodTmp2 = myProd( dargument2, prodTmp1 );
157  Operator *prodTmp4 = myProd( dargument1, derivative12 );
158 
159  Operator *result = myAdd( prodTmp2, prodTmp4 );
160 
161  delete prodTmp1;
162  delete prodTmp2;
163  delete prodTmp4;
164 
165  return result;
166 
167 }
168 
169 
171  VariableType *varType,
172  int *component,
173  Operator **seed,
174  int &nNewIS,
175  TreeProjection ***newIS ){
176 
177  if( dargument1 != 0 )
178  delete dargument1;
179 
180  if( dargument2 != 0 )
181  delete dargument2;
182 
183  dargument1 = argument1->AD_forward(dim,varType,component,seed,nNewIS,newIS);
184  dargument2 = argument2->AD_forward(dim,varType,component,seed,nNewIS,newIS);
185 
186  Operator *prodTmp1 = myProd( this, derivative02);
187  Operator *prodTmp2 = myProd( dargument2, prodTmp1 );
188  Operator *prodTmp4 = myProd( dargument1, derivative12 );
189 
190  Operator *result = myAdd( prodTmp2, prodTmp4 );
191 
192  delete prodTmp1;
193  delete prodTmp2;
194  delete prodTmp4;
195 
196  return result;
197 }
198 
199 
201  VariableType *varType ,
202  int *component,
203  Operator *seed ,
204  Operator **df ,
205  int &nNewIS ,
206  TreeProjection ***newIS ){
207 
208  if( seed->isOneOrZero() != NE_ZERO ){
209 
210  TreeProjection tmp;
211  tmp = *seed;
212 
213  Operator *prodTmp4 = myProd( &tmp, derivative12 );
214 
215  argument1->AD_backward( dim, varType, component, prodTmp4->clone(), df, nNewIS, newIS );
216 
217  Operator *prodTmp1 = myProd( this, derivative02);
218  Operator *prodTmp2 = myProd( &tmp, prodTmp1 );
219 
220  argument2->AD_backward( dim, varType, component, prodTmp2->clone(), df, nNewIS, newIS );
221 
222  delete prodTmp1;
223  delete prodTmp2;
224  delete prodTmp4;
225  }
226 
227  delete seed;
228  return SUCCESSFUL_RETURN;
229 }
230 
231 
233  VariableType *varType ,
234  int *component ,
235  Operator *l ,
236  Operator **S ,
237  int dimS ,
238  Operator **dfS ,
239  Operator **ldf ,
240  Operator **H ,
241  int &nNewLIS ,
242  TreeProjection ***newLIS ,
243  int &nNewSIS ,
244  TreeProjection ***newSIS ,
245  int &nNewHIS ,
246  TreeProjection ***newHIS ){
247 
248  TreeProjection dyy, dy;
249 
251  dy = Product( clone(), derivative02->clone());
254  dyy = Product( dy.clone(), derivative02->clone() );
255 
256  return ADsymCommon2( argument1,argument2,dx,dy,dxx,dxy,dyy, dim, varType, component, l, S, dimS, dfS,
257  ldf, H, nNewLIS, newLIS, nNewSIS, newSIS, nNewHIS, newHIS );
258 }
259 
260 
262 
263  if( initialized ) return SUCCESSFUL_RETURN;
265 
266  Operator *oneTmp = new DoubleConstant(1.0, NE_ONE);
267  Operator *subTmp = mySubtract( argument2, oneTmp );
268 
271 
273 
275  Operator *subTmp2 = mySubtract( argument2, twoTmp );
276  Operator *prodTmp = myProd( argument2, subTmp );
277  Operator *prodTmp2 = myProd( argument2, derivative02 );
278  Operator *addTmp = myAdd( oneTmp, prodTmp2 );
279 
283 
284  delete oneTmp;
285  delete subTmp;
286  delete twoTmp;
287  delete subTmp2;
288  delete prodTmp;
289  delete prodTmp2;
290  delete addTmp;
291 
293  return argument2->initDerivative();
294 }
295 
296 
297 Operator* Power::substitute( int index, const Operator *sub ){
298 
299  return new Power( argument1->substitute( index , sub ),
300  argument2->substitute( index , sub ) );
301 
302 }
303 
304 
306  VariableType *varType,
307  int *component,
308  BooleanType *implicit_dep ){
309 
310  if( argument2->isOneOrZero() == NE_ZERO ){
311  return BT_TRUE;
312  }
313 
314  if( argument1->isOneOrZero() == NE_ONE ){
315  return BT_TRUE;
316  }
317 
318  if( argument1->isOneOrZero() == NE_ZERO ){
319  return BT_TRUE;
320  }
321 
322  if( argument1->isLinearIn( dim, varType, component, implicit_dep ) == BT_TRUE &&
323  argument2->isOneOrZero() == NE_ONE ){
324  return BT_TRUE;
325  }
326 
327  if( isDependingOn( dim, varType, component, implicit_dep) == BT_FALSE ){
328  return BT_TRUE;
329  }
330 
331  return BT_FALSE;
332 }
333 
334 
336  VariableType *varType,
337  int *component,
338  BooleanType *implicit_dep ){
339 
340  if( argument1->isPolynomialIn( dim, varType, component, implicit_dep ) == BT_TRUE &&
341  argument2->isDependingOn( dim, varType, component, implicit_dep ) == BT_FALSE ){
342  return BT_TRUE;
343  }
344 
345  return BT_FALSE;
346 }
347 
348 
350  VariableType *varType,
351  int *component,
352  BooleanType *implicit_dep ){
353 
354  if( argument1->isRationalIn( dim, varType, component, implicit_dep ) == BT_TRUE &&
355  argument2->isDependingOn( dim, varType, component, implicit_dep ) == BT_FALSE ){
356  return BT_TRUE;
357  }
358 
359  return BT_FALSE;
360 }
361 
362 
364 
365  if( monotonicity != MT_UNKNOWN ) return monotonicity;
366 
369 
370  if( m1 == MT_CONSTANT ){
371 
372  if( m2 == MT_CONSTANT ) return MT_CONSTANT;
373 
374  double res;
375  argument1->evaluate(0,0,&res);
376 
377  if( res >= 1.0 ) return m2;
378 
379  if( m2 == MT_NONDECREASING ) return MT_NONINCREASING;
380  if( m2 == MT_NONINCREASING ) return MT_NONDECREASING;
381  }
382 
383 
384  if( m2 == MT_CONSTANT ){
385 
386  double res;
387  argument2->evaluate(0,0,&res);
388 
389  if( res >= 0.0 ) return m1;
390 
391  if( res < 0.0 ){
392 
393  if( m1 == MT_NONDECREASING ) return MT_NONINCREASING;
394  if( m1 == MT_NONINCREASING ) return MT_NONDECREASING;
395  }
396  }
397 
398  return MT_NONMONOTONIC;
399 }
400 
401 
403 
404  if( curvature != CT_UNKNOWN ) return curvature;
405 
406  const CurvatureType c1 = argument1->getCurvature();
407  const CurvatureType c2 = argument2->getCurvature();
408 
409  if( c1 == CT_CONSTANT ){
410 
411  if( c2 == CT_CONSTANT ) return CT_CONSTANT;
412  if( c2 == CT_AFFINE ) return CT_CONVEX ;
413 
414  if( c2 == CT_CONVEX ){
415 
416  double res;
417  argument1->evaluate(0,0,&res);
418 
419  if( res >= 1.0 ) return CT_CONVEX;
420  }
421  if( c2 == CT_CONCAVE ){
422 
423  double res;
424  argument1->evaluate(0,0,&res);
425 
426  if( res < 1.0 ) return CT_CONVEX;
427  }
428 
430  }
431 
432  if( c2 == CT_CONSTANT ){
433 
434  double res;
435  argument2->evaluate(0,0,&res);
436 
437  if( c1 == CT_AFFINE ){
438 
439  if( res >= 1.0 || res < 0.0 ) return CT_CONVEX ;
440  if( res < 1.0 && res >= 0.0 ) return CT_CONCAVE;
441  }
442 
443  if( c1 == CT_CONVEX ){
444 
445  if( res >= 1.0 ) return CT_CONVEX;
446  }
447 
448  if( c1 == CT_CONCAVE ){
449 
450  if( res < 0.0 ) return CT_CONVEX ;
451  if( res <= 1.0 && res >= 0.0 ) return CT_CONCAVE;
452  }
453  }
454 
456 }
457 
458 
459 returnValue Power::AD_forward( int number, double *x, double *seed,
460  double *f, double *df ){
461 
462  if( number >= bufferSize ){
463  bufferSize += number;
464  argument1_result = (double*)realloc( argument1_result,bufferSize*sizeof(double));
465  argument2_result = (double*)realloc( argument2_result,bufferSize*sizeof(double));
466  dargument1_result = (double*)realloc(dargument1_result,bufferSize*sizeof(double));
467  dargument2_result = (double*)realloc(dargument2_result,bufferSize*sizeof(double));
468  }
469 
470  argument1->AD_forward( number, x, seed, &argument1_result[number],
471  &dargument1_result[number] );
472  argument2->AD_forward( number, x, seed, &argument2_result[number],
473  &dargument2_result[number] );
474 
475  f[0] = pow(argument1_result[number],argument2_result[number]);
476  df[0] = argument2_result[number]*pow(argument1_result[number],argument2_result[number]
477  -1.0)*dargument1_result[number]
478  +f[0]*log(argument1_result[number])*dargument2_result[number];
479 
480  return SUCCESSFUL_RETURN;
481 }
482 
483 
484 returnValue Power::AD_forward( int number, double *seed, double *df ){
485 
486  argument1->AD_forward( number, seed, &dargument1_result[number] );
487  argument2->AD_forward( number, seed, &dargument2_result[number] );
488 
489  df[0] = argument2_result[number]*pow(argument1_result[number],argument2_result[number]
490  -1.0)*dargument1_result[number]
491  +pow(argument1_result[number],argument2_result[number])
492  *log(argument1_result[number])*dargument2_result[number];
493 
494  return SUCCESSFUL_RETURN;
495 }
496 
497 
498 returnValue Power::AD_backward( int number, double seed, double *df ){
499 
500  argument1->AD_backward(number, argument2_result[number]*pow(argument1_result[number],
501  argument2_result[number]-1.0)*seed, df );
502 
503  argument2->AD_backward(number, pow(argument1_result[number],argument2_result[number])
504  *log(argument1_result[number])*seed, df );
505 
506  return SUCCESSFUL_RETURN;
507 }
508 
509 
510 
511 returnValue Power::AD_forward2( int number, double *seed, double *dseed,
512  double *df, double *ddf ){
513 
514  double ddargument1_result;
515  double ddargument2_result;
516  double dargument_result1 ;
517  double dargument_result2 ;
518 
519  argument1->AD_forward2( number, seed, dseed,
520  &dargument_result1, &ddargument1_result);
521  argument2->AD_forward2( number, seed, dseed,
522  &dargument_result2, &ddargument2_result);
523 
524  const double nn1 = pow( argument1_result[number], argument2_result[number] );
525  const double nn2 = pow( argument1_result[number], argument2_result[number]-1.0 );
526  const double nn3 = log( argument1_result[number] );
527  const double nn4 = nn2*argument2_result[number];
528  const double nn5 = nn1*nn3;
529  const double nn6 = nn2*(argument2_result[number]*nn3 + 1.0);
530 
531  df[0] = nn4*dargument_result1
532  +nn5*dargument_result2;
533  ddf[0] = nn4*ddargument1_result
534  +nn5*ddargument2_result
535  +argument2_result[number]*(argument2_result[number]-1.0)
536  *pow(argument1_result[number],argument2_result[number]-2.0)
537  *dargument1_result[number]*dargument_result1
538  +nn5*nn3*dargument2_result[number]*dargument_result2
539  +nn6*dargument_result1*dargument2_result[number]
540  +nn6*dargument1_result[number]*dargument_result2;
541 
542  return SUCCESSFUL_RETURN;
543 }
544 
545 returnValue Power::AD_backward2( int number, double seed1, double seed2,
546  double *df, double *ddf ){
547 
548  const double nn1 = pow( argument1_result[number], argument2_result[number] );
549  const double nn2 = pow( argument1_result[number], argument2_result[number]-1.0 );
550  const double nn3 = log( argument1_result[number] );
551  const double nn4 = nn2*argument2_result[number];
552  const double nn5 = nn1*nn3;
553  const double nn6 = nn2*(argument2_result[number]*nn3 + 1.0);
554 
555  argument1->AD_backward2( number,
556  seed1*nn4,
557  seed2*nn4 + seed1*(
558  argument2_result[number]*(argument2_result[number]-1.0)*
559  pow( argument1_result[number],
560  argument2_result[number]-2.0 )*
561  dargument1_result[number]
562  + nn6*dargument2_result[number] ),
563  df, ddf );
564 
565  argument2->AD_backward2( number,
566  seed1*nn5,
567  seed2*nn5 + seed1*(
568  nn5*nn3*dargument2_result[number]
569  + nn6*dargument1_result[number] ),
570  df, ddf );
571 
572  return SUCCESSFUL_RETURN;
573 }
574 
575 
576 std::ostream& Power::print( std::ostream &stream ) const{
577 
578  if ( acadoIsEqual( argument2->getValue(),0.5 ) == BT_TRUE )
579  {
580  return stream << "(sqrt(" << *argument1 << "))";
581  }
582  else
583  {
584  if ( acadoIsEqual( argument2->getValue(),-0.5 ) == BT_TRUE )
585  {
586  return stream << "(1.0/sqrt(" << *argument1 << "))";
587  }
588  else
589  {
590  return stream << "(pow(" << *argument1 << "," << *argument2 << "))";
591  }
592  }
593 }
594 
595 
597 
598  return new Power(*this);
599 }
600 
601 
603 
604  return ON_POWER;
605 
606 }
607 
608 
610 
611 // end of file.
OperatorName
Definition: acado_types.hpp:72
virtual returnValue AD_backward2(int number, double seed1, double seed2, double *df, double *ddf)
Definition: power.cpp:545
Operator * dargument1
virtual returnValue AD_forward2(int number, double *seed1, double *seed2, double *df, double *ddf)=0
virtual MonotonicityType getMonotonicity()=0
Operator * dargument2
virtual BooleanType isPolynomialIn(int dim, VariableType *varType, int *component, BooleanType *implicit_dep)
Definition: power.cpp:335
virtual Operator * AD_forward(int dim, VariableType *varType, int *component, Operator **seed, int &nNewIS, TreeProjection ***newIS)
Definition: power.cpp:170
Abstract base class for all scalar-valued binary operators within the symbolic operators family...
virtual BooleanType isLinearIn(int dim, VariableType *varType, int *component, BooleanType *implicit_dep)
Definition: power.cpp:305
Abstract base class for all scalar-valued symbolic operators.
Definition: operator.hpp:60
TreeProjection * derivative02
Definition: power.hpp:335
virtual BooleanType isDependingOn(VariableType var) const =0
BooleanType acadoIsEqual(double x, double y, double TOL)
Definition: acado_utils.cpp:88
virtual NeutralElement isOneOrZero() const =0
virtual CurvatureType getCurvature()
Definition: power.cpp:402
virtual Operator * substitute(int index, const Operator *sub)
Definition: power.cpp:297
CurvatureType curvature
virtual returnValue evaluate(int number, double *x, double *result)
Definition: power.cpp:124
double * argument1_result
virtual Operator * differentiate(int index)=0
TreeProjection * derivative22
Definition: power.hpp:340
Allows to pass back messages to the calling function.
virtual void power(Operator &arg1, Operator &arg2)=0
Implements the scalar power operator within the symbolic operators family.
Definition: power.hpp:56
virtual Operator * clone() const =0
virtual MonotonicityType getMonotonicity()
Definition: power.cpp:363
IntermediateState pow(const Expression &arg1, const Expression &arg2)
virtual Operator * substitute(int index, const Operator *sub)=0
Operator * argument2
virtual double getValue() const
Definition: operator.cpp:211
virtual BooleanType isDependingOn(VariableType var) const
#define CLOSE_NAMESPACE_ACADO
TreeProjection * derivative12
Definition: power.hpp:337
VariableType
Definition: acado_types.hpp:95
BooleanType initialized
Definition: operator.hpp:642
double * dargument2_result
virtual Operator * mySubtract(Operator *a, Operator *b)
Definition: operator.cpp:263
virtual returnValue initDerivative()
Definition: power.cpp:261
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
Operator * argument1
virtual std::ostream & print(std::ostream &stream) const
Definition: power.cpp:576
TreeProjection * derivative21
Definition: power.hpp:339
virtual returnValue AD_backward2(int number, double seed1, double seed2, double *df, double *ddf)=0
virtual returnValue AD_backward(int dim, VariableType *varType, int *component, Operator *seed, Operator **df, int &nNewIS, TreeProjection ***newIS)
Definition: power.cpp:200
~Power()
Definition: power.cpp:85
MonotonicityType monotonicity
virtual OperatorName getName()
Definition: power.cpp:602
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
virtual BooleanType isRationalIn(int dim, VariableType *varType, int *component, BooleanType *implicit_dep)
Definition: power.cpp:349
double * dargument1_result
virtual returnValue initDerivative()
Definition: operator.cpp:519
virtual Operator * myAdd(Operator *a, Operator *b)
Definition: operator.cpp:246
Power()
Definition: power.cpp:45
virtual BooleanType isLinearIn(int dim, VariableType *varType, int *component, BooleanType *implicit_dep)=0
virtual returnValue evaluate(int number, double *x, double *result)=0
virtual returnValue AD_forward2(int number, double *seed1, double *seed2, double *df, double *ddf)
Definition: power.cpp:511
#define BT_TRUE
Definition: acado_types.hpp:47
virtual BooleanType isPolynomialIn(int dim, VariableType *varType, int *component, BooleanType *implicit_dep)=0
MonotonicityType
virtual Operator * myLogarithm(Operator *a)
Definition: operator.cpp:304
Implements the tree-projection operator within the family of SymbolicOperators.
virtual Operator * differentiate(int index)
Definition: power.cpp:150
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: power.cpp:232
CurvatureType
virtual TreeProjection * convert2TreeProjection(Operator *a) const
Definition: operator.cpp:312
BinaryOperator & operator=(const BinaryOperator &arg)
#define BEGIN_NAMESPACE_ACADO
TreeProjection * derivative01
Definition: power.hpp:334
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
Power & operator=(const Power &arg)
Definition: power.cpp:114
virtual TreeProjection * clone() const
TreeProjection * derivative23
Definition: power.hpp:341
virtual Operator * myPower(Operator *a, Operator *b)
Definition: operator.cpp:280
virtual Operator * clone() const
Definition: power.cpp:596
Implements a scalar constant within the symbolic operators family.
Implements the scalar product operator within the symbolic operators family.
Definition: product.hpp:55
IntermediateState log(const Expression &arg)


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