Changeset 3507


Ignore:
Timestamp:
Dec 27, 2014 11:30:12 AM (5 years ago)
Author:
bradbell
Message:

Must use old variable index to mark variables used as replacements for
other variables (that have been removed).

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/cppad/local/optimize.hpp

    r3504 r3507  
    252252        std::set<class_cexp_pair> cexp_set;
    253253
    254         /// Result of check for a match for this varable.
    255         addr_t match_var;
    256 
    257254        /// New operation sequence corresponding to this old varable.
    258255        /// Set during forward sweep to the index in the new tape
     
    262259        /// Set during forward sweep to the index in the new tape
    263260        size_t new_op;
     261
     262        /// Did this variable match another variable in the operation sequence
     263        bool match;
    264264};
    265265
     
    474474no match was found.
    475475If the return value is greater than zero,
    476 it is the index of a new variable that can be used to replace the
    477 old variable.
     476it is the old operation sequence index of a variable,
     477that comes before current and can be used to replace the current variable.
    478478
    479479\par Restrictions:
     
    503503                par
    504504        );
    505         size_t  i               = hash_table_var[code];
    506         CPPAD_ASSERT_UNKNOWN( i < current );
    507         if( op == tape[i].op )
    508         {       size_t k = tape[i].arg[0];
    509                 CPPAD_ASSERT_UNKNOWN( k < i );
     505        size_t  i_var  = hash_table_var[code];
     506        CPPAD_ASSERT_UNKNOWN( i_var < current );
     507        if( op == tape[i_var].op )
     508        {       size_t k = tape[i_var].arg[0];
     509                CPPAD_ASSERT_UNKNOWN( k < i_var );
    510510                if (new_arg[0] == tape[k].new_var )
    511                         return tape[i].new_var;
     511                        return i_var;
    512512        }
    513513        return 0;
     
    670670                par
    671671        );
    672         size_t  i  = hash_table_var[code];
    673         CPPAD_ASSERT_UNKNOWN( i < current );
    674         if( op == tape[i].op )
     672        size_t  i_var  = hash_table_var[code];
     673        CPPAD_ASSERT_UNKNOWN( i_var < current );
     674        if( op == tape[i_var].op )
    675675        {       bool match = true;
    676676                if( op == DisOp )
    677                 {       match   &= new_arg[0] == tape[i].arg[0];
    678                         size_t k = tape[i].arg[1];
     677                {       match   &= new_arg[0] == tape[i_var].arg[0];
     678                        size_t k = tape[i_var].arg[1];
    679679                        match   &= new_arg[1] == tape[k].new_var;
    680680                }
    681681                else
    682682                {       for(size_t j = 0; j < 2; j++)
    683                         {       size_t k = tape[i].arg[j];
     683                        {       size_t k = tape[i_var].arg[j];
    684684                                if( parameter[j] )
    685685                                {       CPPAD_ASSERT_UNKNOWN( k < npar );
     
    689689                                }
    690690                                else
    691                                 {       CPPAD_ASSERT_UNKNOWN( k < i );
     691                                {       CPPAD_ASSERT_UNKNOWN( k < i_var );
    692692                                        match &= (new_arg[j] == tape[k].new_var);
    693693                                }
     
    695695                }
    696696                if( match )
    697                         match_var = tape[i].new_var;
     697                        match_var = i_var;
    698698        }
    699699        if( (match_var > 0) | ( (op != AddvvOp) & (op != MulvvOp ) ) )
     
    702702        // check for match with argument order switched ----------------------
    703703        CPPAD_ASSERT_UNKNOWN( op == AddvvOp || op == MulvvOp );
    704         i          = new_arg[0];
    705         new_arg[0] = new_arg[1];
    706         new_arg[1] = i;
     704        std::swap(new_arg[0], new_arg[1]);
    707705        unsigned short code_switch = hash_code(
    708706                op                  ,
     
    711709                par
    712710        );
    713         i  = hash_table_var[code_switch];
    714         CPPAD_ASSERT_UNKNOWN( i < current );
    715         if( op == tape[i].op )
     711        i_var  = hash_table_var[code_switch];
     712        CPPAD_ASSERT_UNKNOWN( i_var < current );
     713        if( op == tape[i_var].op )
    716714        {       bool match = true;
    717715                size_t j;
    718716                for(j = 0; j < 2; j++)
    719                 {       size_t k = tape[i].arg[j];
    720                         CPPAD_ASSERT_UNKNOWN( k < i );
     717                {       size_t k = tape[i_var].arg[j];
     718                        CPPAD_ASSERT_UNKNOWN( k < i_var );
    721719                        match &= (new_arg[j] == tape[k].new_var);
    722720                }
    723721                if( match )
    724                         match_var = tape[i].new_var;
     722                        match_var = i_var;
    725723        }
    726724        return match_var;
     
    21352133                unsigned short code         = 0;
    21362134                bool           replace_hash = false;
     2135                addr_t         match_var;
     2136                tape[i_var].match = false;
    21372137                if( keep ) switch( op )
    21382138                {
     
    21522152                        case TanOp:
    21532153                        case TanhOp:
    2154                         tape[i_var].match_var = unary_match(
     2154                        match_var = unary_match(
    21552155                                tape                ,  // inputs
    21562156                                i_var               ,
     
    21602160                                code                  // outputs
    21612161                        );
    2162                         if( tape[i_var].match_var > 0 )
    2163                                 tape[i_var].new_var = tape[i_var].match_var;
     2162                        if( match_var > 0 )
     2163                        {       tape[i_var].match     = true;
     2164                                tape[match_var].match = true;
     2165                                tape[i_var].new_var   = tape[match_var].new_var;
     2166                        }
    21642167                        else
    21652168                        {
     
    21942197                        case DivvpOp:
    21952198                        case PowvpOp:
    2196                         tape[i_var].match_var = binary_match(
     2199                        match_var = binary_match(
    21972200                                tape                ,  // inputs
    21982201                                i_var               ,
     
    22022205                                code                  // outputs
    22032206                        );
    2204                         if( tape[i_var].match_var > 0 )
    2205                                 tape[i_var].new_var = tape[i_var].match_var;
     2207                        if( match_var > 0 )
     2208                        {       tape[i_var].match     = true;
     2209                                tape[match_var].match = true;
     2210                                tape[i_var].new_var   = tape[match_var].new_var;
     2211                        }
    22062212                        else
    22072213                        {       size_pair = record_vp(
     
    22232229                        // left is an index and right is a variable
    22242230                        case DisOp:
    2225                         tape[i_var].match_var = binary_match(
     2231                        match_var = binary_match(
    22262232                                tape                ,  // inputs
    22272233                                i_var               ,
     
    22312237                                code                  // outputs
    22322238                        );
    2233                         if( tape[i_var].match_var > 0 )
    2234                                 tape[i_var].new_var = tape[i_var].match_var;
     2239                        if( match_var > 0 )
     2240                        {       tape[i_var].match     = true;
     2241                                tape[match_var].match = true;
     2242                                tape[i_var].new_var   = tape[match_var].new_var;
     2243                        }
    22352244                        else
    22362245                        {       new_arg[0] = arg[0];
     
    22702279                        case MulpvOp:
    22712280                        case PowpvOp:
    2272                         tape[i_var].match_var = binary_match(
     2281                        match_var = binary_match(
    22732282                                tape                ,  // inputs
    22742283                                i_var               ,
     
    22782287                                code                  // outputs
    22792288                        );
    2280                         if( tape[i_var].match_var > 0 )
    2281                                 tape[i_var].new_var = tape[i_var].match_var;
     2289                        if( match_var > 0 )
     2290                        {       tape[i_var].match     = true;
     2291                                tape[match_var].match = true;
     2292                                tape[i_var].new_var   = tape[match_var].new_var;
     2293                        }
    22822294                        else
    22832295                        {       size_pair = record_pv(
     
    23212333                        case MulvvOp:
    23222334                        case PowvvOp:
    2323                         tape[i_var].match_var = binary_match(
     2335                        match_var = binary_match(
    23242336                                tape                ,  // inputs
    23252337                                i_var               ,
     
    23292341                                code                  // outputs
    23302342                        );
    2331                         if( tape[i_var].match_var > 0 )
    2332                                 tape[i_var].new_var = tape[i_var].match_var;
     2343                        if( match_var > 0 )
     2344                        {       tape[i_var].match     = true;
     2345                                tape[match_var].match = true;
     2346                                tape[i_var].new_var   = tape[match_var].new_var;
     2347                        }
    23332348                        else
    23342349                        {       size_pair = record_vv(
     
    26342649                        for(j = 0; j < info.skip_var_true.size(); j++)
    26352650                        {       i_var = info.skip_var_true[j];
    2636                                 if( tape[i_var].match_var > 0 )
     2651                                if( tape[i_var].match )
    26372652                                {       // the operation for this argument has been removed
    26382653                                        rec->ReplaceArg(i_arg++, 0);
     
    26492664                        for(j = 0; j < info.skip_var_false.size(); j++)
    26502665                        {       i_var = info.skip_var_false[j];
    2651                                 if( tape[i_var].match_var > 0 )
     2666                                if( tape[i_var].match )
    26522667                                {       // the operation for this argument has been removed
    26532668                                        rec->ReplaceArg(i_arg++, 0);
  • trunk/omh/whats_new/whats_new_14.omh

    r3505 r3507  
    6363
    6464$head 12-27$$
     65More work on the bug in
     66$cref/optimizing/CondExp/Optimize/$$
     67conditional expressions.
     68
     69$head 12-26$$
    6570A minimal example for computing cross terms in atomic operation
    6671Hessian sparsity patterns $cref atomic_hes_sparse.cpp$$ was added.
    6772
    6873$head 12-25$$
    69 There was another bug related to
     74More work on the bug in
    7075$cref/optimizing/CondExp/Optimize/$$
    7176conditional expressions.
    72 This has been fixed.
    7377
    7478$head 12-23$$
  • trunk/test_more/optimize.cpp

    r3504 r3507  
    15941594                // f(x) = x[0] + x[0] if x[0] >= 3
    15951595                //      = x[0] + x[1] otherwise
    1596                 vector< AD<double> > ax(2), ay(2);
     1596                vector< AD<double> > ax(2), ay(3);
    15971597                ax[0] = 1.0;
    15981598                ax[1] = 2.0;
     
    16001600                AD<double> three(3);
    16011601                AD<double> value = ax[0] + ax[1];
     1602                // a simple value
    16021603                ay[0]  = CppAD::CondExpGe(ax[0], three, value, value);
    1603                 ay[1]  = CppAD::CondExpGe(ax[0], three, ax[0]+ax[1], ax[0]+ax[1]);
     1604                // a  binary exprpression
     1605                ay[1]  = CppAD::CondExpGe(ax[0], three, ax[0]-ax[1], ax[0]-ax[1]);
     1606                // a unary expression
     1607                ay[2]  = CppAD::CondExpGe(ax[0], three, exp(ax[0]), exp(ax[0]) );
    16041608                CppAD::ADFun<double> f(ax, ay);
    16051609                f.optimize();
    16061610
    16071611                // check case where x[0] >= 3
    1608                 vector<double> x(2), y(2);
     1612                vector<double> x(2), y(3);
    16091613                x[0] = 4.0;
    16101614                x[1] = 2.0;
    16111615                y    = f.Forward(0, x);
    16121616                ok  &= y[0] == x[0] + x[1];
    1613                 ok  &= y[1] == x[0] + x[1];
     1617                ok  &= y[1] == x[0] - x[1];
     1618                ok  &= y[2] == exp(x[0]);
    16141619
    16151620                // check case where x[0] < 3
     
    16181623                y    = f.Forward(0, x);
    16191624                ok  &= y[0] == x[0] + x[1];
    1620                 ok  &= y[1] == x[0] + x[1];
     1625                ok  &= y[1] == x[0] - x[1];
     1626                ok  &= y[2] == exp(x[0]);
    16211627
    16221628                return ok;
Note: See TracChangeset for help on using the changeset viewer.