Changeset 2991 for trunk/test_more


Ignore:
Timestamp:
Oct 22, 2013 12:25:15 PM (6 years ago)
Author:
bradbell
Message:

merger in changes from branches/opt_cond_exp

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/test_more/optimize.cpp

    r2976 r2991  
    1818namespace {
    1919        // -------------------------------------------------------------------
     20        // Test conditional optimizing out call to an atomic function call
     21        void k_algo(
     22                const CppAD::vector< CppAD::AD<double> >& x ,
     23                      CppAD::vector< CppAD::AD<double> >& y )
     24        {       y[0] = x[0] + x[1]; }
     25
     26        void h_algo(
     27                const CppAD::vector< CppAD::AD<double> >& x ,
     28                      CppAD::vector< CppAD::AD<double> >& y )
     29        {       y[0] = x[0] - x[1]; }
     30
     31        bool atomic_cond_exp(void)
     32        {       bool ok = true;
     33                typedef CppAD::vector< CppAD::AD<double> > ADVector;
     34
     35                // Create a checkpoint version of the function g
     36                ADVector ax(2), ag(1), ah(1), ay(1);
     37                ax[0] = 0.;
     38                ax[1] = 1.;
     39                CppAD::checkpoint<double> k_check("k_check", k_algo, ax, ag);
     40                CppAD::checkpoint<double> h_check("h_check", h_algo, ax, ah);
     41
     42                // independent variable vector
     43                Independent(ax);
     44
     45                // atomic function calls that get conditionally used
     46                k_check(ax, ag);
     47                h_check(ax, ah);
     48
     49                // conditional expression
     50                ay[0] = CondExpLt(ax[0], ax[1], ag[0], ah[0]);
     51       
     52                // create function object f : ax -> ay
     53                CppAD::ADFun<double> f;
     54                f.Dependent(ax, ay);
     55       
     56                // use zero order to evaluate when condition is true
     57                CppAD::vector<double>  x(2), dx(2);
     58                CppAD::vector<double>  y(1), dy(1), w(1);
     59                x[0] = 3.;
     60                x[1] = 4.;
     61                y    = f.Forward(0, x);
     62                ok  &= y[0] == x[0] + x[1];
     63
     64                // before optimize
     65                ok  &= f.number_skip() == 0;
     66
     67                // now optimize the operation sequence
     68                f.optimize();
     69
     70                // optimized zero order forward when condition is false
     71                x[0] = 4.;
     72                x[1] = 3.;
     73                y    = f.Forward(0, x);
     74                ok   = y[0] == x[0] - x[1];
     75
     76                // after optimize can skip either call to g or call to h
     77                ok  &= f.number_skip() == 1;
     78
     79                // optimized first order forward
     80                dx[0] = 2.;
     81                dx[1] = 1.;
     82                dy    = f.Forward(1, dx);
     83                ok   &= dy[0] == dx[0] - dx[1];
     84
     85                // optimized first order reverse
     86                w[0]  = 1.;
     87                dx    = f.Reverse(1, w);
     88                ok   &= dx[0] == 1.;
     89                ok   &= dx[1] == -1.;
     90       
     91                return ok;
     92        }
     93        // -------------------------------------------------------------------
    2094        // Test of optimizing out arguments to an atomic function
    21         void algo(
     95        void g_algo(
    2296                const CppAD::vector< CppAD::AD<double> >& ax ,
    2397                      CppAD::vector< CppAD::AD<double> >& ay )
    2498        {       ay = ax; }
    2599
     100        bool atomic_no_used(void)
     101        {       bool ok = true;
     102                using CppAD::AD;
     103                using CppAD::vector;
     104       
     105                // Create a checkpoint version of the function g
     106                vector< AD<double> > ax(2), ay(1), az(1);
     107                ax[0] = 0.;
     108                ax[1] = 1.;
     109                CppAD::checkpoint<double> g_check("g_check", g_algo, ax, ay);
     110       
     111                // independent variable vector
     112                Independent(ax);
     113       
     114                // call atomic function that does not get used
     115                g_check(ax, ay);
     116       
     117                // conditional expression
     118                az[0] = CondExpLt(ax[0], ax[1], ax[0] + ax[1], ax[0] - ax[1]);
     119               
     120                // create function object f : ax -> az
     121                CppAD::ADFun<double> f;
     122                f.Dependent(ax, az);
     123
     124                // number of variables before optimization
     125                size_t n_before = f.size_var();
     126               
     127                // now optimize the operation sequence
     128                f.optimize();
     129
     130                // number of variables before optimization
     131                size_t n_after = f.size_var();
     132                ok            &= n_after + 1 == n_before;
     133       
     134                // check optimization works ok
     135                vector<double> x(2), z(1);
     136                x[0] = 4.;
     137                x[1] = 3.;
     138                z    = f.Forward(0, x);
     139                ok   = z[0] == x[0] - x[1];
     140               
     141                return ok;
     142        }
    26143        bool atomic_arguments(void)
    27144        {       bool ok = true;
     
    30147                vector< AD<double> > au(2), aw(2), ax(2), ay(1);
    31148
    32                 // create atomic function corresponding to algo
     149                // create atomic function corresponding to g_algo
    33150                au[0] = 1.0;
    34151                au[1] = 2.0;
    35                 CppAD::checkpoint<double> algo_check("algo", algo, au, ax);
     152                CppAD::checkpoint<double> g_check("g_algo", g_algo, au, ax);
    36153
    37154                // start recording a new function
    38155                CppAD::Independent(ax);
    39156
    40                 // now use algo_check during the recording
     157                // now use g_check during the recording
    41158                au[0] = ax[0] + ax[1]; // this argument requires a new variable
    42159                au[1] = ax[0] - ax[1]; // this argument also requires a new variable
    43                 algo_check(au, aw);
     160                g_check(au, aw);
    44161
    45162                // now create f(x) = x_0 - x_1
     
    765882                return ok;
    766883        }
    767         bool forward_sparse_jacobian_csum()
     884        bool forward_sparse_jacobian()
    768885        {       bool ok = true;
    769886                using namespace CppAD;
     
    773890       
    774891                // dimension of the range space
    775                 size_t m = 2;
     892                size_t m = 3;
    776893       
    777894                // independent variable vector
     
    779896                X[0] = 2.;
    780897                X[1] = 3.;
     898                X[2] = 4.;
    781899                Independent(X);
    782900       
     
    800918                Y[index]             = Y[0] - (X[1] + X[2]);
    801919                Check[index * n + 0] = true;
     920                Check[index * n + 1] = true;
     921                Check[index * n + 2] = true;
     922                index++;
     923
     924                // Y[2]
     925                // 2DO: There is a subtitle issue that has to do with using reverse
     926                // jacobian sparsity patterns during the optimization process.
     927                // We need an option to include X[0] in the sparsity pattern
     928                // so the optimizer can know it affects the results.
     929                Y[index]             = CondExpLe(X[0], X[1], X[1]+X[1], X[2]-X[2]);
     930                Check[index * n + 0] = false;
    802931                Check[index * n + 1] = true;
    803932                Check[index * n + 2] = true;
     
    835964                return ok;
    836965        }
    837         bool reverse_sparse_jacobian_csum()
     966        bool reverse_sparse_jacobian()
    838967        {       bool ok = true;
    839968                using namespace CppAD;
     
    843972       
    844973                // dimension of the range space
    845                 size_t m = 2;
     974                size_t m = 3;
    846975       
    847976                // independent variable vector
     
    849978                X[0] = 2.;
    850979                X[1] = 3.;
     980                X[2] = 4.;
    851981                Independent(X);
    852982       
     
    8731003                Check[index * n + 2] = true;
    8741004                index++;
     1005
     1006                // Y[2]
     1007                // 2DO: There is a subtitle issue that has to do with using reverse
     1008                // jacobian sparsity patterns during the optimization process.
     1009                // We need an option to include X[0] in the sparsity pattern
     1010                // so the optimizer can know it affects the results.
     1011                Y[index]             = CondExpLe(X[0], X[1], X[1]+X[1], X[2]-X[2]);
     1012                Check[index * n + 0] = false;
     1013                Check[index * n + 1] = true;
     1014                Check[index * n + 2] = true;
     1015                index++;
    8751016       
    8761017                // check final index
     
    9021043                return ok;
    9031044        }
    904         bool reverse_sparse_hessian_csum(void)
     1045        bool reverse_sparse_hessian(void)
    9051046        {       bool ok = true;
    9061047                using CppAD::AD;
    9071048                size_t i, j;
    9081049       
    909                 size_t n = 2;
     1050                size_t n = 3;
    9101051                CppAD::vector< AD<double> > X(n);
    9111052                X[0] = 1.;
    9121053                X[1] = 2.;
     1054                X[2] = 3.;
    9131055                CppAD::Independent(X);
    9141056       
    9151057                size_t m = 1;
    9161058                CppAD::vector< AD<double> > Y(m);
    917                 Y[0] = (2. + X[0] + X[1] + 3.) * X[0];
     1059                Y[0] = CondExpGe( X[0], X[1],
     1060                        X[0] + (2. + X[1] + 3.) * X[1],
     1061                        X[0] + (2. + X[2] + 3.) * X[1]
     1062                );
    9181063       
    9191064                CppAD::vector<bool> check(n * n);
    920                 check[0 * n + 0] = true;  // partial w.r.t. x[0], x[0]
    921                 check[0 * n + 1] = true;  //                x[0], x[1]
    922                 check[1 * n + 0] = true;  //                x[1], x[0]
    923                 check[1 * n + 1] = false; //                x[1], x[1]
     1065                check[0 * n + 0] = false; // partial w.r.t. x[0], x[0]
     1066                check[0 * n + 1] = false; //                x[0], x[1]
     1067                check[0 * n + 2] = false; //                x[0], x[2]
     1068
     1069                check[1 * n + 0] = false; // partial w.r.t. x[1], x[0]
     1070                check[1 * n + 1] = true;  //                x[1], x[1]
     1071                check[1 * n + 2] = true;  //                x[1], x[2]
     1072
     1073                check[2 * n + 0] = false; // partial w.r.t. x[2], x[0]
     1074                check[2 * n + 1] = true;  //                x[2], x[1]
     1075                check[2 * n + 2] = false; //                x[2], x[2]
    9241076       
    9251077                // create function object F : X -> Y
     
    11661318bool optimize(void)
    11671319{       bool ok = true;
     1320        // check optimizing out entire atomic function
     1321        ok     &= atomic_cond_exp();
    11681322        // check optimizing out atomic arguments
    11691323        ok     &= atomic_arguments();
     
    11811335        ok     &= forward_csum();
    11821336        ok     &= reverse_csum();
    1183         ok     &= forward_sparse_jacobian_csum();
    1184         ok     &= reverse_sparse_jacobian_csum();
    1185         ok     &= reverse_sparse_hessian_csum();
     1337        // sparsity patterns
     1338        ok     &= forward_sparse_jacobian();
     1339        ok     &= reverse_sparse_jacobian();
     1340        ok     &= reverse_sparse_hessian();
    11861341        // check that CondExp properly detects dependencies
    11871342        ok     &= cond_exp_depend();
Note: See TracChangeset for help on using the changeset viewer.