Changeset 2240


Ignore:
Timestamp:
Dec 31, 2011 12:33:55 AM (8 years ago)
Author:
bradbell
Message:
  1. Fix bug in abs function with AD< AD<double> > arguments.
  2. Define derivative of abs as sign function.
  3. Add sign function to AD<Base>, Base requirements, and corresponding examples.

check_op_code.sh: porper alphabetic order drops Op from SinOp? and SinhOp?...
abs.cpp: change example to new derivative specification.
base_adolc.hpp: add definition of abs in CppAD namespace.
abs.cpp: test that demonstraces bug in abs for AD< AD<double> >.

Location:
trunk
Files:
3 added
28 edited

Legend:

Unmodified
Added
Removed
  • trunk/bin/check_op_code.sh

    r2082 r2240  
    2121sed -n -e '/^enum/,/^};/p' cppad/local/op_code.hpp | \
    2222        sed -e '/^enum/d' -e '/^};/d' \
    23                 -e 's/^[        ]*//' -e 's/[, ].*//' -e '/^\/\//d' > bin/op_code.1.$$
     23                -e 's/^[        ]*//' -e 's/Op[, ].*//' -e '/^\/\//d' > bin/op_code.1.$$
    2424#
    2525sort --ignore-case bin/op_code.1.$$ > bin/op_code.2.$$
     
    3333# check NumArgTable
    3434sed -n -e '/NumArgTable\[\]/,/^};/p' cppad/local/op_code.hpp | \
    35         sed -e '/NumArgTable\[\]/d' -e '/^};/d' \
    36                 -e 's|^[        ]*[0-9],* *// *||' -e 's| .*||' > bin/op_code.3.$$
     35        sed \
     36                -e '/NumArgTable\[\]/d' \
     37                -e '/^};/d' \
     38                -e 's|^[        ]*[0-9],* *// *||' \
     39                -e 's|Op.*||' \
     40                > bin/op_code.3.$$
    3741#
    3842if ! diff bin/op_code.1.$$ bin/op_code.3.$$
     
    4549# check NumResTable (last line of NumResTable is not used)
    4650sed -n -e '/NumResTable\[\]/,/^};/p' cppad/local/op_code.hpp | \
    47         sed -e '/NumResTable\[\]/d' -e '/^};/d' -e '/Last entry not used/d' \
    48         -e 's|^[        ]*[0-9],* *// *||' -e 's| .*||' > bin/op_code.4.$$
     51        sed \
     52                -e '/NumResTable\[\]/d' \
     53                -e '/^};/d' \
     54                -e '/Last entry not used/d' \
     55                -e 's|^[        ]*[0-9],* *// *||' \
     56                -e 's|Op.*||' \
     57                > bin/op_code.4.$$
    4958#
    5059if ! diff bin/op_code.1.$$ bin/op_code.4.$$
     
    5867# check OpName
    5968sed -n -e '/char \*OpName\[\]/,/^[      ]*};/p' cppad/local/op_code.hpp | \
    60         sed -e '/char \*OpName\[\]/d' -e '/^[   ]*};/d' \
    61         -e 's|^[        ]*"||' -e 's|".*|Op|' > bin/op_code.5.$$
     69        sed \
     70                -e '/char \*OpName\[\]/d' \
     71                -e '/^[         ]*};/d' \
     72                -e 's|^[        ]*"||' \
     73                -e 's|".*||' \
     74                > bin/op_code.5.$$
    6275#
    6376if ! diff bin/op_code.1.$$ bin/op_code.5.$$
  • trunk/cppad/local/abs.hpp

    r1447 r2240  
    44
    55/* --------------------------------------------------------------------------
    6 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-09 Bradley M. Bell
     6CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-11 Bradley M. Bell
    77
    88CppAD is distributed under multiple licenses. This distribution is under
     
    3030$index abs, AD$$
    3131$index absolute, AD value$$
    32 $index value_, AD absolute$$
     32$index value, AD absolute$$
    3333
    3434$section AD Absolute Value Function$$
    3535
    3636$head Syntax$$
    37 $syntax%%y% = abs(%x%)%$$
     37$icode%y% = abs(%x%)%$$
    3838
    3939
     
    4141Evaluates the absolute value function.
    4242
    43 
    4443$head x$$
    45 The argument $italic x$$ has one of the following prototypes
    46 $syntax%
     44The argument $icode x$$ has one of the following prototypes
     45$codei%
    4746        const AD<%Base%>               &%x%
    4847        const VecAD<%Base%>::reference &%x%
     
    5049
    5150$head y$$
    52 The result $italic y$$ has prototype
    53 $syntax%
     51The result $icode y$$ has prototype
     52$codei%
    5453        AD<%Base%> %y%
    5554%$$
     
    5756
    5857$head Operation Sequence$$
    59 This is an AD of $italic Base$$
    60 $xref/glossary/Operation/Atomic/atomic operation/1/$$
     58This is an AD of $icode Base$$
     59$cref/atomic operation/glossary/Operation/Atomic/$$
    6160and hence is part of the current
    62 AD of $italic Base$$
    63 $xref/glossary/Operation/Sequence/operation sequence/1/$$.
     61AD of $icode Base$$
     62$cref/operation sequence/glossary/Operation/Sequence/$$.
    6463
    6564$head Complex Types$$
     
    6766above $code std::complex<float>$$ or $code std::complex<double>$$
    6867because the complex $code abs$$ function is not complex differentiable
    69 (see $xref/Faq/Complex Types/complex types faq/$$).
     68(see $cref/complex types faq/Faq/Complex Types/$$).
    7069
    71 $head Directional Derivative$$
    72 $index directional, derivative abs$$
    73 $index derivative, directional abs$$
     70$head Derivative$$
     71CppAD defines the derivative of the $code abs$$ function is
     72the $cref sign$$ function; i.e.,
     73$latex \[
     74{\rm abs}^{(1)} ( x ) = {\rm sign} (x ) =
     75\left\{ \begin{array}{rl}
     76        +1 & {\rm if} \; x > 0 \\
     77        0  & {\rm if} \; x = 0 \\
     78        -1 & {\rm if} \; x < 0
     79\end{array} \right.
     80\] $$
     81This used to be different;
     82see $cref/old derivative/abs/Old Derivative/$$ below.
     83
     84$head Example$$
     85$children%
     86        example/abs.cpp
     87%$$
     88The file
     89$cref abs.cpp$$
     90contains an example and test of this function.   
     91It returns true if it succeeds and false otherwise.
     92
     93$head Old Derivative$$
    7494The derivative of the absolute value function is one for
    7595$latex x > 0$$ and minus one for $latex x < 0$$.
    76 The subtitle issue is
    77 how to compute its directional derivative
     96CppAD used to compute its directional derivative
    7897what $latex x = 0$$.
    7998$pre
    8099
    81100$$
    82 The function corresponding to the argument $italic x$$
    83 and the result $italic y$$ are represented
     101The function corresponding to the argument $icode x$$
     102and the result $icode y$$ are represented
    84103by their Taylor coefficients; i.e.,
    85104$latex \[
     
    90109\end{array}
    91110\] $$
    92 Note that $latex x^{(0)} = X(0)$$ is the value of $italic x$$ and
    93 $latex y^{(0)} = Y(0)$$ is the value of $italic y$$.
     111Note that $latex x^{(0)} = X(0)$$ is the value of $icode x$$ and
     112$latex y^{(0)} = Y(0)$$ is the value of $icode y$$.
    94113In the equations above, the order $latex p$$ is specified
    95 by a call to $xref/Forward/$$ or $xref/Reverse/$$ as follows:
    96 $syntax%
     114by a call to $cref Forward$$ or $xref/Reverse/$$ as follows:
     115$codei%
    97116        %f%.Forward(%p%, %dx%)
    98117        %f%.Reverse(%p%+1, %w%)
     
    114133\end{array} \right.
    115134\] $$
    116 
    117 
    118 $head Example$$
    119 $children%
    120         example/abs.cpp
    121 %$$
    122 The file
    123 $xref/Abs.cpp/$$
    124 contains an example and test of this function.   
    125 It returns true if it succeeds and false otherwise.
    126135
    127136$end
  • trunk/cppad/local/abs_op.hpp

    r1997 r2240  
    2121*/
    2222
    23 
    2423/*!
    2524Compute forward mode Taylor coefficient for result of op = AbsOp.
     
    4039        Base*  taylor      )
    4140{
    42         size_t k;
    43         Base zero(0.);
    44 
    4541        // check assumptions
    4642        CPPAD_ASSERT_UNKNOWN( NumArg(AbsOp) == 1 );
     
    5349        Base* z = taylor + i_z * nc_taylor;
    5450
    55         // order that decides positive, negative or zero
    56         k = 0;
    57         while( (k < j) & (x[k] == zero) )
    58                 k++;
    59 
    60         if( GreaterThanZero(x[k]) )
    61                 z[j]  = x[j];
    62         else if( LessThanZero(x[k]) )
    63                 z[j] = -x[j];
    64         else    z[j] = zero;
     51        z[j] = sign(x[0]) * x[j];
    6552}
    6653
     
    9077
    9178        // Taylor coefficients corresponding to argument and result
    92         Base y0 = *(taylor + i_x * nc_taylor);
     79        Base x0 = *(taylor + i_x * nc_taylor);
    9380        Base* z = taylor + i_z * nc_taylor;
    9481
    95         if( LessThanZero(y0) )
    96                 z[0]  = - y0;
    97         else    z[0] = y0;
     82        z[0] = abs(x0);
    9883}
    9984/*!
     
    117102        size_t      nc_partial   ,
    118103        Base*       partial      )
    119 {       size_t j, k;   
    120         Base zero(0.);
     104{       size_t j;       
    121105
    122106        // check assumptions
     
    134118        Base* pz       = partial +    i_z * nc_partial;
    135119
    136         // order that decides positive, negative or zero
    137         k = 0;
    138         while( (k < d) & (x[k] == zero) )
    139                 k++;
    140 
    141         if( GreaterThanZero(x[k]) )
    142         {       // partial of z w.r.t y is +1
    143                 for(j = k; j <= d; j++)
    144                         px[j] += pz[j];
    145         }
    146         else if( LessThanZero(x[k]) )
    147         {       // partial of z w.r.t y is -1
    148                 for(j = k; j <= d; j++)
    149                         px[j] -= pz[j];
    150         }
     120        for(j = 0; j <= d; j++)
     121                px[j] += sign(x[0]) * pz[j];
    151122}
    152123
  • trunk/cppad/local/ad.hpp

    r2057 r2240  
    183183        inline AD log(void) const;
    184184        inline AD sin(void) const;
     185        inline AD Sign(void) const;
    185186        inline AD sinh(void) const;
    186187        inline AD sqrt(void) const;
  • trunk/cppad/local/base_complex.hpp

    r2211 r2240  
    8282
    8383$head CondExpOp$$
    84 The conditional expressions $cref/CondExp/$$
    85 requires ordered comparisons (e.g., $code <$$)
    86 and the C++ standard complex types do not allow for ordered comparisons.
    87 Thus, we make it an error to use the conditional comparisons
    88 with complex types:
     84The type $code std::complex<double>$$ does not supports the
     85$code <$$, $code <=$$, $code ==$$, $code >=$$, and $code >$$ operators; see
     86$cref/not ordered/base_cond_exp/CondExpTemplate/Not Ordered/$$.
     87Hence its $code CondExpOp$$ function is defined by
    8988$codep */
    9089namespace CppAD {
     
    106105
    107106$head CondExpRel$$
    108 The following macro invocation
     107The $cref/CPPAD_COND_EXP_REL/base_cond_exp/CondExpRel/$$ macro invocation
    109108$codep */
    110109namespace CppAD {
     
    217216/* $$
    218217
    219 $head Unary Standard Math$$
    220 The following macro invocations define unary standard math functions
    221 required to use $code AD< std::complex<double> >$$
    222 and that are valid with complex arguments:
     218$head Valid Unary Math$$
     219The following macro invocations define the standard unary
     220math functions that are valid with complex arguments and are
     221required to use $code AD< std::complex<double> >$$.
    223222$codep */
    224223namespace CppAD {
     
    232231}
    233232/* $$
    234 The following macro definition and invocations
    235 define unary standard math functions
    236 required to use $code AD< std::complex<double> >$$
    237 and that are invalid with complex arguments:
     233
     234$head Invalid Unary Math$$
     235The following macro definition and invocations define the standard unary
     236math functions that are invalid with complex arguments and are
     237required to use $code AD< std::complex<double> >$$.
    238238$codep */
    239239# undef  CPPAD_USER_MACRO
     
    252252        CPPAD_USER_MACRO(asin)
    253253        CPPAD_USER_MACRO(atan)
     254        CPPAD_USER_MACRO(sign)
    254255}
    255256/* $$
     
    358359        CPPAD_USER_MACRO_TWO(asin)
    359360        CPPAD_USER_MACRO_TWO(atan)
     361        CPPAD_USER_MACRO_TWO(sign)
    360362        // The pow function
    361363        inline std::complex<float> pow(
  • trunk/cppad/local/base_double.hpp

    r2057 r2240  
    4646
    4747$head CondExpOp$$
    48 The type $code double$$ is a relatively simple type
    49 that supports
    50 $code <$$, $code <=$$, $code ==$$, $code >=$$, and $code >$$ operators
    51 its $code CondExpOp$$ function is defined by
     48The type $code double$$ is a relatively simple type that supports
     49$code <$$, $code <=$$, $code ==$$, $code >=$$, and $code >$$ operators; see
     50$cref/ordered type/base_cond_exp/CondExpTemplate/Ordered Type/$$.
     51Hence its $code CondExpOp$$ function is defined by
    5252$codep */
    5353namespace CppAD {
     
    6464
    6565$head CondExpRel$$
    66 The following macro invocation
     66The $cref/CPPAD_COND_EXP_REL/base_cond_exp/CondExpRel/$$ macro invocation
    6767$codep */
    6868namespace CppAD {
     
    162162/* $$
    163163
     164$head sign$$
     165The following defines the $code CppAD::sign$$ function that
     166is required to use $code AD<double>$$:
     167$codep */
     168namespace CppAD {
     169        inline double sign(const double& x)
     170        {       if( x > 0. )
     171                        return 1.;
     172                if( x == 0. )
     173                        return 0.;
     174                return -1.;
     175        }
     176}
     177/* $$
     178
    164179$head pow $$
    165180The following defines a $code CppAD::pow$$ function that
  • trunk/cppad/local/base_float.hpp

    r2057 r2240  
    4646
    4747$head CondExpOp$$
    48 The type $code float$$ is a relatively simple type
    49 that supports
    50 $code <$$, $code <=$$, $code ==$$, $code >=$$, and $code >$$ operators
    51 its $code CondExpOp$$ function is defined by
     48The type $code float$$ is a relatively simple type that supports
     49$code <$$, $code <=$$, $code ==$$, $code >=$$, and $code >$$ operators; see
     50$cref/ordered type/base_cond_exp/CondExpTemplate/Ordered Type/$$.
     51Hence its $code CondExpOp$$ function is defined by
    5252$codep */
    5353namespace CppAD {
     
    6464
    6565$head CondExpRel$$
    66 The following macro invocation
     66The $cref/CPPAD_COND_EXP_REL/base_cond_exp/CondExpRel/$$ macro invocation
    6767$codep */
    6868namespace CppAD {
     
    163163/* $$
    164164
     165$head sign$$
     166The following defines the $code CppAD::sign$$ function that
     167is required to use $code AD<float>$$:
     168$codep */
     169namespace CppAD {
     170        inline float sign(const float& x)
     171        {       if( x > 0.f )
     172                        return 1.f;
     173                if( x == 0.f )
     174                        return 0.f;
     175                return -1.f;
     176        }
     177}
     178/* $$
     179 
    165180$head pow $$
    166181The following defines a $code CppAD::pow$$ function that
  • trunk/cppad/local/base_std_math.hpp

    r2057 r2240  
    8282$cref/float/base_float.hpp/Unary Standard Math/$$,
    8383$cref/double/base_double.hpp/Unary Standard Math/$$, and
    84 $cref/complex/base_complex.hpp/Unary Standard Math/$$.
     84$cref/complex valid unary math/base_complex.hpp/Valid Unary Math/$$.
     85
     86$head sign$$
     87$index sign, base require$$
     88$index base, sign require$$
     89$index require, base sign$$
     90The type $icode Base$$ must support the syntax
     91$codei%
     92        %y% = CppAD::sign(%x%)
     93%$$
     94which computes
     95$latex \[
     96z = \left\{ \begin{array}{ll}
     97        +1 & {\rm if} \; x > 0 \\
     98         0 & {\rm if} \; x = 0 \\
     99        -1 & {\rm if} \; x < 0
     100\end{array} \right.
     101\] $$
     102The arguments $icode x$$ has prototype
     103$codei%
     104        const %Base%& %x%
     105%$$
     106and the return value $icode z$$ has prototype
     107$codei%
     108        %Base% %z%
     109%$$
     110For example, see
     111$cref/float/base_float.hpp/sign/$$,
     112$cref/double/base_double.hpp/sign/$$.
     113Note that, if ordered comparisons are not defined for the type $icode Base$$,
     114the $code code sign$$ function should generate an assert if it is used; see
     115$cref/complex invalid unary math/base_complex.hpp/Invalid Unary Math/$$.
    85116
    86117$head pow$$
     
    98129        const %Base%& %y%
    99130%$$
    100 The return value $icode z$$ has prototype
     131and the return value $icode z$$ has prototype
    101132$codei%
    102133        %Base% %z%
     
    106137$cref/double/base_double.hpp/pow/$$, and
    107138$cref/complex/base_complex.hpp/pow/$$.
    108 
    109139
    110140$end
  • trunk/cppad/local/cond_exp.hpp

    r2120 r2240  
    6060$codei%
    6161        %Rel%   Lt   Le   Eq   Ge   Gt
    62         %Cop%    <   <=   ==    >   >=
     62        %Cop%    <   <=   ==   >=   >
    6363%$$
    6464If $icode f$$ is the $cref ADFun$$ object corresponding to the
  • trunk/cppad/local/for_jac_sweep.hpp

    r2114 r2240  
    386386                        case PriOp:
    387387                        CPPAD_ASSERT_NARG_NRES(op, 5, 0);
     388                        break;
     389                        // -------------------------------------------------
     390
     391                        case SignOp:
     392                        CPPAD_ASSERT_NARG_NRES(op, 1, 1);
     393                        forward_sparse_jacobian_unary_op(
     394                                i_var, arg[0], var_sparsity
     395                        );
    388396                        break;
    389397                        // -------------------------------------------------
  • trunk/cppad/local/forward0sweep.hpp

    r2057 r2240  
    383383                                i_var, arg, num_text, text, num_par, parameter, J, Taylor
    384384                        );
     385                        break;
     386                        // -------------------------------------------------
     387
     388                        case SignOp:
     389                        // cos(x), sin(x)
     390                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
     391                        forward_sign_op_0(i_var, arg[0], J, Taylor);
    385392                        break;
    386393                        // -------------------------------------------------
  • trunk/cppad/local/forward_sweep.hpp

    r2114 r2240  
    425425                        break;
    426426                        // -------------------------------------------------
     427
     428                        case SignOp:
     429                        // cos(x), sin(x)
     430                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
     431                        forward_sign_op(d, i_var, arg[0], J, Taylor);
     432                        break;
    427433
    428434                        case SinOp:
  • trunk/cppad/local/math_other.hpp

    r2057 r2240  
    2727$childtable%
    2828        cppad/local/abs.hpp%
     29        cppad/local/sign.hpp%
    2930        cppad/local/atan2.hpp%
    3031        cppad/local/epsilon.hpp%
     
    3738
    3839# include <cppad/local/abs.hpp>
     40# include <cppad/local/sign.hpp>
    3941# include <cppad/local/atan2.hpp>
    4042# include <cppad/local/epsilon.hpp>
  • trunk/cppad/local/op.hpp

    r2031 r2240  
    3939# include <cppad/local/pow_op.hpp>
    4040# include <cppad/local/print_op.hpp>
     41# include <cppad/local/sign_op.hpp>
    4142# include <cppad/local/sin_op.hpp>
    4243# include <cppad/local/sinh_op.hpp>
  • trunk/cppad/local/op_code.hpp

    r2082 r2240  
    5656        CExpOp,   // CondExp(cop, left, right, trueCase, falseCase)
    5757        ComOp,    // Compare(cop, result, left, right)
     58        CosOp,    //  cos(variable)
    5859        CoshOp,   // cosh(variable)
    59         CosOp,    //  cos(variable)
    6060        CSumOp,   // Cummulative summation (has variable number of arguments)
    6161        DisOp,    //  discrete::eval(index, variable)
     
    7676        PowvvOp,  //  pow(variable,    variable)
    7777        PriOp,    //  PrintFor(text, parameter or variable, parameter or variable)
     78        SignOp,   // sign(variable)
     79        SinOp,    //  sin(variable)
    7880        SinhOp,   // sinh(variable)
    79         SinOp,    //  sin(variable)
    8081        SqrtOp,   // sqrt(variable)
    8182        StppOp,   //    z[parameter] = parameter
     
    8687        SubvpOp,  //      variable   - parameter
    8788        SubvvOp,  //      variable   - variable
     89        TanOp,    //  tan(variable)
    8890        TanhOp,   //  tan(variable)
    89         TanOp,    //  tan(variable)
    9091        // user atomic operation codes (note yet implemented)
    9192        UserOp,   //  start of a user atomic operaiton
     
    120121        6, // CExpOp
    121122        4, // ComOp
     123        1, // CosOp
    122124        1, // CoshOp
    123         1, // CosOp
    124125        0, // CSumOp   (actually has a variable number of arguments, not zero)
    125126        2, // DisOp
     
    140141        2, // PowvvOp
    141142        5, // PriOp
     143        1, // SignOp
     144        1, // SinOp
    142145        1, // SinhOp
    143         1, // SinOp
    144146        1, // SqrtOp
    145147        3, // StppOp
     
    150152        2, // SubvpOp
    151153        2, // SubvvOp
     154        1, // TanOp
    152155        1, // TanhOp
    153         1, // TanOp
    154156        4, // UserOp
    155157        1, // UsrapOp
     
    217219        1, // CExpOp
    218220        0, // ComOp
     221        2, // CosOp
    219222        2, // CoshOp
    220         2, // CosOp
    221223        1, // CSumOp
    222224        1, // DisOp
     
    237239        3, // PowvvOp
    238240        0, // PriOp
     241        1, // SignOp
     242        2, // SinOp
    239243        2, // SinhOp
    240         2, // SinOp
    241244        1, // SqrtOp
    242245        0, // StppOp
     
    247250        1, // SubvpOp
    248251        1, // SubvvOp
     252        2, // TanOp
    249253        2, // TanhOp
    250         2, // TanOp
    251254        0, // UserOp
    252255        0, // UsrapOp
     
    394397        size_t                 i_var  ,
    395398        OpCode                 op     ,
    396         const size_t          *ind    ,
     399        const addr_t          *ind    ,
    397400        size_t                 nfz    ,
    398401        const  Value          *fz     ,
     
    417420                "CExp"  ,
    418421                "Com"   ,
     422                "Cos"   ,
    419423                "Cosh"  ,
    420                 "Cos"   ,
    421424                "CSum"  ,
    422425                "Dis"   ,
     
    437440                "Powvv" ,
    438441                "Pri"   ,
     442                "Sign"  ,
     443                "Sin"   ,
    439444                "Sinh"  ,
    440                 "Sin"   ,
    441445                "Sqrt"  ,
    442446                "Stpp"  ,
     
    447451                "Subvp" ,
    448452                "Subvv" ,
     453                "Tan"   ,
    449454                "Tanh"  ,
    450                 "Tan"   ,
    451455                "User"  ,
    452456                "Usrap" ,
     
    568572                case ExpOp:
    569573                case LogOp:
     574                case SignOp:
    570575                case SinOp:
    571576                case SinhOp:
    572577                case SqrtOp:
    573578                case UsravOp:
     579                case TanOp:
    574580                case TanhOp:
    575                 case TanOp:
    576581                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
    577582                printOpField(os, "  v=", ind[0], ncol);
  • trunk/cppad/local/rev_hes_sweep.hpp

    r2038 r2240  
    308308                        case DisOp:
    309309                        CPPAD_ASSERT_NARG_NRES(op, 2, 1)
    310 
     310                        // derivativve is identically zero
    311311                        break;
    312312                        // -------------------------------------------------
     
    436436                        case PriOp:
    437437                        CPPAD_ASSERT_NARG_NRES(op, 5, 0);
     438                        break;
     439                        // -------------------------------------------------
     440
     441                        case SignOp:
     442                        CPPAD_ASSERT_NARG_NRES(op, 1, 1);
     443                        // Derivative is identiaclly zero
    438444                        break;
    439445                        // -------------------------------------------------
  • trunk/cppad/local/rev_jac_sweep.hpp

    r2038 r2240  
    270270                        case DisOp:
    271271                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
    272 
     272                        // derivative is identically zero
    273273                        break;
    274274                        // -------------------------------------------------
     
    392392                        case PriOp:
    393393                        CPPAD_ASSERT_NARG_NRES(op, 5, 0);
     394                        break;
     395                        // -------------------------------------------------
     396
     397                        case SignOp:
     398                        CPPAD_ASSERT_NARG_NRES(op, 1, 1);
     399                        // derivative is identically zero
    394400                        break;
    395401                        // -------------------------------------------------
  • trunk/cppad/local/reverse_sweep.hpp

    r2037 r2240  
    424424                        // --------------------------------------------------
    425425
     426                        case SignOp:
     427                        CPPAD_ASSERT_UNKNOWN( i_var < numvar );
     428                        reverse_sign_op(
     429                                d, i_var, arg[0], J, Taylor, K, Partial
     430                        );
     431                        break;
     432                        // -------------------------------------------------
     433
    426434                        case SinOp:
    427435                        CPPAD_ASSERT_UNKNOWN( i_var < numvar );
  • trunk/example/abs.cpp

    r1370 r2240  
    11/* $Id$ */
    22/* --------------------------------------------------------------------------
    3 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-07 Bradley M. Bell
     3CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-11 Bradley M. Bell
    44
    55CppAD is distributed under multiple licenses. This distribution is under
     
    1212
    1313/*
    14 $begin Abs.cpp$$
     14$begin abs.cpp$$
    1515$spell
    1616        abs
     
    3535# include <cppad/cppad.hpp>
    3636
    37 bool Abs(void)
     37bool abs(void)
    3838{       bool ok = true;
    3939
     
    6767        // forward computation of partials w.r.t. a positive x[0] direction
    6868        size_t p = 1;
    69         CPPAD_TEST_VECTOR<double> dx(n);
    70         CPPAD_TEST_VECTOR<double> dy(m);
     69        CPPAD_TEST_VECTOR<double> dx(n), dy(m);
    7170        dx[0] = 1.;
    7271        dy    = f.Forward(p, dx);
    7372        ok  &= (dy[0] == - dx[0]);
    74         ok  &= (dy[1] == + dx[0]);
     73        ok  &= (dy[1] ==   0.   ); // used to be ok  &= (dy[1] == + dx[0]);
    7574        ok  &= (dy[2] == + dx[0]);
    7675
     
    7978        dy    = f.Forward(p, dx);
    8079        ok  &= (dy[0] == - dx[0]);
    81         ok  &= (dy[1] == - dx[0]);
     80        ok  &= (dy[1] ==   0.   ); // used to be ok  &= (dy[1] == - dx[0]);
    8281        ok  &= (dy[2] == + dx[0]);
    8382
    8483        // reverse computation of derivative of y[0]
    85         p    = 0;
    86         CPPAD_TEST_VECTOR<double>  w(m);
    87         CPPAD_TEST_VECTOR<double> dw(n);
     84        p    = 1;
     85        CPPAD_TEST_VECTOR<double>  w(m), dw(n);
    8886        w[0] = 1.; w[1] = 0.; w[2] = 0.;
    89         dw   = f.Reverse(p+1, w);
     87        dw   = f.Reverse(p, w);
    9088        ok  &= (dw[0] == -1.);
    9189
    9290        // reverse computation of derivative of y[1]
    9391        w[0] = 0.; w[1] = 1.; w[2] = 0.;
    94         dw   = f.Reverse(p+1, w);
     92        dw   = f.Reverse(p, w);
    9593        ok  &= (dw[0] == 0.);
    9694
    9795        // reverse computation of derivative of y[2]
    9896        w[0] = 0.; w[1] = 0.; w[2] = 1.;
    99         dw   = f.Reverse(p+1, w);
     97        dw   = f.Reverse(p, w);
    10098        ok  &= (dw[0] == 1.);
    10199
  • trunk/example/base_adolc.hpp

    r2057 r2240  
    1515$begin base_adolc.hpp$$
    1616$spell
     17        Rel
     18        codassign
    1719        eps
    1820        std
     
    130132                        condassign(result, left - right, trueCase, falseCase);
    131133                        break;
    132 
    133134                        default:
    134135                        CppAD::ErrorHandler::Call(
     
    197198$head Ordered$$
    198199$codep */
     200namespace CppAD {
    199201        inline bool GreaterThanZero(const adouble &x)
    200202        {    return (x > 0); }
     
    207209        inline bool abs_geq(const adouble& x, const adouble& y)
    208210        {       return fabs(x) >= fabs(y); }
     211}
    209212/* $$
    210213
     
    214217$pre
    215218$$
    216 $code abs$$,
    217219$code acos$$,
    218220$code asin$$,
     
    227229$code tan$$.
    228230
     231$head sign$$
     232This $cref/required/base_require/$$ function is defined using the
     233$code codassign$$ function so that its $code adouble$$ operation sequence
     234does not depend on the value of $icode x$$.
     235$codep */
     236namespace CppAD {
     237        inline adouble sign(const adouble& x)
     238        {       adouble s_plus, s_minus;
     239                // set s_plus to sign(x)/2,  except for case x == 0, s_plus = -.5
     240                condassign(s_plus,  +x, -.5, .5);
     241                // set s_minus to -sign(x)/2, except for case x == 0, s_minus = -.5
     242                condassign(s_minus, -x, -.5, .5);
     243                // set s to sign(x)
     244                return s_plus - s_minus;
     245        }
     246}
     247/* $$
     248
     249$head abs$$
     250This $cref/required/base_require/$$ function uses the adolc $code fabs$$
     251function:
     252$codep */
     253namespace CppAD {
     254        inline adouble abs(const adouble& x)
     255        {       return fabs(x); }
     256}
     257/* $$
     258
    229259$head pow$$
    230260This $cref/required/base_require/$$ function
  • trunk/example/example.cpp

    r2178 r2240  
    5454// external complied tests
    5555extern bool abort_recording(void);
    56 extern bool Abs(void);
     56extern bool abs(void);
    5757extern bool Acos(void);
    5858extern bool Add(void);
     
    154154extern bool runge_45_2(void);
    155155extern bool seq_property(void);
     156extern bool sign(void);
    156157extern bool SimpleVector(void);
    157158extern bool Sin(void);
     
    207208        // external compiled tests
    208209        ok &= Run( abort_recording,   "abort_recording"  );
    209         ok &= Run( Abs,               "Abs"              );
     210        ok &= Run( abs,               "abs"              );
    210211        ok &= Run( Acos,              "Acos"             );
    211212        ok &= Run( Add,               "Add"              );
     
    304305        ok &= Run( runge_45_2,        "runge_45_2"       );
    305306        ok &= Run( seq_property,      "seq_property"     );
     307        ok &= Run( sign,              "sign"             );
    306308        ok &= Run( SimpleVector,      "SimpleVector"     );
    307309        ok &= Run( Sin,               "Sin"              );
  • trunk/example/example.vcproj

    r2091 r2240  
    583583                        </File>
    584584                        <File
     585                                RelativePath=".\sign.cpp"
     586                                >
     587                        </File>
     588                        <File
    585589                                RelativePath=".\simple_vector.cpp"
    586590                                >
  • trunk/example/makefile.am

    r2233 r2240  
    165165        seq_property.cpp \
    166166        simple_vector.cpp \
     167        sign.cpp \
    167168        sin.cpp \
    168169        sinh.cpp \
  • trunk/example/makefile.in

    r2233 r2240  
    7070        rev_sparse_jac.cpp rev_two.cpp romberg_mul.cpp romberg_one.cpp \
    7171        rosen_34.cpp runge_45_1.cpp runge_45_2.cpp seq_property.cpp \
    72         simple_vector.cpp sin.cpp sinh.cpp sparse_hessian.cpp \
     72        simple_vector.cpp sign.cpp sin.cpp sinh.cpp sparse_hessian.cpp \
    7373        sparse_jacobian.cpp sqrt.cpp stack_machine.cpp sub.cpp \
    7474        sub_eq.cpp tan.cpp tanh.cpp tape_index.cpp thread_alloc.cpp \
     
    117117        rev_two.$(OBJEXT) romberg_mul.$(OBJEXT) romberg_one.$(OBJEXT) \
    118118        rosen_34.$(OBJEXT) runge_45_1.$(OBJEXT) runge_45_2.$(OBJEXT) \
    119         seq_property.$(OBJEXT) simple_vector.$(OBJEXT) sin.$(OBJEXT) \
    120         sinh.$(OBJEXT) sparse_hessian.$(OBJEXT) \
     119        seq_property.$(OBJEXT) simple_vector.$(OBJEXT) sign.$(OBJEXT) \
     120        sin.$(OBJEXT) sinh.$(OBJEXT) sparse_hessian.$(OBJEXT) \
    121121        sparse_jacobian.$(OBJEXT) sqrt.$(OBJEXT) \
    122122        stack_machine.$(OBJEXT) sub.$(OBJEXT) sub_eq.$(OBJEXT) \
     
    427427        seq_property.cpp \
    428428        simple_vector.cpp \
     429        sign.cpp \
    429430        sin.cpp \
    430431        sinh.cpp \
     
    597598@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/runge_45_2.Po@am__quote@
    598599@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seq_property.Po@am__quote@
     600@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sign.Po@am__quote@
    599601@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple_vector.Po@am__quote@
    600602@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sin.Po@am__quote@
  • trunk/makefile.am

    r2200 r2240  
    213213        cppad/local/rev_sparse_jac.hpp \
    214214        cppad/local/rev_two.hpp \
     215        cppad/local/sign.hpp \
     216        cppad/local/sign_op.hpp \
     217        cppad/local/sin_op.hpp \
    215218        cppad/local/sinh_op.hpp \
    216         cppad/local/sin_op.hpp \
    217219        cppad/local/sparse_binary_op.hpp \
    218220        cppad/local/sparse_hessian.hpp \
  • trunk/makefile.in

    r2200 r2240  
    461461        cppad/local/rev_sparse_jac.hpp \
    462462        cppad/local/rev_two.hpp \
     463        cppad/local/sign.hpp \
     464        cppad/local/sign_op.hpp \
     465        cppad/local/sin_op.hpp \
    463466        cppad/local/sinh_op.hpp \
    464         cppad/local/sin_op.hpp \
    465467        cppad/local/sparse_binary_op.hpp \
    466468        cppad/local/sparse_hessian.hpp \
  • trunk/test_more/abs.cpp

    r1370 r2240  
    11/* $Id$ */
    22/* --------------------------------------------------------------------------
    3 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-07 Bradley M. Bell
     3CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-11 Bradley M. Bell
    44
    55CppAD is distributed under multiple licenses. This distribution is under
     
    1818
    1919
    20 bool Abs(void)
    21 {       // test if CppAD::abs uses if statement for value computations
     20bool abs(void)
     21{       // test if CppAD::abs uses if statement during forward computations
    2222        bool ok = true;
    2323
     
    2727        typedef CppAD::AD< ADdouble > ADDdouble;
    2828
    29         CPPAD_TEST_VECTOR< ADdouble > u(1);
    30         u[0] = double(0);
    31         Independent(u);
     29        // af(x) = |x|
     30        CPPAD_TEST_VECTOR< ADDdouble > aax(1), aay(1);
     31        aax[0] = ADDdouble(0.);
     32        CppAD::Independent(aax);
     33        aay[0] = CppAD::abs(aax[0]);
     34        CppAD::ADFun< ADdouble > af(aax, aay);
    3235
    33         CPPAD_TEST_VECTOR< ADDdouble > v(1);
    34         v[0] = ADDdouble(u[0]);
    35         CppAD::Independent(v);
     36        // f(x) = |x|
     37        CPPAD_TEST_VECTOR< ADdouble > ax(1), ay(1);
     38        ax[0] = ADdouble(0.);
     39        CppAD::Independent(ax);
     40        ay    = af.Forward(0, ax);
     41        CppAD::ADFun<double> f(ax, ay);
    3642
    37         CPPAD_TEST_VECTOR< ADDdouble > w(1);
    38         w[0] = CppAD::abs(v[0]);
     43        // compute derivative of af at a positive argument
     44        CPPAD_TEST_VECTOR< ADdouble > adx(1), ady(1);
     45        ax[0]  = 1.;
     46        ay     = af.Forward(0, ax);
     47        adx[0] = 1;
     48        ady    = af.Forward(1, adx);
     49        ok    &= (ady[0] == 1.);
    3950
    40         // f(v) = |w|
    41         CppAD::ADFun< ADdouble > f(v, w);
     51        // compute derivative of af at a zero argument
     52        ax[0]  = 0.;
     53        ay     = af.Forward(0, ax);
     54        adx[0] = 1;
     55        ady    = af.Forward(1, adx);
     56        ok    &= (ady[0] == 0.);
    4257
    43         // extract the value of w
    44         CPPAD_TEST_VECTOR< ADdouble > x(1);
    45         x[0] = CppAD::Value(w[0]);
    46        
    47         // g(u) = |u|
    48         CppAD::ADFun<double> g(u, x);
     58        // compute derivative of f at zero argument
     59        CPPAD_TEST_VECTOR<double> x(1), y(1), dx(1), dy(1);
     60        x[0]  = 0.;
     61        y     = f.Forward(0, x);
     62        dx[0] = 1;
     63        dy    = f.Forward(1, dx);
     64        ok    &= (dy[0] == 0.);
    4965
    50         // compute direction derivative of f at zero in positive direction
    51         CPPAD_TEST_VECTOR< ADdouble > dv(1);
    52         CPPAD_TEST_VECTOR< ADdouble > dw(1);
    53         dv[0] = 1;
    54         dw    = f.Forward(1, dv);
    55         ok   &= (dw[0] == 1);
    56 
    57         // compute direction derivative of g at zero in positive direction
    58         CPPAD_TEST_VECTOR<double> du(1);
    59         CPPAD_TEST_VECTOR<double> dx(1);
    60         du[0] = 1;
    61         dx    = g.Forward(1, du);
    62         ok   &= (dx[0] == 1);
     66        // compute derivative of af at a negative argument
     67        x[0]  = -1.;
     68        y     = f.Forward(0, x);
     69        dx[0] = 1;
     70        dy    = f.Forward(1, dx);
     71        ok    &= (dy[0] == -1.);
    6372
    6473        return ok;
  • trunk/test_more/test_more.cpp

    r2057 r2240  
    1818
    1919// various examples / tests
    20 extern bool Abs(void);
     20extern bool abs(void);
    2121extern bool Acos(void);
    2222extern bool Add(void);
     
    121121        // This line is used by test_one.sh
    122122
    123         ok &= Run( Abs,             "Abs"            );
     123        ok &= Run( abs,             "abs"            );
    124124        ok &= Run( Acos,            "Acos"           );
    125125        ok &= Run( Add,             "Add"            );
Note: See TracChangeset for help on using the changeset viewer.