Changeset 3596


Ignore:
Timestamp:
Jan 13, 2015 8:38:51 AM (5 years ago)
Author:
bradbell
Message:

merge to branch: branches/compare_op
from repository: https://github.com/bradbell/cppad
start hash code: 6fe607ca30db07b356fd3a9fe9779fa2dfd382d8
end hash code: 9ed03e1ee2c258ca38561ad083067e235d032e14

commit 9ed03e1ee2c258ca38561ad083067e235d032e14
Author: Brad Bell <bradbell@…>
Date: Tue Jan 13 05:54:30 2015 -0700

Change test so it corresponds to optimization keeping compare operators.

commit 5c418d477d58984b094bba027ebb0794e759e557
Author: Brad Bell <bradbell@…>
Date: Tue Jan 13 05:12:50 2015 -0700

Include example and test of using CompareChange? with optimized tape.

commit c1b48edfa56ca096ce8c2db1dbadb2658cb13fe3
Author: Brad Bell <bradbell@…>
Date: Tue Jan 13 04:24:54 2015 -0700

Fix optimization so variables used in compare opertions are alwasy available.

Location:
branches/compare_op
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/compare_op/cppad/local/optimize.hpp

    r3595 r3596  
    17001700
    17011701                        // Operations where there is nothing to do
    1702                         case ComOp:
    17031702                        case EndOp:
    17041703                        case ParOp:
     
    17101709                        case InvOp:
    17111710                        tape[i_var].connect_type = yes_connected;
     1711                        break;
     1712
     1713                        // Another operator that never gets removed
     1714                        case ComOp:
     1715                        if( arg[1] & 2 )
     1716                                tape[arg[2]].connect_type = yes_connected;
     1717                        if( arg[1] & 4 )
     1718                                tape[arg[3]].connect_type = yes_connected;
    17121719                        break;
    17131720
     
    20852092                bool keep;
    20862093                switch( op )
    2087                 {       // case ComOp: (see wish_list/Optimize/CompareChange entry.
     2094                {       case ComOp: // see wish_list/Optimize/CompareChange entry.
     2095                        keep = true;
     2096                        break;
     2097
    20882098                        case PriOp:
    20892099                        keep = false;
  • branches/compare_op/example/optimize.cpp

    r2506 r3596  
    11/* $Id$ */
    22/* --------------------------------------------------------------------------
    3 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-12 Bradley M. Bell
     3CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-15 Bradley M. Bell
    44
    55CppAD is distributed under multiple licenses. This distribution is under
    6 the terms of the 
     6the terms of the
    77                    Eclipse Public License Version 1.0.
    88
     
    3131# include <cppad/cppad.hpp>
    3232namespace {
    33         template <class Float>
    34         void fun(const Float& x, Float& y, size_t& n_var, size_t& n_opt)
    35         {       using CppAD::exp;
     33        template <class VectorFloat> void fun(
     34                const VectorFloat& x, VectorFloat& y, size_t& n_var, size_t& n_opt )
     35        {       typedef typename VectorFloat::value_type Float;
    3636
    37                 // Create a variable that is optimized out because
    38                 // it is only used in the comparision operation.
    39                 Float a = 1. / x;
    40                 n_var += 1;
    41                 n_opt += 0;
     37                // One for each independent variable and one phantom variable at
     38                // the beginning of operation sequence.
     39                n_var = 1 + x.size();
    4240
    43                 // Create a variable that is used by the result
    44                 Float b = x * 5.;
     41                // One operator for each independent variable and one to mark
     42                // beginning of operation sequence.
     43                n_opt = 1 + x.size();
     44
     45                // Create a variable that is is only used in the comparision operation
     46                // (was optimized out until 2015-01-12).
     47                Float a = 1. / x[0];
    4548                n_var += 1;
    4649                n_opt += 1;
    4750
     51                // Create a variable that is used by the result
     52                Float b = x[0] * 5.;
     53                n_var += 1;
     54                n_opt += 1;
     55
     56                // only one variable created for this comparison operation
     57                // but the value depends on which branch is taken.
    4858                Float c;
    49                 if( a < x ) 
    50                         c = b / 3.; // only one variable created by this choice
    51                 else    c = b / 2.;
     59                if( a < x[0] )
     60                        c = 2.0 * b;
     61                else
     62                        c = 3.0 * b;
    5263                n_var += 1;
    5364                n_opt += 1;
     
    5566                // Create a variable that is optimized out because it
    5667                // will always have the same value as b
    57                 Float d = 5. * x;
     68                Float d = 5. * x[0];
    5869                n_var += 1;
    5970                n_opt += 0;
    6071
    6172                // Create three variables that will be converted to one
    62                 // cumulative summation. Note that a is not connected to 
     73                // cumulative summation. Note that a is not connected to
    6374                // the result y (in the operation sequence).
    64                 y      = 1. + b + c + d;
     75                y[0]   = 1.0 + b + c + d;
    6576                n_var += 3;
    6677                n_opt += 1;
     
    7485        // domain space vector
    7586        size_t n  = 1;
    76         CPPAD_TESTVECTOR(AD<double>) X(n);
    77         X[0]      = .5;
     87        CPPAD_TESTVECTOR(AD<double>) ax(n);
     88        ax[0] = 0.5;
    7889
    7990        // declare independent variables and start tape recording
    80         CppAD::Independent(X);
    81         size_t n_var = 1 + n; // one phantom variable at the beginning
    82         size_t n_opt = 1 + n; // and one for each independent variable
     91        CppAD::Independent(ax);
    8392
    84         // range space vector 
     93        // range space vector
    8594        size_t m = 1;
    86         CPPAD_TESTVECTOR(AD<double>) Y(m);
    87         fun(X[0], Y[0], n_var, n_opt);
     95        CPPAD_TESTVECTOR(AD<double>) ay(m);
     96        size_t n_var, n_opt;
     97        fun(ax, ay, n_var, n_opt);
    8898
    89         // create f: X -> Y and stop tape recording
    90         CppAD::ADFun<double> F(X, Y);
    91         ok &= (F.size_var() == n_var);
    92 
    93         // Check zero order forward mode on the original operation sequence
    94         CPPAD_TESTVECTOR(double) x(n), y(m);
    95         x[0] = Value(X[0]);
    96         size_t i = 0; // temporary variable (we do not use value)
    97         double check;
    98         fun(x[0], check, i, i);
    99         y   = F.Forward(0, x);
    100         ok &= (y[0] == check);
     99        // create f: x -> y and stop tape recording
     100        CppAD::ADFun<double> f(ax, ay);
     101        ok &= (f.size_var() == n_var);
    101102
    102103        // Optimize the operation sequence
    103         F.optimize();
    104         ok &= (F.size_var() == n_opt);
     104        f.optimize();
     105        ok &= (f.size_var() == n_opt);
    105106
    106         // Check result for a zero order calculation.
    107         // This has already been checked if NDEBUG is not defined.
    108         fun(x[0], check, i, i);
    109         ok &= (y[0] == check);
    110         y   = F.Forward(0, x);
     107        // Check result for a zero order calculation for a different x,
     108        // where the result of the comparison is he same.
     109        CPPAD_TESTVECTOR(double) x(n), y(m), check(m);
     110        x[0] = 0.75;
     111        y    = f.Forward(0, x);
     112        ok  &= f.CompareChange() == 0;
     113        fun(x, check, n_var, n_opt);
     114        ok  &= (y[0] == check[0]);
     115
     116        // Check case where result of the comparision is differnent
     117        x[0] = 2.0;
     118        y    = f.Forward(0, x);
     119        ok  &= f.CompareChange() == 1;
     120        fun(x, check, n_var, n_opt);
     121        ok &= (y[0] != check[0]);
     122
     123        // re-tape at new x value, re-optimize, and re-evaluate forward
     124        ax[0] = x[0];
     125        CppAD::Independent(ax);
     126        fun(ax, ay, n_var, n_opt);
     127        f.Dependent(ax, ay);
     128        f.optimize();
     129        y   = f.Forward(0, x);
     130        ok &= f.CompareChange() == 0;
     131        ok &= (y[0] == check[0]);
     132
    111133        return ok;
    112134}
  • branches/compare_op/omh/whats_new/whats_new_15.omh

    r3595 r3596  
    4646See the wish list
    4747$cref/optimize compare_change/WishList/Optimization/CompareChange/$$ entry.
     48$lnext
     49The $cref optimize.cpp$$ example was changed to include a demonstration
     50of how $cref CompareChange$$ can be used with an optimized tape.
    4851$lend
    4952
  • branches/compare_op/test_more/optimize.cpp

    r3507 r3596  
    11/* $Id$ */
    22/* --------------------------------------------------------------------------
    3 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-13 Bradley M. Bell
     3CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-15 Bradley M. Bell
    44
    55CppAD is distributed under multiple licenses. This distribution is under
     
    311311        (const Vector& x, Vector& y, size_t& original, size_t& opt)
    312312        {       typedef typename Vector::value_type Scalar;
    313                 Scalar a;
     313                Scalar not_used;
    314314                Scalar one(1), two(2), three(3), four(4);
    315                 original = 0;
    316                 opt      = 0;
     315
     316                // independent variable and phantom at beginning
     317                original = 1 + x.size();
     318                opt      = 1 + x.size();
    317319
    318320                // unary operator where operand is arg[0]
    319                 a = CppAD::abs(x[0]);
    320                 if( a < 1. )
    321                         y[0] = sin(x[0]);
    322                 else    y[0] = cos(x[0]);
     321                // (note that sin corresponds to two tape variables)
     322                not_used = CppAD::abs(x[0]);
     323                y[0]     = sin(x[0]);
    323324                original += 3;
    324325                opt      += 2;
     
    326327                // binary operator where left operand is a variable
    327328                // and right operand is a parameter
    328                 a = x[1] + 2.;
    329                 if( a < 3. )
    330                         y[1] = x[1] * 3.;
    331                 else    y[1] = x[1] / 2.;
     329                not_used = not_used + 2.;
     330                y[1]     = x[1] * 3.;
    332331                original += 2;
    333332                opt      += 1;
     
    335334                // binary operator where left operand is a parameter
    336335                // and right operation is a variable
    337                 a = 2. - x[2];
    338                 if( a < 4. )
    339                         y[2] = 3. / x[2];
    340                 else    y[2] = 4. + x[2];
     336                not_used = 2. - not_used;
     337                y[2]     = 3. / x[2];
    341338                original += 2;
    342339                opt      += 1;
    343340
    344341                // binary operator where both operands are variables
    345                 a = x[3] - x[2];
    346                 if( a < 4. )
    347                         y[3] = x[3] / x[2];
    348                 else    y[3] = x[3] + x[2];
     342                not_used  = x[3] - not_used;
     343                y[3]      = x[3] / x[2];
    349344                original += 2;
    350345                opt      += 1;
    351346
    352                 // this conditional expression that will be optimized out
    353                 a = CppAD::CondExpLt(x[0], x[1], x[2], x[3]);
    354                 // 1 of the following 2 conditional expressions will be kept
    355                 if( a < 5. )
    356                         y[4] = CppAD::CondExpLt(x[4], one, two, three);
    357                 else    y[4] = CppAD::CondExpLt(x[4], two, three, four);
    358                 original += 2;
     347                // conditional expression that will be optimized out
     348                not_used = CppAD::CondExpLt(x[0], x[1], x[2], x[3]) + not_used;
     349                y[4]     = CppAD::CondExpLt(x[4], one, two, three);
     350                original += 3;
    359351                opt      += 1;
    360352
    361                 // Make sure that a parameter dependent variable
     353                // y[5] does not depend on the value of not_used.
     354                // Make sure a parameter, corresponding to a dependent variable,
    362355                // is not optimized out of the operation sequence.
    363                 // In addition, we do not use the argument x[5], to
    364                 // make sure it is not optimized out.
    365                 y[5] = 1.;
     356                y[5]      = 0.0 * not_used;
    366357                original += 1;
    367358                opt      += 1;
     359
     360                // Wwe do not use the argument x[5], to
     361                // make sure it is not optimized out.
    368362
    369363                return;
     
    405399       
    406400                // Check size before optimization
    407                 ok &= F.size_var() == (n + 1 + original);
     401                ok &= F.size_var() == original;
    408402       
    409403                // Optimize the operation sequence
     
    411405       
    412406                // Check size after optimization
    413                 ok &= F.size_var() == (n + 1 + opt);
     407                ok &= F.size_var() == opt;
    414408       
    415409                // check result now
Note: See TracChangeset for help on using the changeset viewer.