Changeset 3669 for trunk/test_more


Ignore:
Timestamp:
Mar 8, 2015 1:43:45 PM (5 years ago)
Author:
bradbell
Message:

merge to branch: trunk
from repository: https://github.com/coin-or/CppAD
start hash code: 726a32637144e4cf96ba482ca9494ba991a7d91a
end hash code: 00570aaf8a29ef314e49a0485c8a0574a1652619

commit 00570aaf8a29ef314e49a0485c8a0574a1652619
Author: Brad Bell <bradbell@…>
Date: Sat Mar 7 09:35:46 2015 -0800

optimize.cpp: delete trailing white space.

commit 47b44133d7810803b3a170814dda20975564cce5
Author: Brad Bell <bradbell@…>
Date: Sat Mar 7 09:34:33 2015 -0800

  1. Do not allocate for conditional skips when not optimizing conditional skips.
  2. Extensive testing of no_conditional skip option.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/test_more/optimize.cpp

    r3642 r3669  
    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
     
    1717
    1818namespace {
     19        // include conditional skip optimization
     20        bool conditional_skip;
     21
    1922        // accuracy for almost equal checks
    2023        double eps = 10. * std::numeric_limits<double>::epsilon();
     
    3033                using CppAD::AD;
    3134                using CppAD::vector;
    32        
    33                 // independent variable vector 
     35
     36                // independent variable vector
    3437                vector< AD<double> > ax(2), ay(1);
    3538                ax[0] = 1.0;
    3639                ax[1] = 2.0;
    3740                Independent(ax);
    38        
     41
    3942                // first conditional expression
    4043                AD<double> ac1 = CondExpLe(ax[0], ax[1], 2.0 * ax[0], 3.0 * ax[1] );
    41        
     44
    4245                // second conditional expression
    4346                AD<double> ac2 = CondExpGe(ax[0], ax[1], 4.0 * ax[0], 5.0 * ax[1] );
    44        
     47
    4548                // third conditional expression
    4649                AD<double> ac3 = CondExpLt(ax[0], ax[1], 6.0 * ac1, 7.0 * ac2 );
    47        
     50
    4851                // create function object f : ax -> ay
    4952                ay[0] = ac3;
    5053                CppAD::ADFun<double> f(ax, ay);
    51        
     54
    5255                // now optimize the operation sequence
    53                 f.optimize();
    54        
     56                if( conditional_skip )
     57                        f.optimize();
     58                else
     59                        f.optimize("no_conditional_skip");
     60
    5561                // now zero order forward
    5662                vector<double> x(2), y(1);
     
    7177                                c2 = 4.0 * x[0];
    7278                        else    c2 = 5.0 * x[1];
    73        
     79
    7480                        // third conditional expression
    7581                        double c3;
     
    7783                                c3 = 6.0 * c1;
    7884                        else    c3 = 7.0 * c2;
    79        
     85
    8086                        ok &= y[0] == c3;
    8187                }
     
    8692        // the operands in the logical comparison because of the CondExp
    8793        // sparsity pattern.
    88         void j_algo( 
     94        void j_algo(
    8995                const CppAD::vector< CppAD::AD<double> >& ax ,
    9096                      CppAD::vector< CppAD::AD<double> >& ay )
    9197        {       ay[0] = CondExpGt(ax[0], ax[1], ax[2], ax[3]); }
    92        
     98
    9399        bool atomic_cond_exp_sparsity(void)
    94100        {       bool ok = true;
    95101                using CppAD::AD;
    96102                using CppAD::vector;
    97        
     103
    98104                // Create a checkpoint version of the function g
    99105                vector< AD<double> > au(4), av(1);
     
    101107                        au[i] = AD<double>(i);
    102108                CppAD::checkpoint<double> j_check("j_check", j_algo, au, av);
    103        
    104                 // independent variable vector 
     109
     110                // independent variable vector
    105111                vector< AD<double> > ax(2), ay(1);
    106112                ax[0] = 1.;
    107113                ax[1] = 1.;
    108114                Independent(ax);
    109        
     115
    110116                // call atomic function that does not get used
    111                 for(size_t i = 0; i < 4; i++) 
     117                for(size_t i = 0; i < 4; i++)
    112118                        au[i] = ax[0] + AD<double>(i + 1) * ax[1];
    113119                j_check(au, ay);
    114        
     120
    115121                // create function object f : ax -> ay
    116122                CppAD::ADFun<double> f(ax, ay);
    117123
    118        
     124
    119125                // now optimize the operation sequence
    120126                j_check.option( atomic_sparsity_option );
    121                 f.optimize();
    122        
     127                if( conditional_skip )
     128                        f.optimize();
     129                else
     130                        f.optimize("no_conditional_skip");
     131
    123132                // check result where true case is used; i.e., au[0] > au[1]
    124133                vector<double> x(2), y(1);
     
    127136                y    = f.Forward(0, x);
    128137                ok  &= y[0] == x[0] + double(3) * x[1];
    129                
    130        
     138
     139
    131140                // check result where false case is used; i.e., au[0] <= au[1]
    132141                x[0] = 1.;
     
    134143                y    = f.Forward(0, x);
    135144                ok  &= y[0] == x[0] + double(4) * x[1];
    136                
     145
    137146                return ok;
    138147        }
     
    160169                CppAD::checkpoint<double> h_check("h_check", h_algo, ax, ah);
    161170
    162                 // independent variable vector 
     171                // independent variable vector
    163172                Independent(ax);
    164173
     
    168177
    169178                // conditional expression
    170                 ay[0] = CondExpLt(ax[0], ax[1], ag[0], ah[0]); 
    171        
     179                ay[0] = CondExpLt(ax[0], ax[1], ag[0], ah[0]);
     180
    172181                // create function object f : ax -> ay
    173182                CppAD::ADFun<double> f;
    174183                f.Dependent(ax, ay);
    175        
     184
    176185                // use zero order to evaluate when condition is true
    177186                CppAD::vector<double>  x(2), dx(2);
     
    188197
    189198                // now optimize the operation sequence
    190                 f.optimize();
     199                if( conditional_skip )
     200                        f.optimize();
     201                else
     202                        f.optimize("no_conditional_skip");
    191203
    192204                // optimized zero order forward when condition is false
     
    210222                ok   &= dx[0] == 1.;
    211223                ok   &= dx[1] == -1.;
    212        
     224
    213225                return ok;
    214226        }
    215227        // -------------------------------------------------------------------
    216228        // Test of optimizing out arguments to an atomic function
    217         void g_algo( 
     229        void g_algo(
    218230                const CppAD::vector< CppAD::AD<double> >& ax ,
    219231                      CppAD::vector< CppAD::AD<double> >& ay )
     
    224236                using CppAD::AD;
    225237                using CppAD::vector;
    226        
     238
    227239                // Create a checkpoint version of the function g
    228240                vector< AD<double> > ax(2), ay(2), az(1);
     
    230242                ax[1] = 1.;
    231243                CppAD::checkpoint<double> g_check("g_check", g_algo, ax, ay);
    232        
    233                 // independent variable vector 
     244
     245                // independent variable vector
    234246                Independent(ax);
    235        
     247
    236248                // call atomic function that does not get used
    237249                g_check(ax, ay);
    238        
     250
    239251                // conditional expression
    240                 az[0] = CondExpLt(ax[0], ax[1], ax[0] + ax[1], ax[0] - ax[1]); 
    241                
     252                az[0] = CondExpLt(ax[0], ax[1], ax[0] + ax[1], ax[0] - ax[1]);
     253
    242254                // create function object f : ax -> az
    243255                CppAD::ADFun<double> f(ax, az);
     
    246258                // (include ay[0] and ay[1])
    247259                size_t n_before = f.size_var();
    248                
     260
    249261                // now optimize the operation sequence
    250262                g_check.option( atomic_sparsity_option );
    251                 f.optimize();
    252 
    253                 // number of variables after optimization
     263                if( conditional_skip )
     264                        f.optimize();
     265                else
     266                        f.optimize("no_conditional_skip");
     267
     268                // number of variables after optimization
    254269                // (does not include ay[0] and ay[1])
    255270                size_t n_after = f.size_var();
    256271                ok            &= n_after + 2 == n_before;
    257        
     272
    258273                // check optimization works ok
    259274                vector<double> x(2), z(1);
     
    262277                z    = f.Forward(0, x);
    263278                ok  &= z[0] == x[0] - x[1];
    264                
     279
    265280                return ok;
    266281        }
     
    284299                g_check(au, aw);
    285300
    286                 // now create f(x) = x_0 - x_1 
     301                // now create f(x) = x_0 - x_1
    287302                ay[0] = aw[0];
    288303                CppAD::ADFun<double> f(ax, ay);
     
    290305                // number of variables before optimization
    291306                size_t n_before = f.size_var();
    292  
     307
    293308                // now optimize f so that the calculation of au[1] is removed
    294309                g_check.option( atomic_sparsity_option );
    295                 f.optimize();
     310                if( conditional_skip )
     311                        f.optimize();
     312                else
     313                        f.optimize("no_conditional_skip");
    296314
    297315                // check difference in number of variables
     
    304322                x[1] = 6.0;
    305323                y    = f.Forward(0, x);
    306                 ok  &= (y[0] == x[0] + x[1]); 
     324                ok  &= (y[0] == x[0] + x[1]);
    307325
    308326                return ok;
     
    324342                // unary operator where operand is arg[0]
    325343                // (note that sin corresponds to two tape variables)
    326                 not_used = CppAD::abs(x[0]); 
     344                not_used = CppAD::abs(x[0]);
    327345                y[0]     = sin(x[0]);
    328346                original += 3;
     
    375393                size_t opt;
    376394                size_t i, j;
    377        
     395
    378396                // domain space vector
    379397                size_t n  = 6;
    380398                CppAD::vector< AD<double> > X(n);
    381399                for(j = 0; j < n; j++)
    382                         X[j] = 1. / double(j + 1); 
    383        
     400                        X[j] = 1. / double(j + 1);
     401
    384402                // declare independent variables and start tape recording
    385403                CppAD::Independent(X);
    386        
    387                 // range space vector 
     404
     405                // range space vector
    388406                size_t m = n;
    389407                CppAD::vector< AD<double> > Y(m);
    390408                depend_fun(X, Y, original, opt);
    391        
     409
    392410                // create f: X -> Y and stop tape recording
    393411                CppAD::ADFun<double> F;
    394                 F.Dependent(X, Y); 
    395        
     412                F.Dependent(X, Y);
     413
    396414                CppAD::vector<double> x(n), y(m), check(m);
    397415                for(j = 0; j < n; j++)
     
    401419                for(i = 0; i < m; i++)
    402420                        ok &= NearEqual(y[i], check[i], eps, eps);
    403        
     421
    404422                // Check size before optimization
    405423                ok &= F.size_var() == original;
    406        
     424
    407425                // Optimize the operation sequence
    408                 F.optimize();
    409        
     426                if( conditional_skip )
     427                        F.optimize();
     428                else
     429                        F.optimize("no_conditional_skip");
     430
    410431                // Check size after optimization
    411432                ok &= F.size_var() == opt;
    412        
     433
    413434                // check result now
    414435                // (should have already been checked if NDEBUG not defined)
     
    416437                for(i = 0; i < m; i++)
    417438                        ok &= NearEqual(y[i], check[i], eps, eps);
    418        
     439
    419440                return ok;
    420441        }
     
    430451                CppAD::vector< AD<double> > X(n);
    431452                for(j = 0; j < n; j++)
    432                         X[j] = double(j); 
     453                        X[j] = double(j);
    433454
    434455                // range space vector
     
    442463                for(j = 0; j < n; j++)
    443464                        V[j] = 0;
    444        
     465
    445466                // declare independent variables and start tape recording
    446467                CppAD::Independent(X);
     
    461482                        Y[i] = U[I];
    462483                }
    463        
     484
    464485                // create f: X -> Y and stop tape recording
    465                 // Y[ X[0] ] = X[1] and other components of Y are zero. 
     486                // Y[ X[0] ] = X[1] and other components of Y are zero.
    466487                CppAD::ADFun<double> F;
    467                 F.Dependent(X, Y); 
     488                F.Dependent(X, Y);
    468489
    469490                // Check number of VecAD vectors plus number of VecAD elements
    470                 ok &= (F.size_VecAD() == 2 + n + m); 
    471        
     491                ok &= (F.size_VecAD() == 2 + n + m);
     492
    472493                CppAD::vector<double> x(n), y(m);
    473494                for(j = 0; j < n; j++)
     
    481502                }
    482503
    483                 F.optimize();
     504                if( conditional_skip )
     505                        F.optimize();
     506                else
     507                        F.optimize("no_conditional_skip");
    484508
    485509                // Check number of VecAD vectors plus number of VecAD elements
    486                 ok &= (F.size_VecAD() == 1 + m); 
     510                ok &= (F.size_VecAD() == 1 + m);
    487511                y = F.Forward(0, x);
    488512                for(i = 0; i < m; i++)
     
    491515                        else    ok &= (y[i] == x[1]);
    492516                }
    493                
     517
    494518                return ok;
    495519        }
     
    502526                size_t n = 3;
    503527                size_t j;
    504        
     528
    505529                vector< AD<double> >    X(n), Y(n);
    506                 vector<double>          x(n), y(n); 
    507        
     530                vector<double>          x(n), y(n);
     531
    508532                for(j = 0; j < n; j++)
    509533                        X[j] = x[j] = double(j+2);
    510        
     534
    511535                CppAD::Independent(X);
    512                        
     536
    513537                Y[0] = pow(X[0], 2.0);
    514538                Y[1] = pow(2.0, X[1]);
    515539                Y[2] = pow(X[0], X[1]);
    516        
     540
    517541                CppAD::ADFun<double> F(X, Y);
    518                 F.optimize();
     542                if( conditional_skip )
     543                        F.optimize();
     544                else
     545                        F.optimize("no_conditional_skip");
    519546                y = F.Forward(0, x);
    520547
     
    526553
    527554                // check reverse mode derivative
    528                 vector<double>   w(n), dw(n); 
     555                vector<double>   w(n), dw(n);
    529556                w[0] = 0.;
    530557                w[1] = 0.;
     
    540567                check = 0.;
    541568                ok &= NearEqual( dw[2], check, eps, eps );
    542        
     569
    543570                return ok;
    544571        }
     
    564591                vector<double> y_original     = F.Forward(0, x);
    565592                size_t         size_original  = F.size_var();
    566                 F.optimize();
     593                if( conditional_skip )
     594                        F.optimize();
     595                else
     596                        F.optimize("no_conditional_skip");
    567597                ok &= F.size_var() + 5 == size_original;
    568598                vector<double> y = F.Forward(0, x);
     
    582612
    583613                // unary operator where operand is arg[0] and one result
    584                 Scalar a1 = CppAD::exp(x[0]); 
     614                Scalar a1 = CppAD::exp(x[0]);
    585615                original += 1;
    586616                opt      += 1;
     
    651681                size_t opt;
    652682                size_t i, j;
    653        
     683
    654684                // domain space vector
    655685                size_t n  = 7;
    656686                CppAD::vector< AD<double> > X(n);
    657687                for(j = 0; j < n; j++)
    658                         X[j] = 1. / double(j + 1); 
    659        
     688                        X[j] = 1. / double(j + 1);
     689
    660690                // declare independent variables and start tape recording
    661691                CppAD::Independent(X);
    662        
    663                 // range space vector 
     692
     693                // range space vector
    664694                size_t m = n;
    665695                CppAD::vector< AD<double> > Y(m);
    666696                duplicate_fun(X, Y, original, opt);
    667        
     697
    668698                // create f: X -> Y and stop tape recording
    669699                CppAD::ADFun<double> F;
    670                 F.Dependent(X, Y); 
    671        
     700                F.Dependent(X, Y);
     701
    672702                CppAD::vector<double> x(n), y(m), check(m);
    673703                for(j = 0; j < n; j++)
     
    677707                for(i = 0; i < m; i++)
    678708                        ok &= NearEqual(y[i], check[i], eps, eps);
    679        
     709
    680710                // Check size before optimization
    681711                ok &= F.size_var() == (n + 1 + original);
    682        
     712
    683713                // Optimize the operation sequence
    684                 F.optimize();
    685        
     714                if( conditional_skip )
     715                        F.optimize();
     716                else
     717                        F.optimize("no_conditional_skip");
     718
    686719                // Check size after optimization
    687720                ok &= F.size_var() == (n + 1 + opt);
    688        
     721
    689722                // check result now
    690723                // (should have already been checked if NDEBUG not defined)
     
    692725                for(i = 0; i < m; i++)
    693726                        ok &= NearEqual(y[i], check[i], eps, eps);
    694        
     727
    695728                return ok;
    696729        }
     
    707740                CppAD::vector< AD<double> > X(n);
    708741                for(j = 0; j < n; j++)
    709                         X[j] = double(j + 2); 
     742                        X[j] = double(j + 2);
    710743
    711744                // range space vector
     
    727760                // create a duplicate that can only be dectected using new
    728761                // argument indices
    729                 AD<double> B2 = A2 / 2.; 
    730 
    731                 // Make a new variable for result 
     762                AD<double> B2 = A2 / 2.;
     763
     764                // Make a new variable for result
    732765                // and make it depend on all the variables
    733766                Y[0] = B1 + B2;
     
    735768                // create f: X -> Y and stop tape recording
    736769                CppAD::ADFun<double> F;
    737                 F.Dependent(X, Y); 
     770                F.Dependent(X, Y);
    738771
    739772                // check number of variables in original function
    740                 ok &= (F.size_var() ==  1 + n + m + 4 ); 
    741        
     773                ok &= (F.size_var() ==  1 + n + m + 4 );
     774
    742775                CppAD::vector<double> x(n), y(m);
    743776                for(j = 0; j < n; j++)
     
    748781                        ok &= ( y[i] == Value( Y[i] ) );
    749782
    750                 F.optimize();
     783                if( conditional_skip )
     784                        F.optimize();
     785                else
     786                        F.optimize("no_conditional_skip");
    751787
    752788                // check number of variables  in optimized version
    753                 ok &= (F.size_var() == 1 + n + m + 2 ); 
     789                ok &= (F.size_var() == 1 + n + m + 2 );
    754790
    755791                y   = F.Forward(0, x);
     
    771807                CppAD::vector< AD<double> > X(n);
    772808                for(j = 0; j < n; j++)
    773                         X[j] = double(j + 2); 
     809                        X[j] = double(j + 2);
    774810
    775811                // range space vector
     
    791827                // create a duplicate that can only be dectected using new
    792828                // argument indices
    793                 AD<double> B2 = 2. * A2; 
    794 
    795                 // Make a new variable for result 
     829                AD<double> B2 = 2. * A2;
     830
     831                // Make a new variable for result
    796832                // and make it depend on all the variables
    797833                Y[0] = B1 + B2;
     
    799835                // create f: X -> Y and stop tape recording
    800836                CppAD::ADFun<double> F;
    801                 F.Dependent(X, Y); 
     837                F.Dependent(X, Y);
    802838
    803839                // check number of variables in original function
    804                 ok &= (F.size_var() ==  1 + n + m + 4 ); 
    805        
     840                ok &= (F.size_var() ==  1 + n + m + 4 );
     841
    806842                CppAD::vector<double> x(n), y(m);
    807843                for(j = 0; j < n; j++)
     
    812848                        ok &= ( y[i] == Value( Y[i] ) );
    813849
    814                 F.optimize();
     850                if( conditional_skip )
     851                        F.optimize();
     852                else
     853                        F.optimize("no_conditional_skip");
    815854
    816855                // check number of variables  in optimized version
    817                 ok &= (F.size_var() == 1 + n + m + 2 ); 
     856                ok &= (F.size_var() == 1 + n + m + 2 );
    818857
    819858                y   = F.Forward(0, x);
     
    843882                CppAD::Independent(X);
    844883
    845                 // check a huge number of same operation with different operands 
     884                // check a huge number of same operation with different operands
    846885                size_t n_operations = std::min(
    847886                        size_t(CPPAD_HASH_TABLE_SIZE) + 5,
     
    854893                // create f: X -> Y and stop tape recording
    855894                CppAD::ADFun<double> F;
    856                 F.Dependent(X, Y); 
     895                F.Dependent(X, Y);
    857896
    858897                // check number of variables in original function
    859                 ok &= (F.size_var() ==  1 + n + n_operations ); 
    860        
     898                ok &= (F.size_var() ==  1 + n + n_operations );
     899
    861900                CppAD::vector<double> x(n), y(m);
    862901                x[0] = 1.;
     
    865904                ok &= ( y[0] == Value( Y[0] ) );
    866905
    867                 F.optimize();
     906                if( conditional_skip )
     907                        F.optimize();
     908                else
     909                        F.optimize("no_conditional_skip");
    868910
    869911                // check same number of variables in optimized version
    870                 ok &= (F.size_var() == 1 + n + n_operations ); 
     912                ok &= (F.size_var() == 1 + n + n_operations );
    871913
    872914                y   = F.Forward(0, x);
     
    887929                CppAD::vector< AD<double> > X(n);
    888930                for(j = 0; j < n; j++)
    889                         X[j] = double(j + 2); 
     931                        X[j] = double(j + 2);
    890932
    891933                size_t n_original = 1 + n;
     
    915957
    916958                CppAD::ADFun<double> F;
    917                 F.Dependent(X, Y); 
     959                F.Dependent(X, Y);
    918960
    919961                // check number of variables in original function
    920                 ok &= (F.size_var() ==  n_original ); 
    921        
     962                ok &= (F.size_var() ==  n_original );
     963
    922964                CppAD::vector<double> x(n), y(m);
    923965                for(j = 0; j < n; j++)
     
    928970                        ok &= ( y[i] == Value( Y[i] ) );
    929971
    930                 F.optimize();
     972                if( conditional_skip )
     973                        F.optimize();
     974                else
     975                        F.optimize("no_conditional_skip");
    931976
    932977                // check number of variables  in optimized version
    933                 ok &= (F.size_var() == n_optimize ); 
     978                ok &= (F.size_var() == n_optimize );
    934979
    935980                y   = F.Forward(0, x);
     
    942987        bool forward_csum(void)
    943988        {       bool ok = true;
    944        
     989
    945990                using namespace CppAD;
    946        
    947                 // independent variable vector 
     991
     992                // independent variable vector
    948993                CppAD::vector< AD<double> > X(2);
    949                 X[0] = 0.; 
     994                X[0] = 0.;
    950995                X[1] = 1.;
    951996                Independent(X);
    952        
     997
    953998                // compute sum of elements in X
    954999                CppAD::vector< AD<double> > Y(1);
    9551000                Y[0] = X[0] + X[0] + X[1];
    956        
     1001
    9571002                // create function object F : X -> Y
    9581003                ADFun<double> F(X, Y);
    959        
     1004
    9601005                // now optimize the operation sequence
    961                 F.optimize();
    962        
    963                 // use zero order to evaluate F[ (3, 4) ]
     1006                if( conditional_skip )
     1007                        F.optimize();
     1008                else
     1009                        F.optimize("no_conditional_skip");
     1010
     1011                // use zero order to evaluate F[ (3, 4) ]
    9641012                CppAD::vector<double>  x0( F.Domain() );
    9651013                CppAD::vector<double>  y0( F.Range() );
     
    9681016                y0       = F.Forward(0, x0);
    9691017                ok      &= NearEqual(y0[0] , x0[0]+x0[0]+x0[1], eps, eps);
    970        
     1018
    9711019                // evaluate derivative of F in X[0] direction
    9721020                CppAD::vector<double> x1( F.Domain() );
     
    9761024                y1       = F.Forward(1, x1);
    9771025                ok      &= NearEqual(y1[0] , x1[0]+x1[0]+x1[1], eps, eps);
    978        
     1026
    9791027                // evaluate second derivative of F in X[0] direction
    9801028                CppAD::vector<double> x2( F.Domain() );
     
    9851033                double F_00 = 2. * y2[0];
    9861034                ok         &= NearEqual(F_00, 0., eps, eps);
    987        
     1035
    9881036                return ok;
    9891037        }
     
    9911039        bool reverse_csum(void)
    9921040        {       bool ok = true;
    993        
     1041
    9941042                using namespace CppAD;
    995        
    996                 // independent variable vector 
     1043
     1044                // independent variable vector
    9971045                CppAD::vector< AD<double> > X(2);
    998                 X[0] = 0.; 
     1046                X[0] = 0.;
    9991047                X[1] = 1.;
    10001048                Independent(X);
    1001        
     1049
    10021050                // compute sum of elements in X
    10031051                CppAD::vector< AD<double> > Y(1);
    10041052                Y[0] = X[0] - (X[0] - X[1]);
    1005        
     1053
    10061054                // create function object F : X -> Y
    10071055                ADFun<double> F(X, Y);
    1008        
     1056
    10091057                // now optimize the operation sequence
    1010                 F.optimize();
    1011        
    1012                 // use zero order to evaluate F[ (3, 4) ]
     1058                if( conditional_skip )
     1059                        F.optimize();
     1060                else
     1061                        F.optimize("no_conditional_skip");
     1062
     1063                // use zero order to evaluate F[ (3, 4) ]
    10131064                CppAD::vector<double>  x0( F.Domain() );
    10141065                CppAD::vector<double>  y0( F.Range() );
     
    10171068                y0       = F.Forward(0, x0);
    10181069                ok      &= NearEqual(y0[0] , x0[0]-x0[0]+x0[1], eps, eps);
    1019        
    1020                 // evaluate derivative of F 
     1070
     1071                // evaluate derivative of F
    10211072                CppAD::vector<double> dF( F.Domain() );
    10221073                CppAD::vector<double> w( F.Range() );
     
    10251076                ok     &= NearEqual(dF[0] , 0., eps, eps);
    10261077                ok     &= NearEqual(dF[1] , 1., eps, eps);
    1027        
     1078
    10281079                return ok;
    10291080        }
     
    10311082        {       bool ok = true;
    10321083                using namespace CppAD;
    1033        
     1084
    10341085                // dimension of the domain space
    1035                 size_t n = 3; 
    1036        
     1086                size_t n = 3;
     1087
    10371088                // dimension of the range space
    10381089                size_t m = 3;
    1039        
    1040                 // independent variable vector 
     1090
     1091                // independent variable vector
    10411092                CppAD::vector< AD<double> > X(n);
    1042                 X[0] = 2.; 
     1093                X[0] = 2.;
    10431094                X[1] = 3.;
    10441095                X[2] = 4.;
    10451096                Independent(X);
    1046        
     1097
    10471098                // dependent variable vector
    10481099                CppAD::vector< AD<double> > Y(m);
    1049        
     1100
    10501101                // check results vector
    10511102                CppAD::vector< bool >       Check(m * n);
    1052        
     1103
    10531104                // initialize index into Y
    10541105                size_t index = 0;
    1055        
    1056                 // Y[0] 
     1106
     1107                // Y[0]
    10571108                Y[index]             = X[0] + X[1] + 5.;
    10581109                Check[index * n + 0] = true;
     
    10601111                Check[index * n + 2] = false;
    10611112                index++;
    1062        
    1063                 // Y[1] 
     1113
     1114                // Y[1]
    10641115                Y[index]             = Y[0] - (X[1] + X[2]);
    10651116                Check[index * n + 0] = true;
     
    10681119                index++;
    10691120
    1070                 // Y[2] 
     1121                // Y[2]
    10711122                // 2DO: There is a subtitle issue that has to do with using reverse
    10721123                // jacobian sparsity patterns during the optimization process.
     
    10781129                Check[index * n + 2] = true;
    10791130                index++;
    1080        
     1131
    10811132                // check final index
    10821133                assert( index == m );
    1083        
     1134
    10841135                // create function object F : X -> Y
    10851136                ADFun<double> F(X, Y);
    1086                 F.optimize();
    1087        
     1137                if( conditional_skip )
     1138                        F.optimize();
     1139                else
     1140                        F.optimize("no_conditional_skip");
     1141
    10881142                // ---------------------------------------------------------
    1089                 // dependency matrix for the identity function 
     1143                // dependency matrix for the identity function
    10901144                CppAD::vector< std::set<size_t> > Sx(n);
    10911145                size_t i, j;
     
    10941148                        Sx[i].insert(i);
    10951149                }
    1096        
     1150
    10971151                // evaluate the dependency matrix for F(x)
    10981152                CppAD::vector< std::set<size_t> > Sy(m);
    10991153                Sy = F.ForSparseJac(n, Sx);
    1100        
     1154
    11011155                // check values
    11021156                bool found;
     
    11061160                                ok &= (found == Check[i * n + j]);
    11071161                        }
    1108                 }       
    1109        
     1162                }
     1163
    11101164                return ok;
    11111165        }
     
    11131167        {       bool ok = true;
    11141168                using namespace CppAD;
    1115        
     1169
    11161170                // dimension of the domain space
    1117                 size_t n = 3; 
    1118        
     1171                size_t n = 3;
     1172
    11191173                // dimension of the range space
    11201174                size_t m = 3;
    1121        
    1122                 // independent variable vector 
     1175
     1176                // independent variable vector
    11231177                CppAD::vector< AD<double> > X(n);
    1124                 X[0] = 2.; 
     1178                X[0] = 2.;
    11251179                X[1] = 3.;
    11261180                X[2] = 4.;
    11271181                Independent(X);
    1128        
     1182
    11291183                // dependent variable vector
    11301184                CppAD::vector< AD<double> > Y(m);
    1131        
     1185
    11321186                // check results vector
    11331187                CppAD::vector< bool >       Check(m * n);
    1134        
     1188
    11351189                // initialize index into Y
    11361190                size_t index = 0;
    1137        
    1138                 // Y[0] 
     1191
     1192                // Y[0]
    11391193                Y[index]             = X[0] + X[1] + 5.;
    11401194                Check[index * n + 0] = true;
     
    11421196                Check[index * n + 2] = false;
    11431197                index++;
    1144        
    1145                 // Y[1] 
     1198
     1199                // Y[1]
    11461200                Y[index]             = Y[0] - (X[1] + X[2]);
    11471201                Check[index * n + 0] = true;
     
    11501204                index++;
    11511205
    1152                 // Y[2] 
     1206                // Y[2]
    11531207                Y[index]             = CondExpLe(X[0], X[1], X[1]+X[1], X[2]-X[2]);
    11541208                Check[index * n + 0] = false;
     
    11561210                Check[index * n + 2] = true;
    11571211                index++;
    1158        
     1212
    11591213                // check final index
    11601214                assert( index == m );
    1161        
     1215
    11621216                // create function object F : X -> Y
    11631217                ADFun<double> F(X, Y);
    1164                 F.optimize();
    1165        
     1218                if( conditional_skip )
     1219                        F.optimize();
     1220                else
     1221                        F.optimize("no_conditional_skip");
     1222
    11661223                // ----------------------------------------------------------
    11671224                // dependency matrix for the identity function
     
    11721229                                Py[ i * m + j ] = (i == j);
    11731230                }
    1174        
     1231
    11751232                // evaluate the dependency matrix for F(x)
    11761233                CppAD::vector< bool > Px(m * n);
    11771234                Px = F.RevSparseJac(m, Py);
    1178        
     1235
    11791236                // check values
    11801237                for(i = 0; i < m; i++)
    11811238                {       for(j = 0; j < n; j++)
    11821239                                ok &= (Px[i * n + j] == Check[i * n + j]);
    1183                 }       
    1184        
     1240                }
     1241
    11851242                return ok;
    11861243        }
     
    11891246                using CppAD::AD;
    11901247                size_t i, j;
    1191        
     1248
    11921249                size_t n = 3;
    1193                 CppAD::vector< AD<double> > X(n); 
     1250                CppAD::vector< AD<double> > X(n);
    11941251                X[0] = 1.;
    11951252                X[1] = 2.;
    11961253                X[2] = 3.;
    11971254                CppAD::Independent(X);
    1198        
     1255
    11991256                size_t m = 1;
    12001257                CppAD::vector< AD<double> > Y(m);
    1201                 Y[0] = CondExpGe( X[0], X[1], 
    1202                         X[0] + (2. + X[1] + 3.) * X[1], 
     1258                Y[0] = CondExpGe( X[0], X[1],
     1259                        X[0] + (2. + X[1] + 3.) * X[1],
    12031260                        X[0] + (2. + X[2] + 3.) * X[1]
    12041261                );
    1205        
     1262
    12061263                CppAD::vector<bool> check(n * n);
    12071264                check[0 * n + 0] = false; // partial w.r.t. x[0], x[0]
     
    12161273                check[2 * n + 1] = true;  //                x[2], x[1]
    12171274                check[2 * n + 2] = false; //                x[2], x[2]
    1218        
     1275
    12191276                // create function object F : X -> Y
    12201277                CppAD::ADFun<double> F(X, Y);
    1221                 F.optimize();
    1222        
     1278                if( conditional_skip )
     1279                        F.optimize();
     1280                else
     1281                        F.optimize("no_conditional_skip");
     1282
    12231283                // sparsity pattern for the identity function U(x) = x
    12241284                CppAD::vector<bool> Px(n * n);
     
    12261286                        for(j = 0; j < n; j++)
    12271287                                Px[ i * n + j ] = (i == j);
    1228        
     1288
    12291289                // compute sparsity pattern for Jacobian of F(U(x))
    12301290                CppAD::vector<bool> P_jac(m * n);
    12311291                P_jac = F.ForSparseJac(n, Px);
    1232        
    1233                 // compute sparsity pattern for Hessian of F_k ( U(x) ) 
     1292
     1293                // compute sparsity pattern for Hessian of F_k ( U(x) )
    12341294                CppAD::vector<bool> Py(m);
    12351295                CppAD::vector<bool> Pxx(n * n);
     
    12391299                for(i = 0; i < n * n; i++)
    12401300                        ok &= (Pxx[i] == check[i]);
    1241        
     1301
    12421302                return ok;
    12431303        }
     
    12481308
    12491309                AD<double> zero(0.), one(1.), two(2.), three(3.);
    1250        
     1310
    12511311                size_t n = 4;
    1252                 CppAD::vector< AD<double> > X(n); 
     1312                CppAD::vector< AD<double> > X(n);
    12531313                X[0] = zero;
    12541314                X[1] = one;
     
    12561316                X[3] = three;
    12571317                CppAD::Independent(X);
    1258        
     1318
    12591319                size_t m = 4;
    12601320                CppAD::vector< AD<double> > Y(m);
     
    12651325
    12661326                CppAD::ADFun<double> f(X, Y);
    1267                 f.optimize();
     1327                if( conditional_skip )
     1328                        f.optimize();
     1329                else
     1330                        f.optimize("no_conditional_skip");
    12681331
    12691332                CppAD::vector<double> x(n), y(m);
     
    12841347                return ok;
    12851348        }
    1286         // check that CondExp properly handels expressions that get 
     1349        // check that CondExp properly handels expressions that get
    12871350        // removed during opitmization
    12881351        bool cond_exp_removed(void)
     
    12901353                using CppAD::AD;
    12911354                AD<double> zero(0.);
    1292        
     1355
    12931356                size_t n = 1;
    1294                 CppAD::vector< AD<double> > X(n); 
     1357                CppAD::vector< AD<double> > X(n);
    12951358                X[0] = 1.0;
    12961359                CppAD::Independent(X);
    1297        
     1360
    12981361                size_t m = 1;
    12991362                CppAD::vector< AD<double> > Y(m);
     
    13041367
    13051368                CppAD::ADFun<double> f(X, Y);
    1306                 f.optimize();
     1369                if( conditional_skip )
     1370                        f.optimize();
     1371                else
     1372                        f.optimize("no_conditional_skip");
    13071373
    13081374                CppAD::vector<double> x(n), y(m), w(m), dw(n);
     
    13361402        bool old_atomic_forward(
    13371403                size_t                         id ,
    1338                 size_t                          k , 
     1404                size_t                          k ,
    13391405                size_t                          n ,
    13401406                size_t                          m ,
    13411407                const CppAD::vector<bool>&     vx ,
    13421408                CppAD::vector<bool>&           vy ,
    1343                 const CppAD::vector<double>&   tx , 
     1409                const CppAD::vector<double>&   tx ,
    13441410                CppAD::vector<double>&         ty )
    13451411        {       assert(n == 3 && m == 2);
    1346                 if( k > 0 ) 
     1412                if( k > 0 )
    13471413                        return false;
    13481414
     
    13521418                // y[1] = x[1] + x[2]
    13531419                ty[1] = tx[1] + tx[2];
    1354                
     1420
    13551421                if( vy.size() > 0 )
    13561422                {       vy[0] = (vx[0] | vx[1]);
    13571423                        vy[1] = (vx[1] | vx[2]);
    13581424                }
    1359                 return true; 
     1425                return true;
    13601426        }
    13611427
    13621428        bool old_atomic_reverse(
    13631429                size_t                         id ,
    1364                 size_t                          k , 
    1365                 size_t                          n , 
    1366                 size_t                          m , 
    1367                 const CppAD::vector<double>&   tx , 
     1430                size_t                          k ,
     1431                size_t                          n ,
     1432                size_t                          m ,
     1433                const CppAD::vector<double>&   tx ,
    13681434                const CppAD::vector<double>&   ty ,
    13691435                CppAD::vector<double>&         px ,
     
    13981464                my_union(r[2], r[2], s[1]);
    13991465
    1400                 return true; 
     1466                return true;
    14011467        }
    14021468
     
    14211487                old_atomic_for_jac_sparse ,
    14221488                old_atomic_rev_jac_sparse ,
    1423                 old_atomic_rev_hes_sparse 
     1489                old_atomic_rev_hes_sparse
    14241490        )
    14251491
     
    14721538                        ax[j] = 1. / 3.;
    14731539                CppAD::Independent(ax);
    1474        
     1540
    14751541                // dependent variable vector
    14761542                size_t m = 1;
     
    14831549                }
    14841550                CppAD::ADFun<double> f(ax, ay);
    1485        
     1551
    14861552                // Used to fail assert in optimize that forward mode results
    14871553                // are identically equal
    1488                 f.optimize();
    1489        
     1554                if( conditional_skip )
     1555                        f.optimize();
     1556                else
     1557                        f.optimize("no_conditional_skip");
     1558
    14901559                return ok;
    14911560        }
     
    14971566        {       bool ok = true;
    14981567                using CppAD::vector;
    1499        
     1568
    15001569                vector< CppAD::AD<double> > ax(1), ay(1);
    1501                 ax[0] = 0.0; 
     1570                ax[0] = 0.0;
    15021571                CppAD::Independent(ax);
    1503                 ay[0] =  floor(ax[0]) + floor(ax[0]); 
     1572                ay[0] =  floor(ax[0]) + floor(ax[0]);
    15041573                CppAD::ADFun<double> f(ax, ay);
    1505        
     1574
    15061575                size_t size_before = f.size_var();
    1507                 f.optimize();
     1576                if( conditional_skip )
     1577                        f.optimize();
     1578                else
     1579                        f.optimize("no_conditional_skip");
    15081580                size_t size_after = f.size_var();
    15091581                ok &= size_after + 1 == size_before;
    1510        
     1582
    15111583                vector<double> x(1), y(1);
    15121584                x[0] = -2.2;
    15131585                y    = f.Forward(0, x);
    15141586                ok &= y[0] == -6.0;
    1515        
     1587
    15161588                return ok;
    15171589        }
    15181590        // ----------------------------------------------------------------
    1519         void i_algo( 
     1591        void i_algo(
    15201592                const CppAD::vector< CppAD::AD<double> >& ax ,
    15211593                      CppAD::vector< CppAD::AD<double> >& ay )
     
    15271599                using CppAD::AD;
    15281600                using CppAD::vector;
    1529        
     1601
    15301602                // Create a checkpoint version of the function i_algo
    15311603                vector< AD<double> > au(1), av(1), aw(1);
    15321604                au[0] = 1.0;
    15331605                CppAD::checkpoint<double> i_check("i_check", i_algo, au, av);
    1534        
    1535                 // independent variable vector 
     1606
     1607                // independent variable vector
    15361608                vector< AD<double> > ax(2), ay(1);
    15371609                ax[0] = 1.0;
    15381610                ax[1] = 2.0;
    15391611                Independent(ax);
    1540        
     1612
    15411613                // call atomic function that does not get used
    15421614                au[0] = ax[0];
     
    15561628                x[1]      = 2.0;
    15571629                y_before  = f.Forward(0, x);
    1558                 f.optimize();
     1630                if( conditional_skip )
     1631                        f.optimize();
     1632                else
     1633                        f.optimize("no_conditional_skip");
    15591634                y_after   = f.Forward(0, x);
    1560        
     1635
    15611636                ok &= y_before[0] == y_after[0];
    1562                
     1637
    15631638                return ok;
    15641639        }
     
    15701645                using CppAD::AD;
    15711646                using CppAD::vector;
    1572        
     1647
    15731648                // Create a checkpoint version of the function i_algo
    15741649                vector< AD<double> > au(1), av(1), aw(1);
    15751650                au[0] = 1.0;
    15761651                CppAD::checkpoint<double> i_check("i_check", i_algo, au, av);
    1577        
     1652
    15781653                vector< AD<double> > ax(2), ay(1);
    1579                 AD<double> zero = 0.0; 
     1654                AD<double> zero = 0.0;
    15801655                ax[0] = 1.0;
    15811656                ax[1] = 1.0;
     
    15971672                dx[1]     = 2.0;
    15981673                dy_before = f.Forward(1, dx);
    1599                 f.optimize();
     1674                if( conditional_skip )
     1675                        f.optimize();
     1676                else
     1677                        f.optimize("no_conditional_skip");
    16001678                y_after   = f.Forward(0, x);
    16011679                dy_after  = f.Forward(1, dx);
     
    16201698                using CppAD::vector;
    16211699                using CppAD::AD;
    1622        
     1700
    16231701                vector< AD<double> > ax(n), ay(1);
    16241702                for(size_t j = 0; j < n; j++)
     
    16271705                ay[0] = my_max(ax) + my_max(ax);
    16281706                CppAD::ADFun<double> f(ax, ay);
    1629        
    1630                 f.optimize();
    1631        
     1707
     1708                if( conditional_skip )
     1709                        f.optimize();
     1710                else
     1711                        f.optimize("no_conditional_skip");
     1712
    16321713                vector<double> x(n), w(1), dx(n);
    16331714                for(size_t j = 0;j < n; j++)
     
    16521733
    16531734                // f(x) = x[0] + x[0] if x[0] >= 3
    1654                 //      = x[0] + x[1] otherwise 
     1735                //      = x[0] + x[1] otherwise
    16551736                vector< AD<double> > ax(2), ay(3);
    16561737                ax[0] = 1.0;
     
    16661747                ay[2]  = CppAD::CondExpGe(ax[0], three, exp(ax[0]), exp(ax[0]) );
    16671748                CppAD::ADFun<double> f(ax, ay);
    1668                 f.optimize();
     1749                if( conditional_skip )
     1750                        f.optimize();
     1751                else
     1752                        f.optimize("no_conditional_skip");
    16691753
    16701754                // check case where x[0] >= 3
     
    16921776{       bool ok = true;
    16931777        atomic_sparsity_option = CppAD::atomic_base<double>::bool_sparsity_enum;
     1778        conditional_skip       = true;
     1779
     1780        // atomic sparsity loop
    16941781        for(size_t i = 0; i < 2; i++)
    1695         {       // check conditional expression sparsity pattern 
    1696                 // (used to optimize calls to atomic functions). 
     1782        {       // check conditional expression sparsity pattern
     1783                // (used to optimize calls to atomic functions).
    16971784                ok     &= atomic_cond_exp_sparsity();
    16981785                // check optimizing out entire atomic function
     
    17011788                ok     &= atomic_no_used();
    17021789                ok     &= atomic_arguments();
    1703                 atomic_sparsity_option = 
     1790                atomic_sparsity_option =
    17041791                        CppAD::atomic_base<double>::set_sparsity_enum;
    17051792        }
    1706         // check nested conditional expressions
    1707         ok     &= nested_cond_exp();
    1708         // check reverse dependency analysis optimization
    1709         ok     &= depend_one();
    1710         ok     &= depend_two();
    1711         ok     &= depend_three();
    1712         ok     &= depend_four();
    1713         // check removal of duplicate expressions
    1714         ok     &= duplicate_one();
    1715         ok     &= duplicate_two();
    1716         ok     &= duplicate_three();
    1717         ok     &= duplicate_four();
    1718         // convert sequence of additions to cummulative summation
    1719         ok     &= cummulative_sum();
    1720         ok     &= forward_csum();
    1721         ok     &= reverse_csum();
    1722         // sparsity patterns
    1723         ok     &= forward_sparse_jacobian();
    1724         ok     &= reverse_sparse_jacobian();
    1725         ok     &= reverse_sparse_hessian();
    1726         // check that CondExp properly detects dependencies
    1727         ok     &= cond_exp_depend();
    1728         // check that it properly handles expressions that have been removed
    1729         ok     &= cond_exp_removed();
    1730         // check old_atomic functions
    1731         ok     &= old_atomic_test();
    1732         // case where results are not identically equal
    1733         ok     &= not_identically_equal();
    1734         // case where a discrete function is used
    1735         ok     &= discrete_function();
    1736         // check conditional skip of an atomic function
    1737         ok     &= cond_exp_skip_atomic();
    1738         // check conditional dependence through atomic function
    1739         ok     &= cond_exp_atomic_dependence();
    1740         // check reverse mode conditional skipping
    1741         ok     &= cond_exp_reverse();
    1742         // check case where an expresion needed by both true and false case
    1743         ok     &=  cond_exp_both_true_and_false();
     1793
     1794        // conditional skip loop
     1795        for(size_t i = 0; i < 2; i++)
     1796        {       // check nested conditional expressions
     1797                ok     &= nested_cond_exp();
     1798                // check reverse dependency analysis optimization
     1799                ok     &= depend_one();
     1800                ok     &= depend_two();
     1801                ok     &= depend_three();
     1802                ok     &= depend_four();
     1803                // check removal of duplicate expressions
     1804                ok     &= duplicate_one();
     1805                ok     &= duplicate_two();
     1806                ok     &= duplicate_three();
     1807                ok     &= duplicate_four();
     1808                // convert sequence of additions to cummulative summation
     1809                ok     &= cummulative_sum();
     1810                ok     &= forward_csum();
     1811                ok     &= reverse_csum();
     1812                // sparsity patterns
     1813                ok     &= forward_sparse_jacobian();
     1814                ok     &= reverse_sparse_jacobian();
     1815                ok     &= reverse_sparse_hessian();
     1816                // check that CondExp properly detects dependencies
     1817                ok     &= cond_exp_depend();
     1818                // check that it properly handles expressions that have been removed
     1819                ok     &= cond_exp_removed();
     1820                // check old_atomic functions
     1821                ok     &= old_atomic_test();
     1822                // case where results are not identically equal
     1823                ok     &= not_identically_equal();
     1824                // case where a discrete function is used
     1825                ok     &= discrete_function();
     1826                // check conditional skip of an atomic function
     1827                ok     &= cond_exp_skip_atomic();
     1828                // check conditional dependence through atomic function
     1829                ok     &= cond_exp_atomic_dependence();
     1830                // check reverse mode conditional skipping
     1831                ok     &= cond_exp_reverse();
     1832                // check case where an expresion needed by both true and false case
     1833                ok     &=  cond_exp_both_true_and_false();
     1834                //
     1835                conditional_skip = false;
     1836        }
    17441837        //
    17451838        CppAD::user_atomic<double>::clear();
Note: See TracChangeset for help on using the changeset viewer.