Changeset 3638


Ignore:
Timestamp:
Feb 10, 2015 10:04:04 AM (5 years ago)
Author:
bradbell
Message:

merge to branch: trunk
from repository: https://github.com/coin-or/CppAD
start hash code: 3249a4c6f8216de001805d3e22bcdec63fed2d25
end hash code: 22c1453e46e3eb16e9a96d679a0a1fd459c849c0

commit 22c1453e46e3eb16e9a96d679a0a1fd459c849c0
Author: Brad Bell <bradbell@…>
Date: Tue Feb 10 07:19:54 2015 -0700

Fix bug in optimization and sparsity calculations that include the C++11 erf function.

commit df8602cb2129722c0b373fa467a76289769c026e
Author: Brad Bell <bradbell@…>
Date: Mon Feb 9 20:25:19 2015 -0700

erf.sh: Bug report by Micheal Braun.

Location:
trunk
Files:
1 added
8 edited

Legend:

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

    r3607 r3638  
    331331
    332332                        case ErfOp:
    333                         CPPAD_ASSERT_NARG_NRES(op, 1, 1);
     333                        // arg[1] is always the parameter 0
     334                        // arg[0] is always the parameter 2 / sqrt(pi)
     335                        CPPAD_ASSERT_NARG_NRES(op, 3, 5);
    334336                        forward_sparse_jacobian_unary_op(
    335337                                i_var, arg[0], var_sparsity
  • trunk/cppad/local/hash_code.hpp

    r3359 r3638  
    44
    55/* --------------------------------------------------------------------------
    6 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-14 Bradley M. Bell
     6CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-15 Bradley M. Bell
    77
    88CppAD is distributed under multiple licenses. This distribution is under
     
    218218                case CosOp:
    219219                case CoshOp:
     220                case ErfOp:
    220221                case ExpOp:
    221222                case LogOp:
     
    226227                case TanOp:
    227228                case TanhOp:
     229                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 || op == ErfOp );
    228230                v = reinterpret_cast<const unsigned short*>(arg + 0);
    229231                i = short_addr_t;
  • trunk/cppad/local/op_code.hpp

    r3607 r3638  
    699699                case ErfOp:
    700700                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
    701                 // ind[2] points to the parameter 0
    702                 // ind[3] points to the parameter 2 / sqrt(pi)
     701                // ind[1] points to the parameter 0
     702                // ind[2] points to the parameter 2 / sqrt(pi)
    703703                printOpField(os, "  v=", ind[0], ncol);
    704704                break;
  • trunk/cppad/local/optimize.hpp

    r3623 r3638  
    487487        addr_t new_arg[1];
    488488       
    489         CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
     489        // ErfOp has three arguments, but the second and third are always the
     490        // parameters 0 and 2 / sqrt(pi) respectively.
     491        CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 || op == ErfOp);
    490492        CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0  );
    491493        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < current );
     
    14111413                        case CoshOp:
    14121414                        case DivvpOp:
     1415                        case ErfOp:
    14131416                        case ExpOp:
    14141417                        case LogOp:
     
    21722175                        case CosOp:
    21732176                        case CoshOp:
     2177                        case ErfOp:
    21742178                        case ExpOp:
    21752179                        case LogOp:
     
    22012205                                tape[i_var].new_var = i = rec->PutOp(op);
    22022206                                CPPAD_ASSERT_UNKNOWN( size_t(new_arg[0]) < i );
     2207                                if( op == ErfOp )
     2208                                {       // Error function is a special case
     2209                                        // second argument is always the parameter 0
     2210                                        // third argument is always the parameter 2 / sqrt(pi)
     2211                                        CPPAD_ASSERT_UNKNOWN( NumArg(ErfOp) == 3 );
     2212                                        rec->PutArg( rec->PutPar( Base(0) ) );
     2213                                        rec->PutArg( rec->PutPar(
     2214                                                Base( 1.0 / std::sqrt( std::atan(1.0) ) )
     2215                                        ) );
     2216                                }
    22032217                        }
    22042218                        break;
  • trunk/cppad/local/rev_hes_sweep.hpp

    r3607 r3638  
    353353
    354354                        case ErfOp:
    355                         CPPAD_ASSERT_NARG_NRES(op, 1, 1)
     355                        // arg[1] is always the parameter 0
     356                        // arg[0] is always the parameter 2 / sqrt(pi)
     357                        CPPAD_ASSERT_NARG_NRES(op, 3, 5);
    356358                        reverse_sparse_hessian_nonlinear_unary_op(
    357359                        i_var, arg[0], RevJac, for_jac_sparse, rev_hes_sparse
  • trunk/cppad/local/rev_jac_sweep.hpp

    r3607 r3638  
    342342
    343343                        case ErfOp:
    344                         CPPAD_ASSERT_NARG_NRES(op, 1, 1);
     344                        // arg[1] is always the parameter 0
     345                        // arg[0] is always the parameter 2 / sqrt(pi)
     346                        CPPAD_ASSERT_NARG_NRES(op, 3, 5);
    345347                        reverse_sparse_jacobian_unary_op(
    346348                                i_var, arg[0], var_sparsity
  • trunk/omh/whats_new/whats_new_15.omh

    r3637 r3638  
    3232        std
    3333        cxx
     34        erf
    3435$$
    3536
     
    4142The purpose of this section is to
    4243assist you in learning about changes between various versions of CppAD.
     44
     45$head 02-10$$
     46The change on $cref/2014-12-23/whats_new_14/12-23/$$ introduced a
     47bug when the c++11 version of the error function was used with
     48an $cref/optimized/optimize/$$ function. see
     49$cref/CPPAD_COMPILER_HAS_ERF/erf/Method/CPPAD_COMPILER_HAS_ERF/$$.
     50There was also a bug in the sparsity calculations for when
     51this erf function was included.
     52These bugs have been fixed.
    4353
    4454$head 02-09$$
  • trunk/test_more/optimize.cpp

    r3637 r3638  
    543543                return ok;
    544544        }
     545        bool depend_four(void)
     546        {       // erf function is a special case for optimize
     547                bool ok = true;
     548# if CPPAD_COMPILER_HAS_ERF
     549                using CppAD::AD;
     550                using CppAD::vector;
     551
     552                size_t n = 1;
     553                size_t m = 1;
     554                vector< AD<double> > X(n), Y(m);
     555                vector<double>       x(n);
     556                X[0] = x[0] = double(0.5);
     557
     558                CppAD::Independent(X);
     559
     560                Y[0] = erf(X[0]) + erf(X[0]);
     561
     562                CppAD::ADFun<double> F(X, Y);
     563
     564                vector<double> y_original     = F.Forward(0, x);
     565                size_t         size_original  = F.size_var();
     566                F.optimize();
     567                ok &= F.size_var() + 5 == size_original;
     568                vector<double> y = F.Forward(0, x);
     569                ok &=  NearEqual(y[0], y_original[0], eps, eps);
     570# endif
     571                return ok;
     572        }
    545573        // ===================================================================
    546574        // Test duplicate operation analysis
     
    16491677        ok     &= depend_two();
    16501678        ok     &= depend_three();
     1679        ok     &= depend_four();
    16511680        // check removal of duplicate expressions
    16521681        ok     &= duplicate_one();
Note: See TracChangeset for help on using the changeset viewer.