,
cppad-20100902: A Package for Differentiation of C++ Algorithms
One web page per Section    All as one web page
(fast to load)    (slow to load)
Math displayed using Latex    cppad.htm    _printable.htm
Math displayed using MathML    cppad.xml    _printable.xml

a: Syntax
# include <cppad/cppad.hpp>


b: Introduction
We refer to the step by step conversion from an algorithm that computes function values to an algorithm that computes derivative values as Algorithmic Differentiation (often referred to as Automatic Differentiation.) Given a C++ algorithm that computes function values, CppAD generates an algorithm that computes its derivative values. A brief introduction to Algorithmic Differentiation can be found in wikipedia (http://en.wikipedia.org/wiki/Automatic_differentiation) . The web site autodiff.org (http://www.autodiff.org) is dedicated to research about, and promoting the use of, AD.
  1. CppAD (http://www.coin-or.org/CppAD/) uses operator overloading to compute derivatives of algorithms defined in C++. It is distributed by the COIN-OR Foundation (http://www.coin-or.org/foundation.html) with the Common Public License CPL (http://www.opensource.org/licenses/cpl1.0.php) or the GNU General Public License GPL (http://www.opensource.org/licenses/gpl-license.php) . Installation procedures are provided for both 2.1: Unix and 2.2: MS Windows operating systems. Extensive user and developer documentation is included.
  2. An AD of Base 9.4.g.b: operation sequence is stored as an 5: AD function object which can evaluate function values and derivatives. Arbitrary order 5.6.1: forward and 5.6.2: reverse mode derivative calculations can be preformed on the operation sequence. Logical comparisons can be included in an operation sequence using AD 4.4.4: conditional expressions . Evaluation of user defined unary 4.4.5: discrete functions can also be included in the sequence of operations; i.e., functions that depend on the 9.4.j.c: independent variables but which have identically zero derivatives (e.g., a step function).
  3. Derivatives of functions that are defined in terms of other derivatives can be computed using multiple levels of AD; see 7.1.9.1: mul_level.cpp for a simple example and 7.1.11: ode_taylor.cpp for a more realistic example. To this end, CppAD can also be used with other AD types; for example see 7.1.12: ode_taylor_adolc.cpp .
  4. A set of programs for doing 9.2: speed comparisons between Adolc (http://www.math.tu-dresden.de/~adol-c/) , CppAD, Fadbad (http://www.imm.dtu.dk/fadbad.html/) , and Sacado (http://trilinos.sandia.gov/packages/sacado/) are included.
  5. Includes a C++ 6: library that is useful for general operator overloaded numerical method. Allows for replacement of the 7.4: test_vector template vector class which is used for extensive testing; for example, you can do your testing with the uBlas (http://www.boost.org/libs/numeric/ublas/doc/index.htm) template vector class.
  6. See 9.8: whats_new for a list of recent extensions and bug fixes.
You can find out about other algorithmic differentiation tools and about algorithmic differentiation in general at the following web sites: wikipedia (http://en.wikipedia.org/wiki/Automatic_differentiation) , autodiff.org (http://www.autodiff.org) .

c: Example
The file 3.1: get_started.cpp contains an example and test of using CppAD to compute the derivative of a polynomial. There are many other 7: examples .

d: Include File
The following include directive
     # include <cppad/cppad.hpp>
includes the CppAD package for the rest of the current compilation unit.

e: Preprocessor Symbols
All the preprocessor symbols used by CppAD begin with eight CppAD or CPPAD_; see 8: configure for the few exceptions to this rule.

f: Namespace
All of the functions and objects defined by CppAD are in the CppAD namespace; for example, you can access the 4: AD types as
     size_t n = 2;
     CppAD::vector< CppAD::AD<
Base> > x(n)
You can abbreviate access to one object or function a using command of the form
     using CppAD::AD
     CppAD::vector< AD<
Base> > x(n)
You can abbreviate access to all CppAD objects and functions with a command of the form
     using namespace CppAD
     vector< AD<
Base> > x(n)
If you include other namespaces in a similar manner, this can cause naming conflicts.

g: Contents
_contents: 1Table of Contents
Install: 2CppAD Download, Test, and Installation Instructions
Introduction: 3An Introduction by Example to Algorithmic Differentiation
AD: 4AD Objects
ADFun: 5ADFun Objects
library: 6The CppAD General Purpose Library
Example: 7Examples
configure: 8Preprocessor Definitions Used by CppAD
Appendix: 9Appendix
_reference: 10Alphabetic Listing of Cross Reference Tags
_index: 11Keyword Index
_external: 12External Internet References

% --------------------------------------------------------------------
% Latex macros defined here and used throughout the CppAD documentation
\newcommand{\T}{ {\rm T} }
\newcommand{\R}{ {\bf R} }
\newcommand{\C}{ {\bf C} }
\newcommand{\D}[2]{ \frac{\partial #1}{\partial #2} }
\newcommand{\DD}[3]{ \frac{\partial^2 #1}{\partial #2 \partial #3} }
\newcommand{\Dpow}[2]{ \frac{\partial^{#1}}{\partial  {#2}^{#1}} }
\newcommand{\dpow}[2]{ \frac{ {\rm d}^{#1}}{{\rm d}\, {#2}^{#1}} }

Input File: doc.omh
1: Table of Contents
cppad-20100902: A Package for Differentiation of C++ Algorithms: : CppAD
    Table of Contents: 1: _contents
    CppAD Download, Test, and Installation Instructions: 2: Install
        Unix Download, Test and Installation: 2.1: InstallUnix
            Using Subversion To Download Source Code: 2.1.1: subversion
        Windows Download and Test: 2.2: InstallWindows
    An Introduction by Example to Algorithmic Differentiation: 3: Introduction
        A Simple Program Using CppAD to Compute Derivatives: 3.1: get_started.cpp
        Second Order Exponential Approximation: 3.2: exp_2
            exp_2: Implementation: 3.2.1: exp_2.hpp
            exp_2: Test: 3.2.2: exp_2.cpp
            exp_2: Operation Sequence and Zero Order Forward Mode: 3.2.3: exp_2_for0
                exp_2: Verify Zero Order Forward Sweep: 3.2.3.1: exp_2_for0.cpp
            exp_2: First Order Forward Mode: 3.2.4: exp_2_for1
                exp_2: Verify First Order Forward Sweep: 3.2.4.1: exp_2_for1.cpp
            exp_2: First Order Reverse Mode: 3.2.5: exp_2_rev1
                exp_2: Verify First Order Reverse Sweep: 3.2.5.1: exp_2_rev1.cpp
            exp_2: Second Order Forward Mode: 3.2.6: exp_2_for2
                exp_2: Verify Second Order Forward Sweep: 3.2.6.1: exp_2_for2.cpp
            exp_2: Second Order Reverse Mode: 3.2.7: exp_2_rev2
                exp_2: Verify Second Order Reverse Sweep: 3.2.7.1: exp_2_rev2.cpp
            exp_2: CppAD Forward and Reverse Sweeps: 3.2.8: exp_2_cppad
        An Epsilon Accurate Exponential Approximation: 3.3: exp_eps
            exp_eps: Implementation: 3.3.1: exp_eps.hpp
            exp_eps: Test of exp_eps: 3.3.2: exp_eps.cpp
            exp_eps: Operation Sequence and Zero Order Forward Sweep: 3.3.3: exp_eps_for0
                exp_eps: Verify Zero Order Forward Sweep: 3.3.3.1: exp_eps_for0.cpp
            exp_eps: First Order Forward Sweep: 3.3.4: exp_eps_for1
                exp_eps: Verify First Order Forward Sweep: 3.3.4.1: exp_eps_for1.cpp
            exp_eps: First Order Reverse Sweep: 3.3.5: exp_eps_rev1
                exp_eps: Verify First Order Reverse Sweep: 3.3.5.1: exp_eps_rev1.cpp
            exp_eps: Second Order Forward Mode: 3.3.6: exp_eps_for2
                exp_eps: Verify Second Order Forward Sweep: 3.3.6.1: exp_eps_for2.cpp
            exp_eps: Second Order Reverse Sweep: 3.3.7: exp_eps_rev2
                exp_eps: Verify Second Order Reverse Sweep: 3.3.7.1: exp_eps_rev2.cpp
            exp_eps: CppAD Forward and Reverse Sweeps: 3.3.8: exp_eps_cppad
        Run the exp_2 and exp_eps Tests: 3.4: exp_apx_main.cpp
    AD Objects: 4: AD
        AD Default Constructor: 4.1: Default
            Default AD Constructor: Example and Test: 4.1.1: Default.cpp
        AD Copy Constructor and Assignment Operator: 4.2: ad_copy
            AD Copy Constructor: Example and Test: 4.2.1: CopyAD.cpp
            AD Constructor From Base Type: Example and Test: 4.2.2: CopyBase.cpp
            AD Assignment Operator: Example and Test: 4.2.3: Eq.cpp
        Conversion and Printing of AD Objects: 4.3: Convert
            Convert From an AD Type to its Base Type: 4.3.1: Value
                Convert From AD to its Base Type: Example and Test: 4.3.1.1: Value.cpp
            Convert From AD to Integer: 4.3.2: Integer
                Convert From AD to Integer: Example and Test: 4.3.2.1: Integer.cpp
            AD Output Stream Operator: 4.3.3: Output
                AD Output Operator: Example and Test: 4.3.3.1: Output.cpp
            Printing AD Values During Forward Mode: 4.3.4: PrintFor
                Printing During Forward Mode: Example and Test: 4.3.4.1: PrintFor.cpp
            Convert an AD Variable to a Parameter: 4.3.5: Var2Par
                Convert an AD Variable to a Parameter: Example and Test: 4.3.5.1: Var2Par.cpp
        AD Valued Operations and Functions: 4.4: ADValued
            AD Arithmetic Operators and Computed Assignments: 4.4.1: Arithmetic
                AD Unary Plus Operator: 4.4.1.1: UnaryPlus
                    AD Unary Plus Operator: Example and Test: 4.4.1.1.1: UnaryPlus.cpp
                AD Unary Minus Operator: 4.4.1.2: UnaryMinus
                    AD Unary Minus Operator: Example and Test: 4.4.1.2.1: UnaryMinus.cpp
                AD Binary Arithmetic Operators: 4.4.1.3: ad_binary
                    AD Binary Addition: Example and Test: 4.4.1.3.1: Add.cpp
                    AD Binary Subtraction: Example and Test: 4.4.1.3.2: Sub.cpp
                    AD Binary Multiplication: Example and Test: 4.4.1.3.3: Mul.cpp
                    AD Binary Division: Example and Test: 4.4.1.3.4: Div.cpp
                AD Computed Assignment Operators: 4.4.1.4: compute_assign
                    AD Computed Assignment Addition: Example and Test: 4.4.1.4.1: AddEq.cpp
                    AD Computed Assignment Subtraction: Example and Test: 4.4.1.4.2: SubEq.cpp
                    AD Computed Assignment Multiplication: Example and Test: 4.4.1.4.3: MulEq.cpp
                    AD Computed Assignment Division: Example and Test: 4.4.1.4.4: DivEq.cpp
            AD Standard Math Unary Functions: 4.4.2: std_math_ad
                The AD acos Function: Example and Test: 4.4.2.1: Acos.cpp
                The AD asin Function: Example and Test: 4.4.2.2: Asin.cpp
                The AD atan Function: Example and Test: 4.4.2.3: Atan.cpp
                The AD cos Function: Example and Test: 4.4.2.4: Cos.cpp
                The AD cosh Function: Example and Test: 4.4.2.5: Cosh.cpp
                The AD exp Function: Example and Test: 4.4.2.6: Exp.cpp
                The AD log Function: Example and Test: 4.4.2.7: Log.cpp
                The AD log10 Function: Example and Test: 4.4.2.8: Log10.cpp
                The AD sin Function: Example and Test: 4.4.2.9: Sin.cpp
                The AD sinh Function: Example and Test: 4.4.2.10: Sinh.cpp
                The AD sqrt Function: Example and Test: 4.4.2.11: Sqrt.cpp
                The AD tan Function: Example and Test: 4.4.2.12: Tan.cpp
                The AD tanh Function: Example and Test: 4.4.2.13: Tanh.cpp
            Other AD Math Functions: 4.4.3: MathOther
                AD Absolute Value Function: 4.4.3.1: abs
                    AD Absolute Value Function: Example and Test: 4.4.3.1.1: Abs.cpp
                AD Two Argument Inverse Tangent Function: 4.4.3.2: atan2
                    The AD atan2 Function: Example and Test: 4.4.3.2.1: Atan2.cpp
                The AD Error Function: 4.4.3.3: erf
                    The AD erf Function: Example and Test: 4.4.3.3.1: Erf.cpp
                The AD Power Function: 4.4.3.4: pow
                    The AD Power Function: Example and Test: 4.4.3.4.1: Pow.cpp
                    The Pow Integer Exponent: Example and Test: 4.4.3.4.2: pow_int.cpp
            AD Conditional Expressions: 4.4.4: CondExp
                Conditional Expressions: Example and Test: 4.4.4.1: CondExp.cpp
            Discrete AD Functions: 4.4.5: Discrete
                Taping Array Index Operation: Example and Test: 4.4.5.1: TapeIndex.cpp
                Interpolation With Out Retaping: Example and Test: 4.4.5.2: interp_onetape.cpp
                Interpolation With Retaping: Example and Test: 4.4.5.3: interp_retape.cpp
        Bool Valued Operations and Functions with AD Arguments: 4.5: BoolValued
            AD Binary Comparison Operators: 4.5.1: Compare
                AD Binary Comparison Operators: Example and Test: 4.5.1.1: Compare.cpp
            Compare AD and Base Objects for Nearly Equal: 4.5.2: NearEqualExt
                Compare AD with Base Objects: Example and Test: 4.5.2.1: NearEqualExt.cpp
            AD Boolean Functions: 4.5.3: BoolFun
                AD Boolean Functions: Example and Test: 4.5.3.1: BoolFun.cpp
            Is an AD Object a Parameter or Variable: 4.5.4: ParVar
                AD Parameter and Variable Functions: Example and Test: 4.5.4.1: ParVar.cpp
            Check if Equal and Correspond to Same Operation Sequence: 4.5.5: EqualOpSeq
                EqualOpSeq: Example and Test: 4.5.5.1: EqualOpSeq.cpp
        AD Vectors that Record Index Operations: 4.6: VecAD
            AD Vectors that Record Index Operations: Example and Test: 4.6.1: vec_ad.cpp
        AD<Base> Requirements for Base Type: 4.7: base_require
            Enable use of AD<Base> where Base is std::complex<double>: 4.7.1: base_complex.hpp
                Complex Polynomial: Example and Test: 4.7.1.1: ComplexPoly.cpp
                Not Complex Differentiable: Example and Test: 4.7.1.2: not_complex_ad.cpp
            Enable use of AD<Base> where Base is Adolc's adouble Type: 4.7.2: base_adolc.hpp
                Using Adolc with Multiple Levels of Taping: Example and Test: 4.7.2.1: mul_level_adolc.cpp
    ADFun Objects: 5: ADFun
        Declare Independent Variables and Start Recording: 5.1: Independent
            Independent and ADFun Constructor: Example and Test: 5.1.1: Independent.cpp
        Construct an ADFun Object and Stop Recording: 5.2: FunConstruct
            ADFun Assignment: Example and Test: 5.2.1: fun_assign.cpp
        Stop Recording and Store Operation Sequence: 5.3: Dependent
        Abort Recording of an Operation Sequence: 5.4: abort_recording
            Abort Current Recording: Example and Test: 5.4.1: abort_recording.cpp
        ADFun Sequence Properties: 5.5: seq_property
            ADFun Sequence Properties: Example and Test: 5.5.1: seq_property.cpp
        Evaluate ADFun Functions, Derivatives, and Sparsity Patterns: 5.6: FunEval
            Forward Mode: 5.6.1: Forward
                Zero Order Forward Mode: Function Values: 5.6.1.1: ForwardZero
                First Order Forward Mode: Derivative Values: 5.6.1.2: ForwardOne
                Any Order Forward Mode: 5.6.1.3: ForwardAny
                Number Taylor Coefficients, Per Variable, Currently Stored: 5.6.1.4: size_taylor
                Comparison Changes During Zero Order Forward Mode: 5.6.1.5: CompareChange
                    CompareChange and Re-Tape: Example and Test: 5.6.1.5.1: CompareChange.cpp
                Controlling Taylor Coefficients Memory Allocation: 5.6.1.6: capacity_taylor
                Forward Mode: Example and Test: 5.6.1.7: Forward.cpp
            Reverse Mode: 5.6.2: Reverse
                First Order Reverse Mode: 5.6.2.1: reverse_one
                    First Order Reverse Mode: Example and Test: 5.6.2.1.1: reverse_one.cpp
                Second Order Reverse Mode: 5.6.2.2: reverse_two
                    Second Order Reverse ModeExample and Test: 5.6.2.2.1: reverse_two.cpp
                    Hessian Times Direction: Example and Test: 5.6.2.2.2: HesTimesDir.cpp
                Any Order Reverse Mode: 5.6.2.3: reverse_any
                    Third Order Reverse Mode: Example and Test: 5.6.2.3.1: reverse_three.cpp
                    Reverse Mode General Case: Example and Test: 5.6.2.3.2: reverse_any.cpp
                    Checkpoint and Function Composition: Example and Test: 5.6.2.3.3: checkpoint.cpp
            Calculating Sparsity Patterns: 5.6.3: Sparse
                Jacobian Sparsity Pattern: Forward Mode: 5.6.3.1: ForSparseJac
                    Forward Mode Jacobian Sparsity: Example and Test: 5.6.3.1.1: ForSparseJac.cpp
                Jacobian Sparsity Pattern: Reverse Mode: 5.6.3.2: RevSparseJac
                    Reverse Mode Jacobian Sparsity: Example and Test: 5.6.3.2.1: RevSparseJac.cpp
                Hessian Sparsity Pattern: Reverse Mode: 5.6.3.3: RevSparseHes
                    Reverse Mode Hessian Sparsity: Example and Test: 5.6.3.3.1: RevSparseHes.cpp
        First and Second Derivatives: Easy Drivers: 5.7: Drivers
            Jacobian: Driver Routine: 5.7.1: Jacobian
                Jacobian: Example and Test: 5.7.1.1: Jacobian.cpp
            First Order Partial Derivative: Driver Routine: 5.7.2: ForOne
                First Order Partial Driver: Example and Test: 5.7.2.1: ForOne.cpp
            First Order Derivative: Driver Routine: 5.7.3: RevOne
                First Order Derivative Driver: Example and Test: 5.7.3.1: RevOne.cpp
            Hessian: Easy Driver: 5.7.4: Hessian
                Hessian: Example and Test: 5.7.4.1: Hessian.cpp
                Hessian of Lagrangian and ADFun Default Constructor: Example and Test: 5.7.4.2: HesLagrangian.cpp
            Forward Mode Second Partial Derivative Driver: 5.7.5: ForTwo
                Subset of Second Order Partials: Example and Test: 5.7.5.1: ForTwo.cpp
            Reverse Mode Second Partial Derivative Driver: 5.7.6: RevTwo
                Second Partials Reverse Driver: Example and Test: 5.7.6.1: RevTwo.cpp
            Sparse Jacobian: Easy Driver: 5.7.7: sparse_jacobian
                Sparse Jacobian: Example and Test: 5.7.7.1: sparse_jacobian.cpp
            Sparse Hessian: Easy Driver: 5.7.8: sparse_hessian
                Sparse Hessian: Example and Test: 5.7.8.1: sparse_hessian.cpp
        Check an ADFun Sequence of Operations: 5.8: FunCheck
            ADFun Check and Re-Tape: Example and Test: 5.8.1: FunCheck.cpp
        OpenMP Maximum Thread Number: 5.9: omp_max_thread
            Compile and Run the OpenMP Test: 5.9.1: openmp_run.sh
                A Simple Parallel Loop: 5.9.1.1: example_a11c.cpp
                Multi-Threaded Newton's Method Main Program: 5.9.1.2: multi_newton.cpp
                    Multi-Threaded Newton's Method Routine: 5.9.1.2.1: multi_newton
                    OpenMP Multi-Threading Newton's Method Source Code: 5.9.1.2.2: multi_newton.hpp
                Sum of 1/i Main Program: 5.9.1.3: sum_i_inv.cpp
        Optimize the Tape Corresponding to an ADFun object: 5.10: optimize
            ADFun Operation Sequence Optimization: Example and Test: 5.10.1: optimize.cpp
        ADFun Object Deprecated Member Functions: 5.11: FunDeprecated
    The CppAD General Purpose Library: 6: library
        Replacing the CppAD Error Handler: 6.1: ErrorHandler
            Replacing The CppAD Error Handler: Example and Test: 6.1.1: ErrorHandler.cpp
            CppAD Assertions During Execution: 6.1.2: cppad_assert
        Determine if Two Values Are Nearly Equal: 6.2: NearEqual
            NearEqual Function: Example and Test: 6.2.1: Near_Equal.cpp
        Run One Speed Test and Return Results: 6.3: speed_test
            Returns Elapsed Number of Seconds: 6.3.1: elapsed_seconds
                Elapsed Seconds: Example and Test: 6.3.1.1: elapsed_seconds.cpp
            speed_test: Example and test: 6.3.2: speed_test.cpp
        Run One Speed Test and Print Results: 6.4: SpeedTest
            Example Use of SpeedTest: 6.4.1: speed_program.cpp
        Definition of a Numeric Type: 6.5: NumericType
            The NumericType: Example and Test: 6.5.1: NumericType.cpp
        Check NumericType Class Concept: 6.6: CheckNumericType
            The CheckNumericType Function: Example and Test: 6.6.1: CheckNumericType.cpp
        Definition of a Simple Vector: 6.7: SimpleVector
            Simple Vector Template Class: Example and Test: 6.7.1: SimpleVector.cpp
        Check Simple Vector Concept: 6.8: CheckSimpleVector
            The CheckSimpleVector Function: Example and Test: 6.8.1: CheckSimpleVector.cpp
        Obtain Nan and Determine if a Value is Nan: 6.9: nan
            nan: Example and Test: 6.9.1: nan.cpp
        The Integer Power Function: 6.10: pow_int
        Evaluate a Polynomial or its Derivative: 6.11: Poly
            Polynomial Evaluation: Example and Test: 6.11.1: Poly.cpp
            Source: Poly: 6.11.2: poly.hpp
        Compute Determinants and Solve Equations by LU Factorization: 6.12: LuDetAndSolve
            Compute Determinant and Solve Linear Equations: 6.12.1: LuSolve
                LuSolve With Complex Arguments: Example and Test: 6.12.1.1: LuSolve.cpp
                Source: LuSolve: 6.12.1.2: lu_solve.hpp
            LU Factorization of A Square Matrix: 6.12.2: LuFactor
                LuFactor: Example and Test: 6.12.2.1: LuFactor.cpp
                Source: LuFactor: 6.12.2.2: lu_factor.hpp
            Invert an LU Factored Equation: 6.12.3: LuInvert
                LuInvert: Example and Test: 6.12.3.1: LuInvert.cpp
                Source: LuInvert: 6.12.3.2: lu_invert.hpp
        One DimensionalRomberg Integration: 6.13: RombergOne
            One Dimensional Romberg Integration: Example and Test: 6.13.1: RombergOne.cpp
        Multi-dimensional Romberg Integration: 6.14: RombergMul
            One Dimensional Romberg Integration: Example and Test: 6.14.1: RombergMul.cpp
        An Embedded 4th and 5th Order Runge-Kutta ODE Solver: 6.15: Runge45
            Runge45: Example and Test: 6.15.1: runge_45_1.cpp
            Runge45: Example and Test: 6.15.2: runge_45_2.cpp
        A 3rd and 4th Order Rosenbrock ODE Solver: 6.16: Rosen34
            Rosen34: Example and Test: 6.16.1: Rosen34.cpp
        An Error Controller for ODE Solvers: 6.17: OdeErrControl
            OdeErrControl: Example and Test: 6.17.1: OdeErrControl.cpp
            OdeErrControl: Example and Test Using Maxabs Argument: 6.17.2: OdeErrMaxabs.cpp
        An Arbitrary Order Gear Method: 6.18: OdeGear
            OdeGear: Example and Test: 6.18.1: OdeGear.cpp
        An Error Controller for Gear's Ode Solvers: 6.19: OdeGearControl
            OdeGearControl: Example and Test: 6.19.1: OdeGearControl.cpp
        Computing Jacobian and Hessian of Bender's Reduced Objective: 6.20: BenderQuad
            BenderQuad: Example and Test: 6.20.1: BenderQuad.cpp
        Jacobian and Hessian of Optimal Values: 6.21: opt_val_hes
            opt_val_hes: Example and Test: 6.21.1: opt_val_hes.cpp
        LU Factorization of A Square Matrix and Stability Calculation: 6.22: LuRatio
            LuRatio: Example and Test: 6.22.1: LuRatio.cpp
        Float and Double Standard Math Unary Functions: 6.23: std_math_unary
        The CppAD::vector Template Class: 6.24: CppAD_vector
            CppAD::vector Template Class: Example and Test: 6.24.1: CppAD_vector.cpp
            CppAD::vectorBool Class: Example and Test: 6.24.2: vectorBool.cpp
        Routines That Track Use of New and Delete: 6.25: TrackNewDel
            Tracking Use of New and Delete: Example and Test: 6.25.1: TrackNewDel.cpp
    Examples: 7: Example
        General Examples: 7.1: General
            Creating Your Own Interface to an ADFun Object: 7.1.1: ad_fun.cpp
            Example and Test Linking CppAD to Languages Other than C++: 7.1.2: ad_in_c.cpp
            Gradient of Determinant Using Expansion by Minors: Example and Test: 7.1.3: HesMinorDet.cpp
            Gradient of Determinant Using LU Factorization: Example and Test: 7.1.4: HesLuDet.cpp
            Nonlinear Programming Using the CppAD Interface to Ipopt: 7.1.5: cppad_ipopt_nlp
                Linking the CppAD Interface to Ipopt in Visual Studio 9.0: 7.1.5.1: cppad_ipopt_windows
                Nonlinear Programming Using CppAD and Ipopt: Example and Test: 7.1.5.2: ipopt_get_started.cpp
                Example Simultaneous Solution of Forward and Inverse Problem: 7.1.5.3: cppad_ipopt_ode
                    An ODE Inverse Problem Example: 7.1.5.3.1: ipopt_ode_problem
                        ODE Inverse Problem Definitions: Source Code: 7.1.5.3.1.1: ipopt_ode_problem.hpp
                    ODE Fitting Using Simple Representation: 7.1.5.3.2: ipopt_ode_simple
                        ODE Fitting Using Simple Representation: 7.1.5.3.2.1: ipopt_ode_simple.hpp
                    ODE Fitting Using Fast Representation: 7.1.5.3.3: ipopt_ode_fast
                        ODE Fitting Using Fast Representation: 7.1.5.3.3.1: ipopt_ode_fast.hpp
                    Driver for Running the Ipopt ODE Example: 7.1.5.3.4: ipopt_ode_run.hpp
                    Correctness Check for Both Simple and Fast Representations: 7.1.5.3.5: ipopt_ode_check.cpp
                Speed Test for Both Simple and Fast Representations: 7.1.5.4: ipopt_ode_speed.cpp
            Interfacing to C: Example and Test: 7.1.6: Interface2C.cpp
            Gradient of Determinant Using Expansion by Minors: Example and Test: 7.1.7: JacMinorDet.cpp
            Gradient of Determinant Using Lu Factorization: Example and Test: 7.1.8: JacLuDet.cpp
            Using Multiple Levels of AD: 7.1.9: mul_level
                Multiple Tapes: Example and Test: 7.1.9.1: mul_level.cpp
            A Stiff Ode: Example and Test: 7.1.10: OdeStiff.cpp
            Taylor's Ode Solver: An Example and Test: 7.1.11: ode_taylor.cpp
            Using Adolc with Taylor's Ode Solver: An Example and Test: 7.1.12: ode_taylor_adolc.cpp
            Example Differentiating a Stack Machine Interpreter: 7.1.13: StackMachine.cpp
        Utility Routines used by CppAD Examples: 7.2: ExampleUtility
            Program That Runs the CppAD Examples: 7.2.1: Example.cpp
            Program That Runs the Speed Examples: 7.2.2: speed_example.cpp
            Lu Factor and Solve with Recorded Pivoting: 7.2.3: LuVecAD
                Lu Factor and Solve With Recorded Pivoting: Example and Test: 7.2.3.1: LuVecADOk.cpp
        List of All the CppAD Examples: 7.3: ListAllExamples
        Choosing The Vector Testing Template Class: 7.4: test_vector
    Preprocessor Definitions Used by CppAD: 8: configure
    Appendix: 9: Appendix
        Frequently Asked Questions and Answers: 9.1: Faq
        Speed Test Routines: 9.2: speed
            Speed Testing Main Program: 9.2.1: speed_main
                Speed Testing Gradient of Determinant Using Lu Factorization: 9.2.1.1: link_det_lu
                Speed Testing Gradient of Determinant by Minor Expansion: 9.2.1.2: link_det_minor
                Speed Testing the Jacobian of Ode Solution: 9.2.1.3: link_ode
                Speed Testing Second Derivative of a Polynomial: 9.2.1.4: link_poly
                Speed Testing Sparse Hessian: 9.2.1.5: link_sparse_hessian
                Speed Testing Sparse Jacobian: 9.2.1.6: link_sparse_jacobian
                Microsoft Version of Elapsed Number of Seconds: 9.2.1.7: microsoft_timer
            Speed Testing Utilities: 9.2.2: speed_utility
                Simulate a [0,1] Uniform Random Variate: 9.2.2.1: uniform_01
                    Source: uniform_01: 9.2.2.1.1: uniform_01.hpp
                Determinant of a Minor: 9.2.2.2: det_of_minor
                    Determinant of a Minor: Example and Test: 9.2.2.2.1: det_of_minor.cpp
                    Source: det_of_minor: 9.2.2.2.2: det_of_minor.hpp
                Determinant Using Expansion by Minors: 9.2.2.3: det_by_minor
                    Determinant Using Expansion by Minors: Example and Test: 9.2.2.3.1: det_by_minor.cpp
                    Source: det_by_minor: 9.2.2.3.2: det_by_minor.hpp
                Determinant Using Expansion by Lu Factorization: 9.2.2.4: det_by_lu
                    Determinant Using Lu Factorization: Example and Test: 9.2.2.4.1: det_by_lu.cpp
                    Source: det_by_lu: 9.2.2.4.2: det_by_lu.hpp
                Check Determinant of 3 by 3 matrix: 9.2.2.5: det_33
                    Source: det_33: 9.2.2.5.1: det_33.hpp
                Check Gradient of Determinant of 3 by 3 matrix: 9.2.2.6: det_grad_33
                    Source: det_grad_33: 9.2.2.6.1: det_grad_33.hpp
                Evaluate a Function Defined in Terms of an ODE: 9.2.2.7: ode_evaluate
                    ode_evaluate: Example and test: 9.2.2.7.1: ode_evaluate.cpp
                    Source: ode_evaluate: 9.2.2.7.2: ode_evaluate.hpp
                Evaluate a Function That Has a Sparse Hessian: 9.2.2.8: sparse_evaluate
                    sparse_evaluate: Example and test: 9.2.2.8.1: sparse_evaluate.cpp
                    Source: sparse_evaluate: 9.2.2.8.2: sparse_evaluate.hpp
            Speed Test Functions in Double: 9.2.3: speed_double
                Double Speed: Determinant by Minor Expansion: 9.2.3.1: double_det_minor.cpp
                Double Speed: Determinant Using Lu Factorization: 9.2.3.2: double_det_lu.cpp
                Double Speed: Ode Solution: 9.2.3.3: double_ode.cpp
                Double Speed: Evaluate a Polynomial: 9.2.3.4: double_poly.cpp
                Double Speed: Sparse Hessian: 9.2.3.5: double_sparse_hessian.cpp
                Double Speed: Sparse Jacobian: 9.2.3.6: double_sparse_jacobian.cpp
            Speed Test Derivatives Using Adolc: 9.2.4: speed_adolc
                Adolc Speed: Gradient of Determinant by Minor Expansion: 9.2.4.1: adolc_det_minor.cpp
                Adolc Speed: Gradient of Determinant Using Lu Factorization: 9.2.4.2: adolc_det_lu.cpp
                Adolc Speed: Ode: 9.2.4.3: adolc_ode.cpp
                Adolc Speed: Second Derivative of a Polynomial: 9.2.4.4: adolc_poly.cpp
                Adolc Speed: Sparse Hessian: 9.2.4.5: adolc_sparse_hessian.cpp
                adolc Speed: sparse_jacobian: 9.2.4.6: adolc_sparse_jacobian.cpp
            Speed Test Derivatives Using CppAD: 9.2.5: speed_cppad
                CppAD Speed: Gradient of Determinant by Minor Expansion: 9.2.5.1: cppad_det_minor.cpp
                CppAD Speed: Gradient of Determinant Using Lu Factorization: 9.2.5.2: cppad_det_lu.cpp
                CppAD Speed: Gradient of Ode Solution: 9.2.5.3: cppad_ode.cpp
                CppAD Speed: Second Derivative of a Polynomial: 9.2.5.4: cppad_poly.cpp
                CppAD Speed: Sparse Hessian: 9.2.5.5: cppad_sparse_hessian.cpp
                CppAD Speed: Sparse Jacobian: 9.2.5.6: cppad_sparse_jacobian.cpp
            Speed Test Derivatives Using Fadbad: 9.2.6: speed_fadbad
                Fadbad Speed: Gradient of Determinant by Minor Expansion: 9.2.6.1: fadbad_det_minor.cpp
                Fadbad Speed: Gradient of Determinant Using Lu Factorization: 9.2.6.2: fadbad_det_lu.cpp
                Fadbad Speed: Ode: 9.2.6.3: fadbad_ode.cpp
                Fadbad Speed: Second Derivative of a Polynomial: 9.2.6.4: fadbad_poly.cpp
                Fadbad Speed: Sparse Hessian: 9.2.6.5: fadbad_sparse_hessian.cpp
                fadbad Speed: sparse_jacobian: 9.2.6.6: fadbad_sparse_jacobian.cpp
            Speed Test Derivatives Using Sacado: 9.2.7: speed_sacado
                Sacado Speed: Gradient of Determinant by Minor Expansion: 9.2.7.1: sacado_det_minor.cpp
                Sacado Speed: Gradient of Determinant Using Lu Factorization: 9.2.7.2: sacado_det_lu.cpp
                Sacado Speed: Gradient of Ode Solution: 9.2.7.3: sacado_ode.cpp
                Sacado Speed: Second Derivative of a Polynomial: 9.2.7.4: sacado_poly.cpp
                Sacado Speed: Sparse Hessian: 9.2.7.5: sacado_sparse_hessian.cpp
                sacado Speed: sparse_jacobian: 9.2.7.6: sacado_sparse_jacobian.cpp
        The Theory of Derivative Calculations: 9.3: Theory
            The Theory of Forward Mode: 9.3.1: ForwardTheory
                Exponential Function Forward Taylor Polynomial Theory: 9.3.1.1: ExpForward
                Logarithm Function Forward Taylor Polynomial Theory: 9.3.1.2: LogForward
                Square Root Function Forward Taylor Polynomial Theory: 9.3.1.3: SqrtForward
                Trigonometric and Hyperbolic Sine and Cosine Forward Theory: 9.3.1.4: SinCosForward
                Arctangent Function Forward Taylor Polynomial Theory: 9.3.1.5: AtanForward
                Arcsine Function Forward Taylor Polynomial Theory: 9.3.1.6: AsinForward
                Arccosine Function Forward Taylor Polynomial Theory: 9.3.1.7: AcosForward
            The Theory of Reverse Mode: 9.3.2: ReverseTheory
                Exponential Function Reverse Mode Theory: 9.3.2.1: ExpReverse
                Logarithm Function Reverse Mode Theory: 9.3.2.2: LogReverse
                Square Root Function Reverse Mode Theory: 9.3.2.3: SqrtReverse
                Trigonometric and Hyperbolic Sine and Cosine Reverse Theory: 9.3.2.4: SinCosReverse
                Arctangent Function Reverse Mode Theory: 9.3.2.5: AtanReverse
                Arcsine Function Reverse Mode Theory: 9.3.2.6: AsinReverse
                Arccosine Function Reverse Mode Theory: 9.3.2.7: AcosReverse
            An Important Reverse Mode Identity: 9.3.3: reverse_identity
        Glossary: 9.4: glossary
        Bibliography: 9.5: Bib
        Know Bugs and Problems Using CppAD: 9.6: Bugs
        The CppAD Wish List: 9.7: WishList
        Changes and Additions to CppAD: 9.8: whats_new
            Changes and Additions to CppAD During 2010: 9.8.1: whats_new_10
            Changes and Additions to CppAD During 2009: 9.8.2: whats_new_09
            Changes and Additions to CppAD During 2008: 9.8.3: whats_new_08
            Changes and Additions to CppAD During 2007: 9.8.4: whats_new_07
            Changes and Additions to CppAD During 2006: 9.8.5: whats_new_06
            Changes and Additions to CppAD During 2005: 9.8.6: whats_new_05
            Changes and Additions to CppAD During 2004: 9.8.7: whats_new_04
            Changes and Additions to CppAD During 2003: 9.8.8: whats_new_03
        Deprecated Include Files: 9.9: include_deprecated
        Your License for the CppAD Software: 9.10: License
    Alphabetic Listing of Cross Reference Tags: 10: _reference
    Keyword Index: 11: _index
    External Internet References: 12: _external

2: CppAD Download, Test, and Installation Instructions

2.a: Contents
2.1: Unix Download, Test and Installation
2.2: Windows Download and Test

Input File: omh/install.omh
2.1: Unix Download, Test and Installation

2.1.a: Fedora
CppAD is available through yum on the Fedora operating system starting Fedora version 7. You can download and install CppAD with the instruction yum install cppad-devel (In Fedora, devel is used for program development tools.) You can download and install the corresponding version of the documentation using the command yum install cppad-doc

2.1.b: RPM
If you want to use the Fedora cppad.spec file to build an RPM for some other operating system, it can be found at
https://projects.coin-or.org/CppAD/browser/trunk/cppad.spec

2.1.c: Download

2.1.c.a: Subversion
If you are familiar with subversion, you may want to follow the more complicated CppAD download instructions; see the following 2.1.1: subversion instructions .

2.1.c.b: Web Link
If you are not using the subversion download instructions, make sure you are reading the web version of this documentation by following the link web version (http://www.coin-or.org/CppAD/Doc/installunix.htm) . Then proceed with the instruction that appear below this point.

2.1.c.c: Unix Tar Files
The download files below were first archived with tar and then compressed with gzip: The ascii files for these downloads are in Unix format; i.e., each line ends with just a line feed.
CPL License    cppad-20100902.cpl.tgz
GPL License    cppad-20100902.gpl.tgz

2.1.c.d: Tar File Extraction
Use the unix command
     tar -xvzf cppad-20100902.
license.tgz
(where license is cpl or gpl) to decompress and extract the unix format version into the distribution directory
     cppad-20100902
To see if this has been done correctly, check for the following file:
     cppad-20100902/cppad/cppad.hpp

2.1.d: Configure
Enter the distribution_directory (the directory created by the extraction) and execute the command:
     ./configure                            
     --prefix=
PrefixDir                     
     --with-Documentation                   
     --with-stdvector                         
     POSTFIX_DIR=
PostfixDir                 
     ADOLC_DIR=
AdolcDir                     
     FADBAD_DIR=
FadbadDir                   
     SADADO_DIR=
SacadoDir                   
     BOOST_DIR=
BoostDir                     
     IPOPT_DIR=
IpoptDir                     
     CXX_FLAGS=
CompilerFlags 
where only the configure command need appear. The entries one each of the other lines are optional and the text in italic is replaced values that you choose.

2.1.e: make test
You can run all of the CppAD correctness tests by executing the command make test in the distribution_directory . A description of the tests, and instructions for running individual tests, are described below.

2.1.f: Introduction

2.1.f.a: Getting Started
You can run the CppAD getting started example / test by executing the command make test in the directory
     
distribution_directory/introduction/get_started

2.1.f.b: exp_apx
You can run the examples / tests for the exp_apx function (used in the 3: Introduction ) by executing the command make test in the directory
     
distribution_directory/introduction/exp_apx

2.1.g: CppAD Examples
You can run a large number of the examples / tests showing how to use CppAD by executing the command make test in the directory
     
distribution_directory/example
See 7.3: ListAllExamples for a list of all the CppAD examples.

2.1.h: More Testing
You can run a large number of tests (that are not intended to be examples) by executing the command make test in the directory
     
distribution_directory/test_more

2.1.i: Speed Testing

2.1.i.a: CppAD Derivative Speed Tests
A set of CppAD derivative value 9.2.5: speed tests are included with this distribution. You can test that the results computed during these tests are correct by executing the command make test in the directory
     
distribution_directory/speed/cppad
After executing make test, you can run the CppAD derivative speed tests by executing the command ./cppad (see 9.2.1: speed_main ).

2.1.i.b: Function Speed Tests
A set of functions value 9.2.3: speed tests are included (to compare with derivative values speeds). You can test that the results computed during these tests are correct by executing the command make test in the directory
     
distribution_directory/speed/double
After executing make test, you can run the function value speed tests by executing the command ./double (see 9.2.1: speed_main ).

2.1.i.c: Examples For Speed Tests
The speed tests use some utilities that have their own set of examples / tests. You can test that the results computed by this utilities are correct by executing the command make test in the directory
     
distribution_directory/speed/example

2.1.j: Profiling CppAD
The CppAD derivative speed tests mentioned above can be profiled. You can test that the results computed during this profiling are correct by executing the command make test in the directory
     
distribution_directory/speed/profile
After executing make test, you can run the profile tests by executing the command ./profile (see 9.2.1: speed_main ). You can then obtain the profiling results with
     gprof -b speed/profile/profile
If you are using a windows operating system with Cygwin or MinGW, you may have to replace profile by profile.exe in the gprof command above; i.e.,
 
	gprof -b speed/profile/profile.exe
In C++, template parameters and argument types become part of a routines's name. This can make the gprof output hard to read (the routine names can be very long). You can remove the template parameters and argument types from the routine names by executing the following command
 
	gprof -b speed/profile/profile | sed -f speed/profile/gprof.sed
If you are using a windows operating system with Cygwin or MinGW, you would need to use
 
	gprof -b speed/profile/profile.exe | sed -f speed/profile/gprof.sed


2.1.k: PrintFor
You can test the 4.3.4: PrintFor command by executing the command make test in the directory
     
distribution_directory/print_for

2.1.l: PrefixDir
The default value for prefix directory is $HOME i.e., by default the CppAD include files will 2.1.v: install below $HOME. If you want to install elsewhere, you will have to use this option. As an example of using the --prefix=PrefixDir option, if you specify
 
	./configure --prefix=/usr/local
the CppAD include files will be installed in the directory
     /usr/local/include/cppad
If 2.1.m: --with-Documentation is specified, the CppAD documentation files will be installed in the directory
     /usr/local/share/doc/cppad-20100902

2.1.m: --with-Documentation
If the command line argument --with-Documentation is specified, the CppAD documentation HTML and XML files are copied to the directory
     
PrefixDir/share/doc/PostfixDir/cppad-20100902
(see 2.1.o: PostfixDir ). The top of the CppAD HTML documentation tree (with mathematics displayed as LaTex command) will be located at
     
PrefixDir/share/doc/PostfixDir/cppad-20100902/cppad.htm
and the top of the XML documentation tree (with mathematics displayed as MathML) will be located at
     
PrefixDir/share/doc/PostfixDir/cppad-20100902/cppad.xml

2.1.n: --with-stdvector
The 7.4: CPPAD_TEST_VECTOR template class is used for extensive examples and testing of CppAD. If the command line argument --with-stdvector is specified, the default definition this template class is replaced by
 
	std::vector
(In this case BoostDir must not also be specified.)

2.1.o: PostfixDir
By default, the postfix directory is empty; i.e., there is no postfix directory. As an example of using the POSTFIX_DIR=PostfixDir option, if you specify
 
	./configure --prefix=/usr/local POSTFIX_DIR=coin
the CppAD include files will be 2.1.v: installed in the directory
     /usr/local/include/coin/cppad
If 2.1.m: --with-Documentation is specified, the CppAD documentation files will be installed in the directory
     /usr/local/share/doc/coin/cppad-20100902

2.1.p: AdolcDir
If you have Adolc 1.10.2 (http://www.math.tu-dresden.de/~adol-c/) installed on your system, you can specify a value for AdolcDir in the 2.1.d: configure command line. The value of AdolcDir must be such that
     
AdolcDir/include/adolc/adouble.h
is a valid way to reference adouble.h. In this case, you can run the Adolc speed correctness tests by executing the command make test in the directory
     
distribution_directory/speed/adolc
After executing make test, you can run the Adolc speed tests by executing the command ./adolc (see 9.2.1: speed_main ).

2.1.p.a: Linux
If you are using Linux, you will have to add to following lines to the file .bash_profile in your home directory:
     LD_LIBRARY_PATH=
AdolcDir/lib:${LD_LIBRARY_PATH}
     export LD_LIBRARY_PATH
in order for Adolc to run properly.

2.1.p.b: Cygwin
If you are using Cygwin, you will have to add to following lines to the file .bash_profile in your home directory:
     PATH=
AdolcDir/bin:${PATH}
     export PATH
in order for Adolc to run properly. If AdolcDir begins with a disk specification, you must use the Cygwin format for the disk specification. For example, if d:/adolc_base is the proper directory, /cygdrive/d/adolc_base should be used for AdolcDir .

2.1.q: FadbadDir
If you have Fadbad 2.1 (http://www.fadbad.com/) installed on your system, you can specify a value for FadbadDir . It must be such that
     
FadbadDir/FADBAD++/badiff.h
is a valid reference to badiff.h. In this case, you can run the Fadbad speed correctness tests by executing the command make test in the directory
     
distribution_directory/speed/fadbad
After executing make test, you can run the Fadbad speed tests by executing the command ./fadbad (see 9.2.1: speed_main ).

2.1.r: SacadoDir
If you have Sacado (http://trilinos.sandia.gov/packages/sacado/) installed on your system, you can specify a value for SacadoDir . It must be such that
     
SacadoDir/include/Sacado.hpp
is a valid reference to Sacado.hpp. In this case, you can run the Sacado speed correctness tests by executing the command make test in the directory
     
distribution_directory/speed/sacado
After executing make test, you can run the Sacado speed tests by executing the command ./sacado (see 9.2.1: speed_main ).

2.1.s: BoostDir
The 7.4: CPPAD_TEST_VECTOR template class is used for extensive examples and testing of CppAD. The default definition for CPPAD_TEST_VECTOR is 6.24: CppAD::vector . If the command line argument
     BOOST_DIR=
BoostDir
is present, it must be such that
     
BoostDir/boost/numeric/ublas/vector.hpp
is a valid reference to the file vector.hpp. In this case, the default definition of CPPAD_TEST_VECTOR is replaced by
 
	boost::numeric::ublas::vector
(see boost (http://www.boost.org) ). If BoostDir is present, the argument --with-stdvector must not be present.

2.1.t: IpoptDir
If you have Ipopt (http://www.coin-or.org/projects/Ipopt.xml) installed on your system, you can specify a value for IpoptDir . It must be such that
     
IpoptDir/include/coin/IpIpoptApplication.hpp
is a valid reference to IpIpoptApplication.hpp. In this case, the CppAD interface to Ipopt 7.1.5.t: examples can be built and tested by executing the command make test in the directory
     
distribution_directory/cppad_ipopt/example
You can do more testing of this interface by executing make test in the directories
     
distribution_directory/cppad_ipopt/test
     
distribution_directory/cppad_ipopt/speed
Once this has been done, you can execute the program
     
distribution_directory/cppad_ipopt/speed/speed
see 7.1.5.4: ipopt_ode_speed.cpp .

2.1.u: CompilerFlags
If the command line argument CompilerFlags is present, it specifies compiler flags. For example,
     CXX_FLAGS="-Wall -ansi"
would specify that warning flags -Wall and -ansi should be included in all the C++ compile commands. The error and warning flags chosen must be valid options for the C++ compiler. The default value for CompilerFlags is the empty string.

2.1.v: make install
Once you are satisfied that the tests are giving correct results, you can install CppAD into easy to use directories by executing the command
 
	make install
This will install CppAD in the location specified by 2.1.l: PrefixDir . You must have permission to write in the PrefixDir directory to execute this command. You may optionally specify a destination directory for the install; i.e.,
     make install DESTDIR=
DestinationDirectory

Input File: omh/install_unix.omh
2.1.1: Using Subversion To Download Source Code

2.1.1.a: File Format
The files corresponding to this download procedure are in Unix format; i.e., each line ends with just a line feed.

2.1.1.b: Subversion
You must have subversion (http://subversion.tigris.org/) installed to use this download procedure. In Unix, you can check if subversion is already installed in your path by entering the command
 
	which svn


2.1.1.c: OMhelp
The documentation for CppAD is built from the source code files using OMhelp (http://www.seanet.com/~bradbell/omhelp/) . In Unix, you can check if OMhelp is already installed in your path by entering the command
 
	which omhelp


2.1.1.d: Current Version
The following command will download the current version of the CppAD source code:
     svn co https://projects.coin-or.org/svn/CppAD/
dir dir
where dir is replaced by trunk. To see if this has been done correctly, check for the following file:
     
dir/cppad/cppad.hpp
Since you downloaded the current version, you should set the version of CppAD to the current date. Using an editor of you choice, open the file
     
dir/configure
(if you plan to use the 2.2: Windows install instructions, edit dir/cppad/config.h instead of dir/configure). Search this file for text of the form yyyymmdd where yyyy are four decimal digits representing a year, mm is two decimal digits representing a month, and dd is two decimal digits representing a day. Replace each occurrence of this text with the decimal digits for the current year, month, and day (i.e., the eight decimal digits representing the current date).

2.1.1.e: Stable Version
Subversion downloads are available for the following stable versions of CppAD:
dir yyyymmdd
1.0    20060913
2.0    20071016
2.1    20071124
2.2    20071210
The following command will download a stable version of the CppAD source code:
     svn co https://projects.coin-or.org/svn/CppAD/stable/
dir dir
To see if this has been done correctly, check for the following file: if dir is 1.0 check for
     1.0/CppAD/CppAD.h
otherwise check for
     
dir/cppad/cppad.hpp
Since you downloaded a stable version, the version of CppAD configure, and all the other relevant files, is correct.

2.1.1.f: Build the Documentation
Now build the documentation for this version using the commands
     mkdir 
dir/doc
     cd 
dir/doc
     omhelp ../doc.omh -noframe -debug -l http://www.coin-or.org/CppAD/
     omhelp ../doc.omh -noframe -debug -l http://www.coin-or.org/CppAD/ -xml

2.1.1.g: Continue with Installation
Once the steps above are completed, you can proceed with the install instructions in the documentation you just built. Start by opening the one of the two files
     
dir/doc/index.xml
     
dir/doc/index.htm
in a web browser and proceeding to the 2.1: Unix or 2.2: Windows install instructions.
Input File: omh/subversion.omh
2.2: Windows Download and Test

2.2.a: Cygwin
If you are using Cygwin, or MinGW with MSYS, follow the 2.1: unix install instructions.

2.2.b: Download

2.2.b.a: Subversion
If you are familiar with subversion, you may want to follow the more complicated 2.1.1: subversion download instructions instead of the ones below.

2.2.b.b: Web Link
If you are not using the subversion download instructions, sure you are reading the web based version of this documentation by following the link web version (http://www.coin-or.org/CppAD/Doc/installwindows.htm) . Then proceed with the instruction that appear below this point.

2.2.b.c: Unix Tar Files
The download files below were first archived with tar and then compressed with gzip. The ascii files are in Unix format; i.e., each line ends with a line feed (instead of a carriage return and line feed as is standard for windows formatted files). Visual Studio can handel this formatting just fine, but you may want to convert the format to the windows standard if you are using and editor that has trouble viewing the files in Unix format. and then a line feed.
CPL License    cppad-20100902.cpl.tgz
GPL License    cppad-20100902.gpl.tgz
The following steps will decompress and extract the files using Winzip (http://www.winzip.com/index.htm) version 7.0 (other version of Winzip and other decompression programs will be similar).
  1. Download your choice between these two licenses listed above and store the result in a file on disk.
  2. Open the file using Winzip (using All archives) as the file type in the Open browser.
  3. Winzip will ask if it should decompress the file into a temporary folder and open it. Respond by selecting the Yes button.
  4. Now select the Extract button from the main menu.
  5. Place the name of the directory were you want the distribution in the Extract to field and then select the Extract button in the pop-up dialog. Winzip will create a subdirectory called cppad-20100902 where the files are placed.


2.2.c: Getting Started
The following steps will build the 3.1: get_started.cpp example. Using Microsoft Visual C++, open the workspace
 
	cppad-20100902\introduction\get_started\get_started.sln
in Visual Studio and then select Build | Build get_started.exe. Then in a Dos box, and in the cppad-20100902 directory, execute the following command
 
	introduction\get_started\Debug\get_started


2.2.d: Introduction
The following steps will build the routines that verify the calculations in the exp_apx calculations in the 3: Introduction section. Using Microsoft Visual C++, open the workspace
 
	cppad-20100902\introduction\exp_apx\exp_apx.sln
in Visual Studio. Then select Build | Build exp_apx.exe. Then in a Dos box, and in the cppad-20100902 directory, execute the following command
 
	introduction\exp_apx\Debug\exp_apx


2.2.e: Examples and Testing
The following steps will build an extensive set of examples and correctness tests. Using Microsoft Visual C++, open the workspace
 
	cppad-20100902\example\example.sln
in Visual Studio. Then select Build | Build Example.exe. Then in a Dos box, and in the cppad-20100902 directory, execute the following command
 
	example\Debug\example


2.2.f: More Correctness Testing
Using Microsoft Visual C++, open the workspace
 
	cppad-20100902\test_more\test_more.sln
in Visual Studio and then select Build | Build test_more.exe. Then in a Dos box, and in the cppad-20100902 directory, execute the following command
 
	test_more\Debug\test_more


2.2.g: Printing During Forward Mode
Using Microsoft Visual C++, open the workspace
 
	cppad-20100902\print_for\print_for.sln
in Visual Studio. Then select Build | Build print_for.exe. Then in a Dos box, and in the cppad-20100902 directory, execute the following command
 
	print_for\Debug\print_for


2.2.h: CppAD Speed Test
Using Microsoft Visual C++, open the workspace
 
	cppad-20100902\speed\cppad\cppad.sln
in Visual Studio. Then select Build | Build cppad.exe. Then in a Dos box, and in the cppad-20100902 directory, execute the following commands
 
	speed\cppad\Debug\cppad correct 123
	speed\cppad\Debug\cppad speed 123


2.2.i: Double Speed Test
Using Microsoft Visual C++, open the workspace
 
	cppad-20100902\speed\double\double.sln
in Visual Studio. Then select Build | Build double.exe. Then in a Dos box, and in the cppad-20100902 directory, execute the following commands
 
	speed\double\Debug\double correct 123
	speed\double\Debug\double speed 123


2.2.j: Speed Utility Example
Using Microsoft Visual C++, open the workspace cppad-20100902\speed\example\example.sln in Visual Studio. Then select Build | Build example.exe. Then in a Dos box, and in the cppad-20100902 directory, execute the following command
 
	speed\example\Debug\example

Input File: omh/install_windows.omh
3: An Introduction by Example to Algorithmic Differentiation

3.a: Preface

3.a.a: Algorithmic Differentiation
Algorithmic Differentiation (often referred to as Automatic Differentiation or just AD) uses the software representation of a function to obtain an efficient method for calculating its derivatives. These derivatives can be of arbitrary order and are analytic in nature (do not have any truncation error).

3.a.b: Forward Mode
A forward mode sweep computes the partial derivative of all the dependent variables with respect to one independent variable (or independent variable direction).

3.a.c: Reverse Mode
A reverse mode sweep computes the derivative of one dependent variable (or one dependent variable direction) with respect to all the independent variables.

3.a.d: Operation Count
The number of floating point operations for either a forward or reverse mode sweep is a small multiple of the number required to evaluate the original function. Thus, using reverse mode, you can evaluate the derivative of a scalar valued function with respect to thousands of variables in a small multiple of the work to evaluate the original function.

3.a.e: Efficiency
AD automatically takes advantage of the speed of your algorithmic representation of a function. For example, if you calculate a determinant using LU factorization, AD will use the LU representation for the derivative of the determinant (which is faster than using the definition of the determinant).

3.b: Purpose
This is an introduction by example to Algorithmic Differentiation. Its purpose is to aid in understand what AD calculates, how the calculations are preformed, and the amount of computation and memory required for a forward or reverse sweep.

3.c: Outline
  1. Demonstrate the use of CppAD to calculate derivatives of a polynomial: 3.1: get_started.cpp .
  2. Present two algorithms that approximate the exponential function. The first algorithm 3.2.1: exp_2.hpp is simpler and does not include any logical variables or loops. The second algorithm 3.3.1: exp_eps.hpp includes logical operations and a while loop. For each of these algorithms, do the following:
    1. Define the mathematical function corresponding to the algorithm (3.2: exp_2 and 3.3: exp_eps ).
    2. Write out the floating point operation sequence, and corresponding values, that correspond to executing the algorithm for a specific input (3.2.3: exp_2_for0 and 3.3.3: exp_eps_for0 ).
    3. Compute a forward sweep derivative of the operation sequence (3.2.4: exp_2_for1 and 3.3.4: exp_eps_for1 ).
    4. Compute a reverse sweep derivative of the operation sequence (3.2.5: exp_2_rev1 and 3.3.5: exp_eps_rev1 ).
    5. Use CppAD to compute both a forward and reverse sweep of the operation sequence (3.2.8: exp_2_cppad and 3.3.8: exp_eps_cppad ).
  3. The program 3.4: exp_apx_main.cpp runs all of the test routines that validate the calculations in the 3.2: exp_2 and 3.3: exp_eps presentation.


3.d: Reference
An in-depth review of AD theory and methods can be found in the book Evaluating Derivatives: Principles and Techniques of Algorithmic Differentiation , Andreas Griewank, SIAM Frontiers in Applied Mathematics, 2000.

3.e: Contents
get_started.cpp: 3.1A Simple Program Using CppAD to Compute Derivatives
exp_2: 3.2Second Order Exponential Approximation
exp_eps: 3.3An Epsilon Accurate Exponential Approximation
exp_apx_main.cpp: 3.4Run the exp_2 and exp_eps Tests

Input File: omh/introduction.omh
3.1: A Simple Program Using CppAD to Compute Derivatives

3.1.a: Purpose
Demonstrate the use of CppAD by computing the derivative of a simple example function.

3.1.b: Function
The example function  f : \R \rightarrow \R is defined by  \[
      f(x) = a_0 + a_1 * x^1 + \cdots + a_{k-1} * x^{k-1}
\] 
where a is a fixed vector of length k.

3.1.c: Derivative
The derivative of  f(x) is given by  \[
      f' (x) = a_1 + 2 * a_2 * x +  \cdots + (k-1) * a_{k-1} * x^{k-2} 
\] 


3.1.d: Value
For the particular case in this example,  k is equal to 5,  a = (1, 1, 1, 1, 1) , and  x = 3 . If follows that  \[
      f' ( 3 ) = 1 + 2 * 3 + 3 * 3^2 + 4 * 3^3 = 142
\] 


3.1.e: Poly
The routine Poly is defined below for this particular application. A general purpose polynomial evaluation routine is documented and distributed with CppAD (see 6.11: Poly ).

3.1.f: Exercises
Modify the program below to accomplish the following tasks using CppAD:
  1. Compute and print the derivative of  f(x) = 1 + x + x^2 + x^3 + x^4 at the point  x = 2 .
  2. Compute and print the derivative of  f(x) = 1 + x + x^2 / 2 at the point  x = .5 .
  3. Compute and print the derivative of  f(x) = \exp (x) - 1 - x - x^2 / 2 at the point  x = .5 .


3.1.g: Program
 
#include <iostream>      // standard input/output 
#include <vector>        // standard vector
#include <cppad/cppad.hpp> // the CppAD package http://www.coin-or.org/CppAD/

namespace { 
      // define y(x) = Poly(a, x) in the empty namespace
      template <class Type>
      Type Poly(const std::vector<double> &a, const Type &x)
      {     size_t k  = a.size();
            Type y   = 0.;  // initialize summation
            Type x_i = 1.;  // initialize x^i
            size_t i;
            for(i = 0; i < k; i++)
            {     y   += a[i] * x_i;  // y   = y + a_i * x^i
                  x_i *= x;           // x_i = x_i * x
            }
            return y;
      }
}
// main program
int main(void)
{     using CppAD::AD;           // use AD as abbreviation for CppAD::AD
      using std::vector;         // use vector as abbreviation for std::vector
      size_t i;                  // a temporary index

      // vector of polynomial coefficients
      size_t k = 5;              // number of polynomial coefficients
      vector<double> a(k);       // vector of polynomial coefficients
      for(i = 0; i < k; i++)
            a[i] = 1.;           // value of polynomial coefficients

      // domain space vector
      size_t n = 1;              // number of domain space variables
      vector< AD<double> > X(n); // vector of domain space variables
      X[0] = 3.;                 // value corresponding to operation sequence

      // declare independent variables and start recording operation sequence
      CppAD::Independent(X);

      // range space vector
      size_t m = 1;              // number of ranges space variables
      vector< AD<double> > Y(m); // vector of ranges space variables
      Y[0] = Poly(a, X[0]);      // value during recording of operations

      // store operation sequence in f: X -> Y and stop recording
      CppAD::ADFun<double> f(X, Y);

      // compute derivative using operation sequence stored in f
      vector<double> jac(m * n); // Jacobian of f (m by n matrix)
      vector<double> x(n);       // domain space vector
      x[0] = 3.;                 // argument value for derivative
      jac  = f.Jacobian(x);      // Jacobian for operation sequence

      // print the results
      std::cout << "f'(3) computed by CppAD = " << jac[0] << std::endl;

      // check if the derivative is correct
      int error_code;
      if( jac[0] == 142. )
            error_code = 0;      // return code for correct case
      else  error_code = 1;      // return code for incorrect case

      return error_code;
}


3.1.h: Output
Executing the program above will generate the following output:
 
	f'(3) computed by CppAD = 142

Input File: introduction/get_started/get_started.cpp
3.2: Second Order Exponential Approximation

3.2.a: Syntax
# include "exp_2.hpp"
y = exp_2(x)

3.2.b: Purpose
This is a simple example algorithm that is used to demonstrate Algorithmic Differentiation (see 3.3: exp_eps for a more complex example).

3.2.c: Mathematical Form
The exponential function can be defined by  \[
     \exp (x) = 1 + x^1 / 1 ! + x^2 / 2 ! + \cdots 
\] 
The second order approximation for the exponential function is  \[
{\rm exp\_2} (x) =  1 + x + x^2 / 2 
\] 


3.2.d: include
The include command in the syntax is relative to
     cppad-
yy-mm-dd/introduction/exp_apx
where cppad-yy-mm-dd is the distribution directory created during the beginning steps of the 2: installation of CppAD.

3.2.e: x
The argument x has prototype
     const 
Type &x
(see Type below). It specifies the point at which to evaluate the approximation for the second order exponential approximation.

3.2.f: y
The result y has prototype
     
Type y
It is the value of the exponential function approximation defined above.

3.2.g: Type
If u and v are Type objects and i is an int:
Operation Result Type Description
Type(i) Type object with value equal to i
u = v Type new u (and result) is value of v
u * v Type result is value of  u * v
u / v Type result is value of  u / v
u + v Type result is value of  u + v

3.2.h: Contents
exp_2.hpp: 3.2.1exp_2: Implementation
exp_2.cpp: 3.2.2exp_2: Test
exp_2_for0: 3.2.3exp_2: Operation Sequence and Zero Order Forward Mode
exp_2_for1: 3.2.4exp_2: First Order Forward Mode
exp_2_rev1: 3.2.5exp_2: First Order Reverse Mode
exp_2_for2: 3.2.6exp_2: Second Order Forward Mode
exp_2_rev2: 3.2.7exp_2: Second Order Reverse Mode
exp_2_cppad: 3.2.8exp_2: CppAD Forward and Reverse Sweeps

3.2.i: Implementation
The file 3.2.1: exp_2.hpp contains a C++ implementation of this function.

3.2.j: Test
The file 3.2.2: exp_2.cpp contains a test of this implementation. It returns true for success and false for failure.

3.2.k: Exercises
  1. Suppose that we make the call
     
    	double x = .1;
    	double y = exp_2(x);
    
    What is the value assigned to v1, v2, ... ,v5 in 3.2.1: exp_2.hpp ?
  2. Extend the routine exp_2.hpp to a routine exp_3.hpp that computes  \[
         1 + x^2 / 2 ! + x^3 / 3 !
    \] 
    Do this in a way that only assigns one value to each variable (as exp_2 does).
  3. Suppose that we make the call
     
    	double x = .5;
    	double y = exp_3(x);
    
    using exp_3 created in the previous problem. What is the value assigned to the new variables in exp_3 (variables that are in exp_3 and not in exp_2) ?

Input File: introduction/exp_apx/exp_2.hpp
3.2.1: exp_2: Implementation
 
template <class Type>
Type exp_2(const Type &x) 
{       Type v1  = x;                // v1 = x
        Type v2  = Type(1) + v1;     // v2 = 1 + x
        Type v3  = v1 * v1;          // v3 = x^2
        Type v4  = v3 / Type(2);     // v4 = x^2 / 2 
        Type v5  = v2 + v4;          // v5 = 1 + x + x^2 / 2
        return v5;                   // exp_2(x) = 1 + x + x^2 / 2
}

Input File: introduction/exp_apx/exp_2.omh
3.2.2: exp_2: Test
 
# include <cmath>           // define fabs function
# include "exp_2.hpp"       // definition of exp_2 algorithm
bool exp_2(void)
{	double x     = .5;
	double check = 1 + x + x * x / 2.; 
	bool   ok    = std::fabs( exp_2(x) - check ) <= 1e-10; 
	return ok;
}

Input File: introduction/exp_apx/exp_2.omh
3.2.3: exp_2: Operation Sequence and Zero Order Forward Mode

3.2.3.a: Mathematical Form
The operation sequence (see below) corresponding to the algorithm 3.2.1: exp_2.hpp is the same for all values of x. The mathematical form for the corresponding function is  \[
     f(x) = 1 + x + x^2 / 2
\] 
An algorithmic differentiation package does not operate on the mathematical function  f(x) but rather on the particular algorithm used to compute the function (in this case 3.2.1: exp_2.hpp ).

3.2.3.b: Zero Order Expansion
In general, a zero order forward sweep is given a vector  x^{(0)} \in \R^n and it returns the corresponding vector  y^{(0)} \in \R^m given by  \[
     y^{(0)} = f( x^{(0)} )
\]
The superscript  (0) denotes zero order derivative; i.e., it is equal to the value of the corresponding variable. For the example we are considering here, both  n and  m are equal to one.

3.2.3.c: Operation Sequence
An atomic Type operation is an operation that has a Type result and is not made up of other more basic operations. A sequence of atomic Type operations is called a Type operation sequence. Given an C++ algorithm and its inputs, there is a corresponding Type operation sequence for each type. If Type is clear from the context, we drop it and just refer to the operation sequence.

We consider the case where 3.2.1: exp_2.hpp is executed with  x^{(0)} = .5 . The table below contains the corresponding operation sequence and the results of a zero order sweep.

3.2.3.c.a: Index
The Index column contains the index in the operation sequence of the corresponding atomic operation and variable. A Forward sweep starts with the first operation and ends with the last.

3.2.3.c.b: Code
The Code column contains the C++ source code corresponding to the corresponding atomic operation in the sequence.

3.2.3.c.c: Operation
The Operation column contains the mathematical function corresponding to each atomic operation in the sequence.

3.2.3.c.d: Zero Order
The Zero Order column contains the zero order derivative for the corresponding variable in the operation sequence. Forward mode refers to the fact that these coefficients are computed in the same order as the original algorithm; i.e, in order of increasing index in the operation sequence.

3.2.3.c.e: Sweep
Index    Code    Operation    Zero Order
1    Type v1 = x;  v_1 = x   v_1^{(0)} = 0.5
2    Type v2 = Type(1) + v1;  v_2 = 1 + v_1   v_2^{(0)} = 1.5
3    Type v3 = v1 * v1;  v_3 = v_1 * v_1   v_3^{(0)} = 0.25
4    Type v4 = v3 / Type(2);  v_4 = v_3 / 2  v_4^{(0)} = 0.125
5    Type v5 = v2 + v4;  v_5 = v_2 + v_4   v_5^{(0)} = 1.625
3.2.3.d: Return Value
The return value for this case is  \[
     1.625 =
     v_5^{(0)} =
     f( x^{(0)} )
\] 


3.2.3.e: Verification
The file 3.2.3.1: exp_2_for0.cpp contains a routine that verifies the values computed above. It returns true for success and false for failure.

3.2.3.f: Exercises
  1. Suppose that  x^{(0)} = .2 , what is the result of a zero order forward sweep for the operation sequence above; i.e., what are the corresponding values for  \[
         v_1^{(0)} , v_2^{(0)} , \cdots , v_5^{(0)}
    \]
  2. Create a modified version of 3.2.3.1: exp_2_for0.cpp that verifies the values you obtained for the previous exercise.
  3. Create and run a main program that reports the result of calling the modified version of 3.2.3.1: exp_2_for0.cpp in the previous exercise.

Input File: introduction/exp_apx/exp_2.omh
3.2.3.1: exp_2: Verify Zero Order Forward Sweep
 # include <cmath>            // for fabs function
bool exp_2_for0(double *v0)  // double v0[6]
{	bool  ok = true;
	double x = .5;

	v0[1] = x;                                  // v1 = x
	ok  &= std::fabs( v0[1] - 0.5) < 1e-10;

	v0[2] = 1. + v0[1];                         // v2 = 1 + v1
	ok  &= std::fabs( v0[2] - 1.5) < 1e-10;

	v0[3] = v0[1] * v0[1];                      // v3 = v1 * v1
	ok  &= std::fabs( v0[3] - 0.25) < 1e-10;

	v0[4] = v0[3] / 2.;                         // v4 = v3 / 2
	ok  &= std::fabs( v0[4] - 0.125) < 1e-10;

	v0[5] = v0[2] + v0[4];                      // v5  = v2 + v4
	ok  &= std::fabs( v0[5] - 1.625) < 1e-10;

	return ok;
}
bool exp_2_for0(void)
{	double v0[6];
	return exp_2_for0(v0);
}

Input File: introduction/exp_apx/exp_2_for0.cpp
3.2.4: exp_2: First Order Forward Mode

3.2.4.a: First Order Expansion
We define  x(t) near  t = 0 by the first order expansion  \[
     x(t) = x^{(0)} + x^{(1)} * t
\]
it follows that  x^{(0)} is the zero, and  x^{(1)} the first, order derivative of  x(t) at  t = 0 .

3.2.4.b: Purpose
In general, a first order forward sweep is given the 3.2.3.b: zero order derivative for all of the variables in an operation sequence, and the first order derivatives for the independent variables. It uses these to compute the first order derivatives, and thereby obtain the first order expansion, for all the other variables in the operation sequence.

3.2.4.c: Mathematical Form
Suppose that we use the algorithm 3.2.1: exp_2.hpp to compute  \[
     f(x) = 1 + x + x^2 / 2
\] 
The corresponding derivative function is  \[
     \partial_x f (x) =   1 + x
\] 
An algorithmic differentiation package does not operate on the mathematical form of the function, or its derivative, but rather on the 3.2.3.c: operation sequence for the for the algorithm that is used to evaluate the function.

3.2.4.d: Operation Sequence
We consider the case where 3.2.1: exp_2.hpp is executed with  x = .5 . The corresponding operation sequence and zero order forward mode values (see 3.2.3.c.e: zero order sweep ) are inputs and are used by a first order forward sweep.

3.2.4.d.a: Index
The Index column contains the index in the operation sequence of the corresponding atomic operation. A Forward sweep starts with the first operation and ends with the last.

3.2.4.d.b: Operation
The Operation column contains the mathematical function corresponding to each atomic operation in the sequence.

3.2.4.d.c: Zero Order
The Zero Order column contains the zero order derivatives for the corresponding variable in the operation sequence (see 3.2.3.c.e: zero order sweep ).

3.2.4.d.d: Derivative
The Derivative column contains the mathematical function corresponding to the derivative with respect to  t , at  t = 0 , for each variable in the sequence.

3.2.4.d.e: First Order
The First Order column contains the first order derivatives for the corresponding variable in the operation sequence; i.e.,  \[
     v_j (t) = v_j^{(0)} + v_j^{(1)} t
\] 
We use  x^{(0)} = 1 so that differentiation with respect to  t , at  t = 0 , is the same partial differentiation with respect to  x at  x = x^{(0)} .

3.2.4.d.f: Sweep
Index    Operation    Zero Order    Derivative    First Order
1     v_1 = x  0.5  v_1^{(1)} = x^{(1)}    v_1^{(1)} = 1
2     v_2 = 1 + v_1 1.5  v_2^{(1)} = v_1^{(1)}  v_2^{(1)} = 1
3     v_3 = v_1 * v_1 0.25  v_3^{(1)} = 2 * v_1^{(0)} * v_1^{(1)}  v_3^{(1)} = 1
4     v_4 = v_3 / 2 0.125  v_4^{(1)} = v_3^{(1)} / 2  v_4^{(1)} = 0.5
5    v_5 = v_2 + v_4 1.625  v_5^{(1)} = v_2^{(1)} + v_4^{(1)}  v_5^{(1)} = 1.5
3.2.4.e: Return Value
The derivative of the return value for this case is  \[
\begin{array}{rcl}
     1.5 
     & = &
     v_5^{(1)} =
     \left[ \D{v_5}{t} \right]_{t=0} = 
     \left[ \D{}{t} f ( x^{(0)} + x^{(1)} t ) \right]_{t=0}
     \\
     & = &
     f^{(1)} ( x^{(0)} ) * x^{(1)} = 
     f^{(1)} ( x^{(0)} )
\end{array}
\] 
(We have used the fact that  x^{(1)} = 1 .)

3.2.4.f: Verification
The file 3.2.4.1: exp_2_for1.cpp contains a routine which verifies the values computed above. It returns true for success and false for failure.

3.2.4.g: Exercises
  1. Which statement in the routine defined by 3.2.4.1: exp_2_for1.cpp uses the values that are calculated by the routine defined by 3.2.3.1: exp_2_for0.cpp ?
  2. Suppose that  x = .1 , what are the results of a zero and first order forward sweep for the operation sequence above; i.e., what are the corresponding values for  v_1^{(0)}, v_2^{(0)}, \cdots , v_5^{(0)} and  v_1^{(1)}, v_2^{(1)}, \cdots , v_5^{(1)} ?
  3. Create a modified version of 3.2.4.1: exp_2_for1.cpp that verifies the derivative values from the previous exercise. Also create and run a main program that reports the result of calling the modified version of 3.2.4.1: exp_2_for1.cpp .

Input File: introduction/exp_apx/exp_2.omh
3.2.4.1: exp_2: Verify First Order Forward Sweep
 # include <cmath>                   // prototype for fabs
extern bool exp_2_for0(double *v0); // computes zero order forward sweep
bool exp_2_for1(double *v1)         // double v1[6]
{	bool ok = true;
	double v0[6];

	// set the value of v0[j] for j = 1 , ... , 5
	ok &= exp_2_for0(v0);

	v1[1] = 1.;                                     // v1 = x
	ok    &= std::fabs( v1[1] - 1. ) <= 1e-10;

	v1[2] = v1[1];                                  // v2 = 1 + v1
	ok    &= std::fabs( v1[2] - 1. ) <= 1e-10;

	v1[3] = v1[1] * v0[1] + v0[1] * v1[1];          // v3 = v1 * v1
	ok    &= std::fabs( v1[3] - 1. ) <= 1e-10;

	v1[4] = v1[3] / 2.;                             // v4 = v3 / 2
	ok    &= std::fabs( v1[4] - 0.5) <= 1e-10;

	v1[5] = v1[2] + v1[4];                          // v5 = v2 + v4
	ok    &= std::fabs( v1[5] - 1.5) <= 1e-10;

	return ok;
}
bool exp_2_for1(void)
{	double v1[6];
	return exp_2_for1(v1);
}

Input File: introduction/exp_apx/exp_2_for1.cpp
3.2.5: exp_2: First Order Reverse Mode

3.2.5.a: Purpose
First order reverse mode uses the 3.2.3.c: operation sequence , and zero order forward sweep values, to compute the first order derivative of one dependent variable with respect to all the independent variables. The computations are done in reverse of the order of the computations in the original algorithm.

3.2.5.b: Mathematical Form
Suppose that we use the algorithm 3.2.1: exp_2.hpp to compute  \[
     f(x) = 1 + x + x^2 / 2
\] 
The corresponding derivative function is  \[
     \partial_x f (x) =   1 + x
\] 


3.2.5.c: f_5
For our example, we chose to compute the derivative of the value returned by 3.2.1: exp_2.hpp which is equal to the symbol  v_5 in the 3.2.3.c: exp_2 operation sequence . We begin with the function  f_5  where  v_5 is both an argument and the value of the function; i.e.,  \[
\begin{array}{rcl}
f_5 ( v_1 , v_2 , v_3 , v_4 , v_5 ) & = & v_5 
\\
\D{f_5}{v_5} & = & 1
\end{array}
\] 
All the other partial derivatives of  f_5  are zero.

3.2.5.d: Index 5: f_4
Reverse mode starts with the last operation in the sequence. For the case in question, this is the operation with index 5,  \[
     v_5 = v_2 + v_4
\] 
We define the function  f_4 ( v_1 , v_2 , v_3 , v_4 )  as equal to  f_5  except that  v_5  is eliminated using this operation; i.e.  \[
f_4  = 
f_5 [  v_1 , v_2 , v_3 , v_4 , v_5 ( v_2 , v_4 ) ]
\] 
It follows that  \[
\begin{array}{rcll}
\D{f_4}{v_2} 
& = & \D{f_5}{v_2} + 
     \D{f_5}{v_5} * \D{v_5}{v_2} 
& = 1
\\
\D{f_4}{v_4} 
& = & \D{f_5}{v_4} + 
     \D{f_5}{v_5} * \D{v_5}{v_4} 
& = 1
\end{array}
\] 
All the other partial derivatives of  f_4 are zero.

3.2.5.e: Index 4: f_3
The next operation has index 4,  \[
     v_4 = v_3 / 2
\] 
We define the function  f_3 (  v_1 , v_2 , v_3 )  as equal to  f_4  except that  v_4  is eliminated using this operation; i.e.,  \[
f_3 = 
f_4 [ v_1 , v_2 , v_3 , v_4 ( v_3 ) ]
\] 
It follows that  \[
\begin{array}{rcll}
\D{f_3}{v_1}
& = & \D{f_4}{v_1}
& = 0
\\
\D{f_3}{v_2} 
& = & \D{f_4}{v_2}
& = 1
\\
\D{f_3}{v_3} 
& = & \D{f_4}{v_3} + 
     \D{f_4}{v_4} * \D{v_4}{v_3} 
& = 0.5
\end{array}
\] 


3.2.5.f: Index 3: f_2
The next operation has index 3,  \[
     v_3 = v_1 * v_1
\] 
We define the function  f_2 ( v_1 , v_2 )  as equal to  f_3  except that  v_3  is eliminated using this operation; i.e.,  \[
f_2 = 
f_3 [ v_1 , v_2 , v_3 ( v_1 ) ]
\] 
Note that the value of  v_1 is equal to  x which is .5 for this evaluation. It follows that  \[
\begin{array}{rcll}
\D{f_2}{v_1}
& = & \D{f_3}{v_1} +
     \D{f_3}{v_3} * \D{v_3}{v_1} 
& = 0.5
\\
\D{f_2}{v_2} 
& = & \D{f_3}{v_2}
& = 1
\end{array}
\] 


3.2.5.g: Index 2: f_1
The next operation has index 2,  \[
     v_2 = 1 + v_1
\] 
We define the function  f_1 ( v_1 )  as equal to  f_2  except that  v_2  is eliminated using this operation; i.e.,  \[
f_1 = 
f_2 [ v_1 , v_2 ( v_1 ) ]
\] 
It follows that  \[
\begin{array}{rcll}
\D{f_1}{v_1}
& = & \D{f_2}{v_1} +
     \D{f_2}{v_2} * \D{v_2}{v_1} 
& = 1.5
\end{array}
\] 
Note that  v_1 is equal to  x , so the derivative of this is the derivative of the function defined by 3.2.1: exp_2.hpp at  x = .5 .

3.2.5.h: Verification
The file 3.2.5.1: exp_2_rev1.cpp contains a routine which verifies the values computed above. It returns true for success and false for failure. It only tests the partial derivatives of  f_j that might not be equal to the corresponding partials of  f_{j+1} ; i.e., the other partials of  f_j must be equal to the corresponding partials of  f_{j+1} .

3.2.5.i: Exercises
  1. Which statement in the routine defined by 3.2.5.1: exp_2_rev1.cpp uses the values that are calculated by the routine defined by 3.2.3.1: exp_2_for0.cpp ?
  2. Consider the case where  x = .1 and we first preform a zero order forward sweep for the operation sequence used above. What are the results of a first order reverse sweep; i.e., what are the corresponding derivatives of  f_5 , f_4 , \ldots , f_1 .
  3. Create a modified version of 3.2.5.1: exp_2_rev1.cpp that verifies the values you obtained for the previous exercise. Also create and run a main program that reports the result of calling the modified version of 3.2.5.1: exp_2_rev1.cpp .

Input File: introduction/exp_apx/exp_2.omh
3.2.5.1: exp_2: Verify First Order Reverse Sweep
 # include <cstddef>                 // define size_t
# include <cmath>                   // prototype for fabs
extern bool exp_2_for0(double *v0); // computes zero order forward sweep
bool exp_2_rev1(void)
{	bool ok = true;

	// set the value of v0[j] for j = 1 , ... , 5
	double v0[6];
	ok &= exp_2_for0(v0);

	// initial all partial derivatives as zero
	double f_v[6];
	size_t j;
	for(j = 0; j < 6; j++)
		f_v[j] = 0.;

	// set partial derivative for f5
	f_v[5] = 1.;
	ok &= std::fabs( f_v[5] - 1. ) <= 1e-10; // f5_v5

	// f4 = f5( v1 , v2 , v3 , v4 , v2 + v4 )
	f_v[2] += f_v[5] * 1.;
	f_v[4] += f_v[5] * 1.;
	ok &= std::fabs( f_v[2] - 1. ) <= 1e-10; // f4_v2
	ok &= std::fabs( f_v[4] - 1. ) <= 1e-10; // f4_v4

	// f3 = f4( v1 , v2 , v3 , v3 / 2 )
	f_v[3] += f_v[4] / 2.;
	ok &= std::fabs( f_v[3] - 0.5) <= 1e-10; // f3_v3

	// f2 = f3( v1 , v2 , v1 * v1 )
	f_v[1] += f_v[3] * 2. * v0[1];
	ok &= std::fabs( f_v[1] - 0.5) <= 1e-10; // f2_v1

	// f1 = f2( v1 , 1 + v1 )
	f_v[1] += f_v[2] * 1.;
	ok &= std::fabs( f_v[1] - 1.5) <= 1e-10; // f1_v1

	return ok;
}

Input File: introduction/exp_apx/exp_2_rev1.cpp
3.2.6: exp_2: Second Order Forward Mode

3.2.6.a: Second Order Expansion
We define  x(t) near  t = 0 by the second order expansion  \[
     x(t) = x^{(0)} + x^{(1)} * t + x^{(2)} * t^2 / 2
\]
It follows that for  k = 0 , 1 , 2 ,  \[
     x^{(k)} = \dpow{k}{t} x (0)
\] 


3.2.6.b: Purpose
In general, a second order forward sweep is given the 3.2.4.a: first order expansion for all of the variables in an operation sequence, and the second order derivatives for the independent variables. It uses these to compute the second order derivative, and thereby obtain the second order expansion, for all the variables in the operation sequence.

3.2.6.c: Mathematical Form
Suppose that we use the algorithm 3.2.1: exp_2.hpp to compute  \[
     f(x) = 1 + x + x^2 / 2
\] 
The corresponding second derivative function is  \[
     \Dpow{2}{x} f (x) =   1
\] 


3.2.6.d: Operation Sequence
We consider the case where 3.2.1: exp_2.hpp is executed with  x = .5 . The corresponding operation sequence, zero order forward sweep values, and first order forward sweep values are inputs and are used by a second order forward sweep.

3.2.6.d.a: Index
The Index column contains the index in the operation sequence of the corresponding atomic operation. A Forward sweep starts with the first operation and ends with the last.

3.2.6.d.b: Zero
The Zero column contains the zero order sweep results for the corresponding variable in the operation sequence (see 3.2.3.c.e: zero order sweep ).

3.2.6.d.c: Operation
The Operation column contains the first order sweep operation for this variable.

3.2.6.d.d: First
The First column contains the first order sweep results for the corresponding variable in the operation sequence (see 3.2.4.d.f: first order sweep ).

3.2.6.d.e: Derivative
The Derivative column contains the mathematical function corresponding to the second derivative with respect to  t , at  t = 0 , for each variable in the sequence.

3.2.6.d.f: Second
The Second column contains the second order derivatives for the corresponding variable in the operation sequence; i.e., the second order expansion for the i-th variable is given by  \[
     v_i (t) = v_i^{(0)} + v_i^{(1)} * t +  v_i^{(2)} * t^2 / 2
\] 
We use  x^{(0)} = 1 , and  x^{(2)} = 0 so that second order differentiation with respect to  t , at  t = 0 , is the same as the second partial differentiation with respect to  x at  x = x^{(0)} .

3.2.6.d.g: Sweep
Index    Zero    Operation    First    Derivative    Second
1 0.5     v_1^{(1)} = x^{(1)}  1  v_1^{(2)} = x^{(2)}  v_1^{(2)} = 0
2 1.5     v_2^{(1)} = v_1^{(1)} 1  v_2^{(2)} = v_1^{(2)}  v_2^{(2)} = 0
3 0.25     v_3^{(1)} = 2 * v_1^{(0)} * v_1^{(1)} 1  v_3^{(2)} = 2 * (v_1^{(1)} * v_1^{(1)} + v_1^{(0)} * v_1^{(2)} )  v_3^{(2)} = 2
4 0.125     v_4^{(1)} = v_3^{(1)} / 2 .5  v_4^{(2)} = v_3^{(2)} / 2  v_4^{(2)} = 1
5 1.625    v_5^{(1)} = v_2^{(1)} + v_4^{(1)} 1.5  v_5^{(2)} = v_2^{(2)} + v_4^{(2)}  v_5^{(2)} = 1
3.2.6.e: Return Value
The second derivative of the return value for this case is  \[
\begin{array}{rcl}
     1 
     & = &
     v_5^{(2)} =
     \left[ \Dpow{2}{t} v_5 \right]_{t=0} =
     \left[ \Dpow{2}{t} f( x^{(0)} + x^{(1)} * t ) \right]_{t=0}
     \\
     & = &
     x^{(1)} * \Dpow{2}{x} f ( x^{(0)} ) * x^{(1)} = 
     \Dpow{2}{x} f ( x^{(0)} )
\end{array}
\] 
(We have used the fact that  x^{(1)} = 1 and  x^{(2)} = 0 .)

3.2.6.f: Verification
The file 3.2.6.1: exp_2_for2.cpp contains a routine which verifies the values computed above. It returns true for success and false for failure.

3.2.6.g: Exercises
  1. Which statement in the routine defined by 3.2.6.1: exp_2_for2.cpp uses the values that are calculated by the routine defined by 3.2.4.1: exp_2_for1.cpp ?
  2. Suppose that  x = .1 , what are the results of a zero, first, and second order forward sweep for the operation sequence above; i.e., what are the corresponding values for  v_i^{(k)} for  i = 1, \ldots , 5 and  k = 0, 1, 2 .
  3. Create a modified version of 3.2.6.1: exp_2_for2.cpp that verifies the derivative values from the previous exercise. Also create and run a main program that reports the result of calling the modified version of 3.2.6.1: exp_2_for2.cpp .

Input File: introduction/exp_apx/exp_2.omh
3.2.6.1: exp_2: Verify Second Order Forward Sweep
 # include <cmath>                   // prototype for fabs
extern bool exp_2_for0(double *v0); // computes zero order forward sweep
extern bool exp_2_for1(double *v1); // computes first order forward sweep
bool exp_2_for2(void)
{	bool ok = true;
	double v0[6], v1[6], v2[6];

	// set the value of v0[j], v1[j], for j = 1 , ... , 5
	ok &= exp_2_for0(v0);
	ok &= exp_2_for1(v1);

	v2[1] = 0.;                                     // v1 = x
	ok    &= std::fabs( v2[1] - 0. ) <= 1e-10;

	v2[2] = v2[1];                                  // v2 = 1 + v1
	ok    &= std::fabs( v2[2] - 0. ) <= 1e-10;

	v2[3] = 2.*(v0[1]*v2[1] + v1[1]*v1[1]);         // v3 = v1 * v1
	ok    &= std::fabs( v2[3] - 2. ) <= 1e-10;

	v2[4] = v2[3] / 2.;                             // v4 = v3 / 2
	ok    &= std::fabs( v2[4] - 1. ) <= 1e-10;

	v2[5] = v2[2] + v2[4];                          // v5 = v2 + v4
	ok    &= std::fabs( v2[5] - 1. ) <= 1e-10;

	return ok;
}

Input File: introduction/exp_apx/exp_2_for2.cpp
3.2.7: exp_2: Second Order Reverse Mode

3.2.7.a: Purpose
In general, a second order reverse sweep is given the 3.2.4.a: first order expansion for all of the variables in an operation sequence. Given a choice of a particular variable, it computes the derivative, of that variables first order expansion coefficient, with respect to all of the independent variables.

3.2.7.b: Mathematical Form
Suppose that we use the algorithm 3.2.1: exp_2.hpp to compute  \[
     f(x) = 1 + x + x^2 / 2
\] 
The corresponding second derivative is  \[
     \Dpow{2}{x} f (x) =   1
\] 


3.2.7.c: f_5
For our example, we chose to compute the derivative of  v_5^{(1)} with respect to all the independent variable. For the case computed for the 3.2.4.d.f: first order sweep ,  v_5^{(1)} is the derivative of the value returned by 3.2.1: exp_2.hpp . This the value computed will be the second derivative of the value returned by 3.2.1: exp_2.hpp . We begin with the function  f_5  where  v_5^{(1)} is both an argument and the value of the function; i.e.,  \[
\begin{array}{rcl}
f_5 \left( 
     v_1^{(0)}, v_1^{(1)} , \ldots  , v_5^{(0)} , v_5^{(1)} 
\right) 
& = & v_5^{(1)} 
\\
\D{f_5}{v_5^{(1)}} & = & 1
\end{array}
\] 
All the other partial derivatives of  f_5  are zero.

3.2.7.d: Index 5: f_4
Second order reverse mode starts with the last operation in the sequence. For the case in question, this is the operation with index 5. The zero and first order sweep representations of this operation are  \[
\begin{array}{rcl}
     v_5^{(0)} & = & v_2^{(0)} + v_4^{(0)}
     \\
     v_5^{(1)} & = & v_2^{(1)} + v_4^{(1)}
\end{array}
\] 
We define the function  f_4 \left( v_1^{(0)} , \ldots , v_4^{(1)} \right)  as equal to  f_5  except that  v_5^{(0)}  and  v_5^{(1)} are eliminated using this operation; i.e.  \[
f_4  = 
f_5 \left[   v_1^{(0)} , \ldots , v_4^{(1)} , 
     v_5^{(0)} \left( v_2^{(0)} , v_4^{(0)} \right) ,  
     v_5^{(1)} \left( v_2^{(1)} , v_4^{(1)} \right) 
\right] 
\] 
It follows that  \[
\begin{array}{rcll}
\D{f_4}{v_2^{(1)}} 
& = & \D{f_5}{v_2^{(1)}} + 
     \D{f_5}{v_5^{(1)}} * \D{v_5^{(1)}}{v_2^{(1)}} 
& = 1
\\
\D{f_4}{v_4^{(1)}} 
& = & \D{f_5}{v_4^{(1)}} + 
     \D{f_5}{v_5^{(1)}} * \D{v_5}{v_4^{(1)}} 
& = 1
\end{array}
\] 
All the other partial derivatives of  f_4 are zero.

3.2.7.e: Index 4: f_3
The next operation has index 4,  \[
\begin{array}{rcl}
     v_4^{(0)} & = & v_3^{(0)} / 2
     \\
     v_4^{(1)} & = & v_3^{(1)} / 2
\end{array}
\] 
We define the function  f_3 \left(  v_1^{(0)} , \ldots , v_3^{(1)} \right)  as equal to  f_4  except that  v_4^{(0)} and  v_4^{(1)} are eliminated using this operation; i.e.,  \[
f_3 = 
f_4 \left[ v_1^{(0)} , \ldots , v_3^{(1)} ,
     v_4^{(0)} \left( v_3^{(0)} \right) ,
     v_4^{(1)} \left( v_3^{(1)} \right)
\right]
\] 
It follows that  \[
\begin{array}{rcll}
\D{f_3}{v_2^{(1)}} 
& = & \D{f_4}{v_2^{(1)}}
& = 1
\\
\D{f_3}{v_3^{(1)}} 
& = & \D{f_4}{v_3^{(1)}} + 
     \D{f_4}{v_4^{(1)}} * \D{v_4^{(1)}}{v_3^{(1)}} 
& = 0.5
\end{array}
\] 
All the other partial derivatives of  f_3 are zero.

3.2.7.f: Index 3: f_2
The next operation has index 3,  \[
\begin{array}{rcl}
     v_3^{(0)} & = & v_1^{(0)} * v_1^{(0)}
     \\
     v_3^{(1)} & = & 2 * v_1^{(0)} * v_1^{(1)}
\end{array}
\] 
We define the function  f_2 \left(  v_1^{(0)} , \ldots , v_2^{(1)} \right)  as equal to  f_3  except that  v_3^{(0)}  and  v_3^{(1)} are eliminated using this operation; i.e.,  \[
f_2 = 
f_3 \left[ v_1^{(0)} , \ldots , v_2^{(1)} ,
     v_3^{(0)} ( v_1^{(0)} ) ,
     v_3^{(1)} ( v_1^{(0)} , v_1^{(1)} ) 
\right]
\] 
Note that, from the 3.2.4.d.f: first order forward sweep , the value of  v_1^{(0)} is equal to  .5 and  v_1^{(1)} is equal 1. It follows that  \[
\begin{array}{rcll}
\D{f_2}{v_1^{(0)}}
& = & 
\D{f_3}{v_1^{(0)}} +
     \D{f_3}{v_3^{(0)}} * \D{v_3^{(0)}}{v_1^{(0)}}  +
     \D{f_3}{v_3^{(1)}} * \D{v_3^{(1)}}{v_1^{(0)}}  
& = 1
\\
\D{f_2}{v_1^{(1)}}
& = & 
\D{f_3}{v_1^{(1)}} +
     \D{f_3}{v_3^{(1)}} * \D{v_3^{(1)}}{v_1^{(1)}}  
& = 0.5 
\\
\D{f_2}{v_2^{(0)}} 
& = & \D{f_3}{v_2^{(0)}}
& = 0
\\
\D{f_2}{v_2^{(1)}} 
& = & \D{f_3}{v_2^{(1)}}
& = 1
\end{array}
\] 


3.2.7.g: Index 2: f_1
The next operation has index 2,  \[
\begin{array}{rcl}
     v_2^{(0)} & = & 1 + v_1^{(0)}
     \\
     v_2^{(1)} & = & v_1^{(1)}
\end{array}
\] 
We define the function  f_1 ( v_1^{(0)} , v_1^{(1)} )  as equal to  f_2  except that  v_2^{(0)}  and  v_2^{(1)}  are eliminated using this operation; i.e.,  \[
f_1 = 
f_2 \left[ v_1^{(0)} , v_1^{(1)} , 
     v_2^{(0)} ( v_1^{(0)} )  ,
     v_2^{(1)} ( v_1^{(1)} )
\right]
\] 
It follows that  \[
\begin{array}{rcll}
\D{f_1}{v_1^{(0)}}
& = & \D{f_2}{v_1^{(0)}} +
     \D{f_2}{v_2^{(0)}} * \D{v_2^{(0)}}{v_1^{(0)}} 
& = 1
\\
\D{f_1}{v_1^{(1)}}
& = & \D{f_2}{v_1^{(1)}} +
     \D{f_2}{v_2^{(1)}} * \D{v_2^{(1)}}{v_1^{(1)}} 
& = 1.5 
\end{array}
\] 
Note that  v_1 is equal to  x , so the second derivative of the function defined by 3.2.1: exp_2.hpp at  x = .5 is given by  \[
\Dpow{2}{x} v_5^{(0)} 
=
\D{ v_5^{(1)} }{x} 
=
\D{ v_5^{(1)} }{v_1^{(0)}} 

\D{f_1}{v_1^{(0)}} = 1
\] 
There is a theorem about Algorithmic Differentiation that explains why the other partial of  f_1 is equal to the first derivative of the function defined by 3.2.1: exp_2.hpp at  x = .5 .

3.2.7.h: Verification
The file 3.2.7.1: exp_2_rev2.cpp contains a routine which verifies the values computed above. It returns true for success and false for failure. It only tests the partial derivatives of  f_j that might not be equal to the corresponding partials of  f_{j+1} ; i.e., the other partials of  f_j must be equal to the corresponding partials of  f_{j+1} .

3.2.7.i: Exercises
  1. Which statement in the routine defined by 3.2.7.1: exp_2_rev2.cpp uses the values that are calculated by the routine defined by 3.2.3.1: exp_2_for0.cpp ? Which statements use values that are calculate by the routine defined in 3.2.4.1: exp_2_for1.cpp ?
  2. Consider the case where  x = .1 and we first preform a zero order forward sweep, then a first order sweep, for the operation sequence used above. What are the results of a second order reverse sweep; i.e., what are the corresponding derivatives of  f_5 , f_4 , \ldots , f_1 .
  3. Create a modified version of 3.2.7.1: exp_2_rev2.cpp that verifies the values you obtained for the previous exercise. Also create and run a main program that reports the result of calling the modified version of 3.2.7.1: exp_2_rev2.cpp .

Input File: introduction/exp_apx/exp_2.omh
3.2.7.1: exp_2: Verify Second Order Reverse Sweep
 # include <cstddef>                 // define size_t
# include <cmath>                   // prototype for fabs
extern bool exp_2_for0(double *v0); // computes zero order forward sweep
extern bool exp_2_for1(double *v1); // computes first order forward sweep
bool exp_2_rev2(void)
{	bool ok = true;

	// set the value of v0[j], v1[j] for j = 1 , ... , 5
	double v0[6], v1[6];
	ok &= exp_2_for0(v0);
	ok &= exp_2_for1(v1);

	// initial all partial derivatives as zero
	double f_v0[6], f_v1[6];
	size_t j;
	for(j = 0; j < 6; j++)
	{	f_v0[j] = 0.;
		f_v1[j] = 0.;
	}

	// set partial derivative for f_5
	f_v1[5] = 1.;
	ok &= std::fabs( f_v1[5] - 1. ) <= 1e-10; // partial f_5 w.r.t v_5^1

	// f_4 = f_5( v_1^0 , ... , v_4^1 , v_2^0 + v_4^0 , v_2^1 + v_4^1 )
	f_v0[2] += f_v0[5] * 1.;
	f_v0[4] += f_v0[5] * 1.;
	f_v1[2] += f_v1[5] * 1.;
	f_v1[4] += f_v1[5] * 1.;
	ok &= std::fabs( f_v0[2] - 0. ) <= 1e-10; // partial f_4 w.r.t. v_2^0
	ok &= std::fabs( f_v0[4] - 0. ) <= 1e-10; // partial f_4 w.r.t. v_4^0
	ok &= std::fabs( f_v1[2] - 1. ) <= 1e-10; // partial f_4 w.r.t. v_2^1
	ok &= std::fabs( f_v1[4] - 1. ) <= 1e-10; // partial f_4 w.r.t. v_4^1

	// f_3 = f_4( v_1^0 , ... , v_3^1, v_3^0 / 2 , v_3^1 / 2 )
	f_v0[3] += f_v0[4] / 2.;
	f_v1[3] += f_v1[4] / 2.;
	ok &= std::fabs( f_v0[3] - 0.  ) <= 1e-10; // partial f_3 w.r.t. v_3^0
	ok &= std::fabs( f_v1[3] - 0.5 ) <= 1e-10; // partial f_3 w.r.t. v_3^1

	// f_2 = f_3(  v_1^0 , ... , v_2^1, v_1^0 * v_1^0 , 2 * v_1^0 * v_1^1 )
	f_v0[1] += f_v0[3] * 2. * v0[1];
	f_v0[1] += f_v1[3] * 2. * v1[1];
	f_v1[1] += f_v1[3] * 2. * v0[1];
	ok &= std::fabs( f_v0[1] - 1.  ) <= 1e-10; // partial f_2 w.r.t. v_1^0
	ok &= std::fabs( f_v1[1] - 0.5 ) <= 1e-10; // partial f_2 w.r.t. v_1^1

	// f_1 = f_2( v_1^0 , v_1^1 , 1 + v_1^0 , v_1^1 )
	f_v0[1] += f_v0[2] * 1.;
	f_v1[1] += f_v1[2] * 1.;
	ok &= std::fabs( f_v0[1] - 1. ) <= 1e-10; // partial f_1 w.r.t. v_1^0
	ok &= std::fabs( f_v1[1] - 1.5) <= 1e-10; // partial f_1 w.r.t. v_1^1

	return ok;
}

Input File: introduction/exp_apx/exp_2_rev2.cpp
3.2.8: exp_2: CppAD Forward and Reverse Sweeps
.

3.2.8.a: Purpose
Use CppAD forward and reverse modes to compute the partial derivative with respect to  x , at the point  x = .5 , of the function
     exp_2(
x)
as defined by the 3.2.1: exp_2.hpp include file.

3.2.8.b: Exercises
  1. Create and test a modified version of the routine below that computes the same order derivatives with respect to  x , at the point  x = .1 of the function
         exp_2(
    x)
  2. Create a routine called
         exp_3(
    x)
    that evaluates the function  \[
         f(x) = 1 + x^2 / 2 + x^3 / 6
    \] 
    Test a modified version of the routine below that computes the derivative of  f(x) at the point  x = .5 .
 

# include <cppad/cppad.hpp>  // http://www.coin-or.org/CppAD/ 
# include "exp_2.hpp"        // second order exponential approximation
bool exp_2_cppad(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::vector;    // can use any simple vector template class
	using CppAD::NearEqual; // checks if values are nearly equal

	// domain space vector
	size_t n = 1; // dimension of the domain space
	vector< AD<double> > X(n);
	X[0] = .5;    // value of x for this operation sequence

	// declare independent variables and start recording operation sequence
	CppAD::Independent(X);

	// evaluate our exponential approximation
	AD<double> x   = X[0];
	AD<double> apx = exp_2(x);  

	// range space vector
	size_t m = 1;  // dimension of the range space
	vector< AD<double> > Y(m);
	Y[0] = apx;    // variable that represents only range space component

	// Create f: X -> Y corresponding to this operation sequence
	// and stop recording. This also executes a zero order forward 
	// sweep using values in X for x.
	CppAD::ADFun<double> f(X, Y);

	// first order forward sweep that computes
	// partial of exp_2(x) with respect to x
	vector<double> dx(n);  // differential in domain space
	vector<double> dy(m);  // differential in range space
	dx[0] = 1.;            // direction for partial derivative
	dy    = f.Forward(1, dx);
	double check = 1.5;
	ok   &= NearEqual(dy[0], check, 1e-10, 1e-10);

	// first order reverse sweep that computes the derivative
	vector<double>  w(m);   // weights for components of the range
	vector<double> dw(n);   // derivative of the weighted function
	w[0] = 1.;              // there is only one weight
	dw   = f.Reverse(1, w); // derivative of w[0] * exp_2(x)
	check = 1.5;            // partial of exp_2(x) with respect to x
	ok   &= NearEqual(dw[0], check, 1e-10, 1e-10);

	// second order forward sweep that computes
	// second partial of exp_2(x) with respect to x
	vector<double> x2(n);     // second order Taylor coefficients 
	vector<double> y2(m);  
	x2[0] = 0.;               // evaluate second partial .w.r.t. x
	y2    = f.Forward(2, x2);
	check = 0.5 * 1.;         // Taylor coef is 1/2 second derivative 
	ok   &= NearEqual(y2[0], check, 1e-10, 1e-10);

	// second order reverse sweep that computes
	// derivative of partial of exp_2(x) w.r.t. x
	dw.resize(2 * n);         // space for first and second derivatives
	dw    = f.Reverse(2, w);
	check = 1.;               // result should be second derivative
	ok   &= NearEqual(dw[0*2+1], check, 1e-10, 1e-10);

	return ok;
}


Input File: introduction/exp_apx/exp_2_cppad.cpp
3.3: An Epsilon Accurate Exponential Approximation

3.3.a: Syntax
# include "exp_eps.hpp"
y = exp_eps(xepsilon)

3.3.b: Purpose
This is a an example algorithm that is used to demonstrate how Algorithmic Differentiation works with loops and boolean decision variables (see 3.2: exp_2 for a simpler example).

3.3.c: Mathematical Function
The exponential function can be defined by  \[
     \exp (x) = 1 + x^1 / 1 ! + x^2 / 2 ! + \cdots 
\] 
We define  k ( x, \varepsilon )   as the smallest non-negative integer such that  \varepsilon \geq x^k / k ! ; i.e.,  \[
k( x, \varepsilon ) = 
     \min \{ k \in {\rm Z}_+ \; | \; \varepsilon \geq x^k / k ! \}
\] 
The mathematical form for our approximation of the exponential function is  \[
\begin{array}{rcl}
{\rm exp\_eps} (x , \varepsilon ) & = & \left\{
\begin{array}{ll}
\frac{1}{ {\rm exp\_eps} (-x , \varepsilon ) } 
     & {\rm if} \; x < 0 
\\
1 + x^1 / 1 ! + \cdots + x^{k( x, \varepsilon)} / k( x, \varepsilon ) !
     & {\rm otherwise}
\end{array}
\right.
\end{array}
\] 


3.3.d: include
The include command in the syntax is relative to
     cppad-
yy-mm-dd/introduction/exp_apx
where cppad-yy-mm-dd is the distribution directory created during the beginning steps of the 2: installation of CppAD.

3.3.e: x
The argument x has prototype
     const 
Type &x
(see Type below). It specifies the point at which to evaluate the approximation for the exponential function.

3.3.f: epsilon
The argument epsilon has prototype
     const 
Type &epsilon
It specifies the accuracy with which to approximate the exponential function value; i.e., it is the value of  \varepsilon in the exponential function approximation defined above.

3.3.g: y
The result y has prototype
     
Type y
It is the value of the exponential function approximation defined above.

3.3.h: Type
If u and v are Type objects and i is an int:
Operation Result Type Description
Type(i) Type object with value equal to i
u > v bool true, if u greater than v, an false otherwise
u = v Type new u (and result) is value of v
u * v Type result is value of  u * v
u / v Type result is value of  u / v
u + v Type result is value of  u + v
-u Type result is value of  - u

3.3.i: Implementation
The file 3.3.1: exp_eps.hpp contains a C++ implementation of this function.

3.3.j: Test
The file 3.3.2: exp_eps.cpp contains a test of this implementation. It returns true for success and false for failure.

3.3.k: Exercises
  1. Using the definition of  k( x, \varepsilon ) above, what is the value of  k(.5, 1) ,  k(.5, .1) , and  k(.5, .01) ?
  2. Suppose that we make the following call to exp_eps:
     
    	double x       = 1.;
    	double epsilon = .01;
    	double y = exp_eps(x, epsilon);
    
    What is the value assigned to k, temp, term, and sum the first time through the while loop in 3.3.1: exp_eps.hpp ?
  3. Continuing the previous exercise, what is the value assigned to k, temp, term, and sum the second time through the while loop in 3.3.1: exp_eps.hpp ?

Input File: introduction/exp_apx/exp_eps.hpp
3.3.1: exp_eps: Implementation
 
template <class Type>
Type exp_eps(const Type &x, const Type &epsilon)
{	// abs_x = |x|
	Type abs_x = x;
	if( Type(0) > x )
		abs_x = - x;
	// initialize
	int  k    = 0;          // initial order 
	Type term = 1.;         // term = |x|^k / k !
	Type sum  = term;       // initial sum
	while(term > epsilon)
	{	k         = k + 1;          // order for next term
		Type temp = term * abs_x;   // term = |x|^k / (k-1)!
		term      = temp / Type(k); // term = |x|^k / k !
		sum       = sum + term;     // sum  = 1 + ... + |x|^k / k !
	}
	// In the case where x is negative, use exp(x) = 1 / exp(-|x|)
	if( Type(0) > x ) 
		sum = Type(1) / sum;
	return sum;
}

Input File: introduction/exp_apx/exp_eps.omh
3.3.2: exp_eps: Test of exp_eps
 
# include <cmath>             // for fabs function
# include "exp_eps.hpp"       // definition of exp_eps algorithm
bool exp_eps(void)
{	double x       = .5;
	double epsilon = .2;
	double check   = 1 + .5 + .125; // include 1 term less than epsilon
	bool   ok      = std::fabs( exp_eps(x, epsilon) - check ) <= 1e-10; 
	return ok;
}

Input File: introduction/exp_apx/exp_eps.omh
3.3.3: exp_eps: Operation Sequence and Zero Order Forward Sweep

3.3.3.a: Mathematical Form
Suppose that we use the algorithm 3.3.1: exp_eps.hpp to compute exp_eps(xepsilon) with x is equal to .5 and epsilon is equal to .2. For this case, the mathematical form for the operation sequence corresponding to the exp_eps is  \[
     f( x , \varepsilon ) = 1 + x + x^2 / 2  
\] 
Note that, for these particular values of x and epsilon, this is the same as the mathematical form for 3.2.3.a: exp_2 .

3.3.3.b: Operation Sequence
We consider the 9.4.g.b: operation sequence corresponding to the algorithm 3.3.1: exp_eps.hpp with the argument x is equal to .5 and epsilon is equal to .2.

3.3.3.b.a: Variable
We refer to values that depend on the input variables x and epsilon as variables.

3.3.3.b.b: Parameter
We refer to values that do not depend on the input variables x or epsilon as parameters. Operations where the result is a parameter are not included in the zero order sweep below.

3.3.3.b.c: Index
The Index column contains the index in the operation sequence of the corresponding atomic operation and variable. A Forward sweep starts with the first operation and ends with the last.

3.3.3.b.d: Code
The Code column contains the C++ source code corresponding to the corresponding atomic operation in the sequence.

3.3.3.b.e: Operation
The Operation column contains the mathematical function corresponding to each atomic operation in the sequence.

3.3.3.b.f: Zero Order
The Zero Order column contains the 3.2.3.b: zero order derivative for the corresponding variable in the operation sequence. Forward mode refers to the fact that these coefficients are computed in the same order as the original algorithm; i.e., in order of increasing index.

3.3.3.b.g: Sweep
Index    Code    Operation    Zero Order
1    abs_x = x;  v_1 = x   v_1^{(0)} = 0.5
2    temp = term * abs_x;  v_2 = 1 * v_1   v_2^{(0)} = 0.5
3    term = temp / Type(k);  v_3 = v_2 / 1  v_3^{(0)} = 0.5
4    sum = sum + term;  v_4 = 1 + v_3   v_4^{(0)} = 1.5
5    temp = term * abs_x;  v_5 = v_3 * v_1   v_5^{(0)} = 0.25
6    term = temp / Type(k);  v_6 = v_5 / 2  v_6^{(0)} = 0.125
7    sum = sum + term;  v_7 = v_4 + v_6   v_7^{(0)} = 1.625
3.3.3.c: Return Value
The return value for this case is  \[
     1.625 =
     v_7^{(0)} =
     f ( x^{(0)} , \varepsilon^{(0)} )
\] 


3.3.3.d: Comparisons
If x were negative, or if epsilon were a much smaller or much larger value, the results of the following comparisons could be different:
 
	if( Type(0) > x ) 
	while(term > epsilon)
This in turn would result in a different operation sequence. Thus the operation sequence above only corresponds to 3.3.1: exp_eps.hpp for values of x and epsilon within a certain range. Note that there is a neighborhood of  x = 0.5 for which the comparisons would have the same result and hence the operation sequence would be the same.

3.3.3.e: Verification
The file 3.3.3.1: exp_eps_for0.cpp contains a routine that verifies the values computed above. It returns true for success and false for failure.

3.3.3.f: Exercises
  1. Suppose that  x^{(0)} = .1 , what is the result of a zero order forward sweep for the operation sequence above; i.e., what are the corresponding values for  v_1^{(0)} , v_2^{(0)} , \ldots , v_7^{(0)} .
  2. Create a modified version of 3.3.3.1: exp_eps_for0.cpp that verifies the values you obtained for the previous exercise.
  3. Create and run a main program that reports the result of calling the modified version of 3.3.3.1: exp_eps_for0.cpp in the previous exercise.

Input File: introduction/exp_apx/exp_eps.omh
3.3.3.1: exp_eps: Verify Zero Order Forward Sweep
 # include <cmath>                // for fabs function
bool exp_eps_for0(double *v0)    // double v0[8]
{	bool  ok = true;
	double x = .5;

	v0[1] = x;                                  // abs_x = x;
	ok  &= std::fabs( v0[1] - 0.5) < 1e-10;

	v0[2] = 1. * v0[1];                         // temp = term * abs_x;
	ok  &= std::fabs( v0[2] - 0.5) < 1e-10;

	v0[3] = v0[2] / 1.;                         // term = temp / Type(k);
	ok  &= std::fabs( v0[3] - 0.5) < 1e-10;

	v0[4] = 1. + v0[3];                         // sum = sum + term;
	ok  &= std::fabs( v0[4] - 1.5) < 1e-10;

	v0[5] = v0[3] * v0[1];                      // temp = term * abs_x;
	ok  &= std::fabs( v0[5] - 0.25) < 1e-10;

	v0[6] = v0[5] / 2.;                         // term = temp / Type(k);
	ok  &= std::fabs( v0[6] - 0.125) < 1e-10;

	v0[7] = v0[4] + v0[6];                      // sum = sum + term;
	ok  &= std::fabs( v0[7] - 1.625) < 1e-10;

	return ok;
}
bool exp_eps_for0(void)
{	double v0[8];
	return exp_eps_for0(v0);
}

Input File: introduction/exp_apx/exp_eps_for0.cpp
3.3.4: exp_eps: First Order Forward Sweep

3.3.4.a: First Order Expansion
We define  x(t) and  \varepsilon(t) ] near  t = 0 by the first order expansions  \[
\begin{array}{rcl}
     x(t) & = & x^{(0)} + x^{(1)} * t 
     \\
     \varepsilon(t) & = & \varepsilon^{(0)} + \varepsilon^{(1)} * t
\end{array}
\]
It follows that  x^{(0)} (  \varepsilon^{(0)} ) is the zero, and  x^{(1)} (  \varepsilon^{(1)} ) the first, order derivative of  x(t) at  t = 0 (  \varepsilon (t) ) at  t = 0 .

3.3.4.b: Mathematical Form
Suppose that we use the algorithm 3.3.1: exp_eps.hpp to compute exp_eps(xepsilon) with x is equal to .5 and epsilon is equal to .2. For this case, the mathematical function for the operation sequence corresponding to exp_eps is  \[
f ( x , \varepsilon ) =   1 + x + x^2 / 2  
\] 
The corresponding partial derivative with respect to  x , and the value of the derivative, are  \[
\partial_x f ( x , \varepsilon ) =   1 + x  = 1.5
\] 


3.3.4.c: Operation Sequence

3.3.4.c.a: Index
The Index column contains the index in the operation sequence of the corresponding atomic operation. A Forward sweep starts with the first operation and ends with the last.

3.3.4.c.b: Operation
The Operation column contains the mathematical function corresponding to each atomic operation in the sequence.

3.3.4.c.c: Zero Order
The Zero Order column contains the zero order derivatives for the corresponding variable in the operation sequence (see 3.2.4.d.f: zero order sweep ).

3.3.4.c.d: Derivative
The Derivative column contains the mathematical function corresponding to the derivative with respect to  t , at  t = 0 , for each variable in the sequence.

3.3.4.c.e: First Order
The First Order column contains the first order derivatives for the corresponding variable in the operation sequence; i.e.,  \[
     v_j (t) = v_j^{(0)} + v_j^{(1)} t
\] 
We use  x^{(1)} = 1 and  \varepsilon^{(1)} = 0 , so that differentiation with respect to  t , at  t = 0 , is the same partial differentiation with respect to  x at  x = x^{(0)} .

3.3.4.c.f: Sweep
Index    Operation    Zero Order    Derivative    First Order
1     v_1 = x  0.5  v_1^{(1)} = x^{(1)}    v_1^{(1)} = 1
2     v_2 = 1 * v_1 0.5  v_2^{(1)} = 1 * v_1^{(1)}  v_2^{(1)} = 1
3     v_3 = v_2 / 1 0.5  v_3^{(1)} = v_2^{(1)} / 1  v_3^{(1)} = 1
4     v_4 = 1 + v_3 1.5  v_4^{(1)} = v_3^{(1)}   v_4^{(1)} = 1
5     v_5 = v_3 * v_1 0.25  v_5^{(1)} = v_3^{(1)} * v_1^{(0)} + v_3^{(0)} * v_1^{(1)}  v_5^{(1)} = 1
6     v_6 = v_5 / 2 0.125  v_6^{(1)} = v_5^{(1)} / 2  v_6^{(1)} = 0.5
7     v_7 = v_4 + v_6 1.625   v_7^{(1)} = v_4^{(1)} + v_6^{(1)}   v_7^{(1)} = 1.5
3.3.4.d: Return Value
The derivative of the return value for this case is  \[
\begin{array}{rcl}
1.5 
& = & 
v_7^{(1)} =
\left[ \D{v_7}{t} \right]_{t=0} =
\left[ \D{}{t} f( x^{(0)} + x^{(1)} * t , \varepsilon^{(0)} ) \right]_{t=0}
\\
& = &
\partial_x f ( x^{(0)} , \varepsilon^{(0)} ) * x^{(1)} = 
\partial_x f ( x^{(0)} , \varepsilon^{(0)} )
\end{array}
\] 
(We have used the fact that  x^{(1)} = 1 and  \varepsilon^{(1)} = 0 .)

3.3.4.e: Verification
The file 3.3.4.1: exp_eps_for1.cpp contains a routine that verifies the values computed above. It returns true for success and false for failure.

3.3.4.f: Exercises
  1. Suppose that  x = .1 , what are the results of a zero and first order forward mode sweep for the operation sequence above; i.e., what are the corresponding values for  v_1^{(0)}, v_2^{(0)}, \cdots , v_7^{(0)} and  v_1^{(1)}, v_2^{(1)}, \cdots , v_7^{(1)} ?
  2. Create a modified version of 3.3.4.1: exp_eps_for1.cpp that verifies the derivative values from the previous exercise. Also create and run a main program that reports the result of calling the modified version of 3.3.4.1: exp_eps_for1.cpp .
  3. Suppose that  x = .1 and  \epsilon = .2 , what is the operation sequence corresponding to
         exp_eps(
    xepsilon)

Input File: introduction/exp_apx/exp_eps.omh
3.3.4.1: exp_eps: Verify First Order Forward Sweep
 # include <cmath>                     // for fabs function
extern bool exp_eps_for0(double *v0); // computes zero order forward sweep
bool exp_eps_for1(double *v1)         // double v[8]
{	bool ok = true;
	double v0[8];

	// set the value of v0[j] for j = 1 , ... , 7
	ok &= exp_eps_for0(v0);

	v1[1] = 1.;                                      // v1 = x
	ok    &= std::fabs( v1[1] - 1. ) <= 1e-10;

	v1[2] = 1. * v1[1];                              // v2 = 1 * v1
	ok    &= std::fabs( v1[2] - 1. ) <= 1e-10;

	v1[3] = v1[2] / 1.;                              // v3 = v2 / 1
	ok    &= std::fabs( v1[3] - 1. ) <= 1e-10;

	v1[4] = v1[3];                                   // v4 = 1 + v3
	ok    &= std::fabs( v1[4] - 1. ) <= 1e-10;

	v1[5] = v1[3] * v0[1] + v0[3] * v1[1];           // v5 = v3 * v1
	ok    &= std::fabs( v1[5] - 1. ) <= 1e-10;

	v1[6] = v1[5] / 2.;                              // v6 = v5 / 2
	ok    &= std::fabs( v1[6] - 0.5 ) <= 1e-10;

	v1[7] = v1[4] + v1[6];                           // v7 = v4 + v6
	ok    &= std::fabs( v1[7] - 1.5 ) <= 1e-10;

	return ok;
}
bool exp_eps_for1(void)
{	double v1[8];
	return exp_eps_for1(v1);
}

Input File: introduction/exp_apx/exp_eps_for1.cpp
3.3.5: exp_eps: First Order Reverse Sweep

3.3.5.a: Purpose
First order reverse mode uses the 3.3.3.b: operation sequence , and zero order forward sweep values, to compute the first order derivative of one dependent variable with respect to all the independent variables. The computations are done in reverse of the order of the computations in the original algorithm.

3.3.5.b: Mathematical Form
Suppose that we use the algorithm 3.3.1: exp_eps.hpp to compute exp_eps(xepsilon) with x is equal to .5 and epsilon is equal to .2. For this case, the mathematical function for the operation sequence corresponding to exp_eps is  \[
f ( x , \varepsilon ) =   1 + x + x^2 / 2  
\] 
The corresponding partial derivatives, and the value of the derivatives, are  \[
\begin{array}{rcl}
\partial_x f ( x , \varepsilon ) & = &  1 + x  = 1.5
\\
\partial_\varepsilon f ( x , \varepsilon ) & = &  0
\end{array}
\] 


3.3.5.c: epsilon
Since  \varepsilon is an independent variable, it could included as an argument to all of the  f_j functions below. The result would be that all the partials with respect to  \varepsilon would be zero and hence we drop it to simplify the presentation.

3.3.5.d: f_7
In reverse mode we choose one dependent variable and compute its derivative with respect to all the independent variables. For our example, we chose the value returned by 3.3.1: exp_eps.hpp which is  v_7 . We begin with the function  f_7 where  v_7 is both an argument and the value of the function; i.e.,  \[
\begin{array}{rcl}
f_7 ( v_1 , v_2 , v_3 , v_4 , v_5 , v_6 , v_7 ) & = & v_7 
\\
\D{f_7}{v_7} & = & 1
\end{array}
\] 
All the other partial derivatives of  f_7 are zero.

3.3.5.e: Index 7: f_6
The last operation has index 7,  \[
     v_7 =   v_4 + v_6  
\] 
We define the function  f_6 ( v_1 , v_2 , v_3 , v_4 , v_5 , v_6 )  as equal to  f_7 except that  v_7 is eliminated using this operation; i.e.  \[
f_6  = 
f_7 [ v_1 , v_2 , v_3 , v_4 , v_5 , v_6 , v_7 ( v_4 , v_6 ) ]
\] 
It follows that  \[
\begin{array}{rcll}
\D{f_6}{v_4} 
& = & \D{f_7}{v_4} + 
     \D{f_7}{v_7} * \D{v_7}{v_4} 
& = 1
\\
\D{f_6}{v_6} 
& = & \D{f_7}{v_6} + 
     \D{f_7}{v_7} * \D{v_7}{v_6} 
& = 1
\end{array}
\] 
All the other partial derivatives of  f_6 are zero.

3.3.5.f: Index 6: f_5
The previous operation has index 6,  \[
     v_6 = v_5 / 2
\] 
We define the function  f_5 (  v_1 , v_2 , v_3 , v_4 , v_5 )  as equal to  f_6  except that  v_6  is eliminated using this operation; i.e.,  \[
f_5 = 
f_6 [  v_1 , v_2 , v_3 , v_4 , v_5 , v_6 ( v_5 ) ]
\] 
It follows that  \[
\begin{array}{rcll}
\D{f_5}{v_4} 
& = & \D{f_6}{v_4} 
& = 1
\\
\D{f_5}{v_5} 
& = & \D{f_6}{v_5} + 
     \D{f_6}{v_6} * \D{v_6}{v_5} 
& = 0.5
\end{array}
\] 
All the other partial derivatives of  f_5 are zero.

3.3.5.g: Index 5: f_4
The previous operation has index 5,  \[
     v_5 = v_3 * v_1
\] 
We define the function  f_4 (  v_1 , v_2 , v_3 , v_4 )  as equal to  f_5  except that  v_5  is eliminated using this operation; i.e.,  \[
f_4 = 
f_5 [  v_1 , v_2 , v_3 , v_4 , v_5 ( v_3 , v_1 )  ]
\] 
Given the information from the forward sweep, we have  v_3 =  0.5  and  v_1 = 0.5  . It follows that  \[
\begin{array}{rcll}
\D{f_4}{v_1} 
& = & \D{f_5}{v_1} + 
     \D{f_5}{v_5} * \D{v_5}{v_1} 
& =  0.25
\\
\D{f_4}{v_2} & = & \D{f_5}{v_2}  & = 0
\\
\D{f_4}{v_3} 
& = & \D{f_5}{v_3} + 
     \D{f_5}{v_5} * \D{v_5}{v_3} 
& =  0.25
\\
\D{f_4}{v_4}
& = & \D{f_5}{v_4} 
& = 1
\end{array}
\] 


3.3.5.h: Index 4: f_3
The previous operation has index 4,  \[
     v_4 = 1 + v_3
\] 
We define the function  f_3 (  v_1 , v_2 , v_3 )  as equal to  f_4  except that  v_4  is eliminated using this operation; i.e.,  \[
f_3 = 
f_4 [  v_1 , v_2 , v_3 , v_4 ( v_3 )  ]
\] 
It follows that  \[
\begin{array}{rcll}
\D{f_3}{v_1} 
& = & \D{f_4}{v_1} 
& =  0.25
\\
\D{f_3}{v_2} & = & \D{f_4}{v_2}  & = 0
\\
\D{f_3}{v_3} 
& = & \D{f_4}{v_3} + 
     \D{f_4}{v_4} * \D{v_4}{v_3} 
& =  1.25
\end{array}
\] 


3.3.5.i: Index 3: f_2
The previous operation has index 3,  \[
     v_3 = v_2 / 1
\] 
We define the function  f_2 (  v_1 , v_2 )  as equal to  f_3  except that  v_3  is eliminated using this operation; i.e.,  \[
f_2 = 
f_4 [  v_1 , v_2 , v_3 ( v_2 )  ]
\] 
It follows that  \[
\begin{array}{rcll}
\D{f_2}{v_1} 
& = & \D{f_3}{v_1} 
& =  0.25
\\
\D{f_2}{v_2} & = & \D{f_3}{v_2}  +
     \D{f_3}{v_3} * \D{v_3}{v_2}
& = 1.25
\end{array}
\] 


3.3.5.j: Index 2: f_1
The previous operation has index 1,  \[
     v_2 = 1 * v_1
\] 
We define the function  f_1 (  v_1 )  as equal to  f_2  except that  v_2  is eliminated using this operation; i.e.,  \[
f_1 = 
f_2 [  v_1 , v_2 ( v_1 )  ]
\] 
It follows that  \[
\begin{array}{rcll}
\D{f_1}{v_1} & = & \D{f_2}{v_1}  +
     \D{f_2}{v_2} * \D{v_2}{v_1}
& = 1.5
\end{array}
\] 
Note that  v_1 is equal to  x , so the derivative of exp_eps(xepsilon) at x equal to .5 and epsilon equal .2 is 1.5 in the x direction and zero in the epsilon direction. We also note that 3.3.4: forward forward mode gave the same result for the partial in the x direction.

3.3.5.k: Verification
The file 3.3.5.1: exp_eps_rev1.cpp contains a routine that verifies the values computed above. It returns true for success and false for failure. It only tests the partial derivatives of  f_j that might not be equal to the corresponding partials of  f_{j+1} ; i.e., the other partials of  f_j must be equal to the corresponding partials of  f_{j+1} .

3.3.5.l: Exercises
  1. Consider the case where  x = .1 and we first preform a zero order forward mode sweep for the operation sequence used above (in reverse order). What are the results of a first order reverse mode sweep; i.e., what are the corresponding values for  \D{f_j}{v_k} for all  j, k such that  \D{f_j}{v_k} \neq 0 .
  2. Create a modified version of 3.3.5.1: exp_eps_rev1.cpp that verifies the values you obtained for the previous exercise. Also create and run a main program that reports the result of calling the modified version of 3.3.5.1: exp_eps_rev1.cpp .

Input File: introduction/exp_apx/exp_eps.omh
3.3.5.1: exp_eps: Verify First Order Reverse Sweep
 # include <cstddef>                     // define size_t
# include <cmath>                       // for fabs function
extern bool exp_eps_for0(double *v0);   // computes zero order forward sweep
bool exp_eps_rev1(void)
{	bool ok = true;

	// set the value of v0[j] for j = 1 , ... , 7
	double v0[8];
	ok &= exp_eps_for0(v0);

	// initial all partial derivatives as zero
	double f_v[8];
	size_t j;
	for(j = 0; j < 8; j++)
		f_v[j] = 0.;

	// set partial derivative for f7
	f_v[7] = 1.;
	ok    &= std::fabs( f_v[7] - 1. ) <= 1e-10;     // f7_v7

	// f6( v1 , v2 , v3 , v4 , v5 , v6 )
	f_v[4] += f_v[7] * 1.;
	f_v[6] += f_v[7] * 1.;
	ok     &= std::fabs( f_v[4] - 1.  ) <= 1e-10;   // f6_v4
	ok     &= std::fabs( f_v[6] - 1.  ) <= 1e-10;   // f6_v6

	// f5( v1 , v2 , v3 , v4 , v5 )
	f_v[5] += f_v[6] / 2.;
	ok     &= std::fabs( f_v[5] - 0.5 ) <= 1e-10;   // f5_v5

	// f4( v1 , v2 , v3 , v4 )
	f_v[1] += f_v[5] * v0[3];
	f_v[3] += f_v[5] * v0[1];
	ok     &= std::fabs( f_v[1] - 0.25) <= 1e-10;   // f4_v1
	ok     &= std::fabs( f_v[3] - 0.25) <= 1e-10;   // f4_v3

	// f3( v1 , v2 , v3 )
	f_v[3] += f_v[4] * 1.;
	ok     &= std::fabs( f_v[3] - 1.25) <= 1e-10;   // f3_v3

	// f2( v1 , v2 )
	f_v[2] += f_v[3] / 1.;
	ok     &= std::fabs( f_v[2] - 1.25) <= 1e-10;   // f2_v2

	// f1( v1 )
	f_v[1] += f_v[2] * 1.;
	ok     &= std::fabs( f_v[1] - 1.5 ) <= 1e-10;   // f1_v2

	return ok;
}

Input File: introduction/exp_apx/exp_eps_rev1.cpp
3.3.6: exp_eps: Second Order Forward Mode

3.3.6.a: Second Order Expansion
We define  x(t) and  \varepsilon(t) ] near  t = 0 by the second order expansions  \[
\begin{array}{rcl}
     x(t) & = & x^{(0)} + x^{(1)} * t  + x^{(2)} * t^2 / 2
     \\
     \varepsilon(t) & = & \varepsilon^{(0)} + \varepsilon^{(1)} * t
                      +   \varepsilon^{(2)} * t^2 / 2
\end{array}
\]
It follows that for  k = 0 , 1 , 2 ,  \[
\begin{array}{rcl}
     x^{(k)}  & = & \dpow{k}{t} x (0)
     \\
     \varepsilon^{(k)}  & = & \dpow{k}{t} \varepsilon (0)
\end{array}
\] 


3.3.6.b: Purpose
In general, a second order forward sweep is given the 3.2.4.a: first order expansion for all of the variables in an operation sequence, and the second order derivatives for the independent variables. It uses these to compute the second order derivative, and thereby obtain the second order expansion, for all the variables in the operation sequence.

3.3.6.c: Mathematical Form
Suppose that we use the algorithm 3.3.1: exp_eps.hpp to compute exp_eps(xepsilon) with x is equal to .5 and epsilon is equal to .2. For this case, the mathematical function for the operation sequence corresponding to exp_eps is  \[
f ( x , \varepsilon ) =   1 + x + x^2 / 2  
\] 
The corresponding second partial derivative with respect to  x , and the value of the derivative, are  \[
\Dpow{2}{x} f ( x , \varepsilon ) =   1.
\] 


3.3.6.d: Operation Sequence

3.3.6.d.a: Index
The Index column contains the index in the operation sequence of the corresponding atomic operation. A Forward sweep starts with the first operation and ends with the last.

3.3.6.d.b: Zero
The Zero column contains the zero order sweep results for the corresponding variable in the operation sequence (see 3.2.3.c.e: zero order sweep ).

3.3.6.d.c: Operation
The Operation column contains the first order sweep operation for this variable.

3.3.6.d.d: First
The First column contains the first order sweep results for the corresponding variable in the operation sequence (see 3.2.4.d.f: first order sweep ).

3.3.6.d.e: Derivative
The Derivative column contains the mathematical function corresponding to the second derivative with respect to  t , at  t = 0 , for each variable in the sequence.

3.3.6.d.f: Second
The Second column contains the second order derivatives for the corresponding variable in the operation sequence; i.e., the second order expansion for the i-th variable is given by  \[
     v_i (t) = v_i^{(0)} + v_i^{(1)} * t +  v_i^{(2)} * t^2 / 2
\] 
We use  x^{(1)} = 1 ,  x^{(2)} = 0 , use  \varepsilon^{(1)} = 1 , and  \varepsilon^{(2)} = 0 so that second order differentiation with respect to  t , at  t = 0 , is the same as the second partial differentiation with respect to  x at  x = x^{(0)} .

3.3.6.d.g: Sweep
Index    Zero    Operation    First    Derivative    Second
1 0.5  v_1^{(1)} = x^{(1)}   1  v_2^{(2)} = x^{(2)}   0
2 0.5  v_2^{(1)} = 1 * v_1^{(1)} 1  v_2^{(2)} = 1 * v_1^{(2)} 0
3 0.5  v_3^{(1)} = v_2^{(1)} / 1 1  v_3^{(2)} = v_2^{(2)} / 1 0
4 1.5  v_4^{(1)} = v_3^{(1)}  1  v_4^{(2)} = v_3^{(2)}  0
5 0.25  v_5^{(1)} = v_3^{(1)} * v_1^{(0)} + v_3^{(0)} * v_1^{(1)} 1  v_5^{(2)} = v_3^{(2)} * v_1^{(0)} + 2 * v_3^{(1)} * v_1^{(1)}
                      + v_3^{(0)} * v_1^{(2)}
2
6 0.125  v_6^{(1)} = v_5^{(1)} / 2 0.5  v_6^{(2)} = v_5^{(2)} / 2 1
7 1.625   v_7^{(1)} = v_4^{(1)} + v_6^{(1)} 1.5   v_7^{(2)} = v_4^{(2)} + v_6^{(2)} 1
3.3.6.e: Return Value
The second derivative of the return value for this case is  \[
\begin{array}{rcl}

& = & 
v_7^{(2)} =
\left[ \Dpow{2}{t} v_7 \right]_{t=0} =
\left[ \Dpow{2}{t} f( x^{(0)} + x^{(1)} * t , \varepsilon^{(0)} ) \right]_{t=0}
\\
& = &
x^{(1)} * \Dpow{2}{x} f ( x^{(0)} ,  \varepsilon^{(0)} ) * x^{(1)} =
\Dpow{2}{x} f ( x^{(0)} ,  \varepsilon^{(0)} )
\end{array}
\] 
(We have used the fact that  x^{(1)} = 1 ,  x^{(2)} = 0 ,  \varepsilon^{(1)} = 1 , and  \varepsilon^{(2)} = 0 .)

3.3.6.f: Verification
The file 3.3.6.1: exp_eps_for2.cpp contains a routine which verifies the values computed above. It returns true for success and false for failure.

3.3.6.g: Exercises
  1. Which statement in the routine defined by 3.3.6.1: exp_eps_for2.cpp uses the values that are calculated by the routine defined by 3.3.4.1: exp_eps_for1.cpp ?
  2. Suppose that  x = .1 , what are the results of a zero, first, and second order forward sweep for the operation sequence above; i.e., what are the corresponding values for  v_i^{(k)} for  i = 1, \ldots , 7 and  k = 0, 1, 2 .
  3. Create a modified version of 3.3.6.1: exp_eps_for2.cpp that verifies the derivative values from the previous exercise. Also create and run a main program that reports the result of calling the modified version of 3.3.6.1: exp_eps_for2.cpp .

Input File: introduction/exp_apx/exp_eps.omh
3.3.6.1: exp_eps: Verify Second Order Forward Sweep
 # include <cmath>                     // for fabs function
extern bool exp_eps_for0(double *v0); // computes zero order forward sweep
extern bool exp_eps_for1(double *v1); // computes first order forward sweep
bool exp_eps_for2(void)
{	bool ok = true;
	double v0[8], v1[8], v2[8];

	// set the value of v0[j], v1[j] for j = 1 , ... , 7
	ok &= exp_eps_for0(v0);
	ok &= exp_eps_for1(v1);

	v2[1] = 0.;                                      // v1 = x
	ok    &= std::fabs( v2[1] - 0. ) <= 1e-10;

	v2[2] = 1. * v2[1];                              // v2 = 1 * v1
	ok    &= std::fabs( v2[2] - 0. ) <= 1e-10;

	v2[3] = v2[2] / 1.;                              // v3 = v2 / 1
	ok    &= std::fabs( v2[3] - 0. ) <= 1e-10;

	v2[4] = v2[3];                                   // v4 = 1 + v3
	ok    &= std::fabs( v2[4] - 0. ) <= 1e-10;

	v2[5] = v2[3] * v0[1] + 2. * v1[3] * v1[1]       // v5 = v3 * v1
	      + v0[3] * v2[1];           
	ok    &= std::fabs( v2[5] - 2. ) <= 1e-10;

	v2[6] = v2[5] / 2.;                              // v6 = v5 / 2
	ok    &= std::fabs( v2[6] - 1. ) <= 1e-10;

	v2[7] = v2[4] + v2[6];                           // v7 = v4 + v6
	ok    &= std::fabs( v2[7] - 1. ) <= 1e-10;

	return ok;
}

Input File: introduction/exp_apx/exp_eps_for2.cpp
3.3.7: exp_eps: Second Order Reverse Sweep

3.3.7.a: Purpose
In general, a second order reverse sweep is given the 3.3.4.a: first order expansion for all of the variables in an operation sequence. Given a choice of a particular variable, it computes the derivative, of that variables first order expansion coefficient, with respect to all of the independent variables.

3.3.7.b: Mathematical Form
Suppose that we use the algorithm 3.3.1: exp_eps.hpp to compute exp_eps(xepsilon) with x is equal to .5 and epsilon is equal to .2. For this case, the mathematical function for the operation sequence corresponding to exp_eps is  \[
f ( x , \varepsilon ) =   1 + x + x^2 / 2  
\] 
The corresponding derivative of the partial derivative with respect to  x is  \[
\begin{array}{rcl}
\Dpow{2}{x} f ( x , \varepsilon ) & = &  1
\\
\partial_\varepsilon \partial_x f ( x , \varepsilon ) & = &  0
\end{array}
\] 


3.3.7.c: epsilon
Since  \varepsilon is an independent variable, it could included as an argument to all of the  f_j functions below. The result would be that all the partials with respect to  \varepsilon would be zero and hence we drop it to simplify the presentation.

3.3.7.d: f_7
In reverse mode we choose one dependent variable and compute its derivative with respect to all the independent variables. For our example, we chose the value returned by 3.3.1: exp_eps.hpp which is  v_7 . We begin with the function  f_7 where  v_7 is both an argument and the value of the function; i.e.,  \[
\begin{array}{rcl}
f_7 \left( 
     v_1^{(0)} , v_1^{(1)} , \ldots , v_7^{(0)} , v_7^{(1)} 
\right) 
& = & v_7^{(1)} 
\\
\D{f_7}{v_7^{(1)}} & = & 1
\end{array}
\] 
All the other partial derivatives of  f_7 are zero.

3.3.7.e: Index 7: f_6
The last operation has index 7,  \[
\begin{array}{rcl}
     v_7^{(0)} & = &   v_4^{(0)} + v_6^{(0)}  
     \\
     v_7^{(1)} & = &   v_4^{(1)} + v_6^{(1)}  
\end{array}
\] 
We define the function  f_6 \left( v_1^{(0)} , \ldots , v_6^{(1)} \right)  as equal to  f_7 except that  v_7^{(0)} and  v_7^{(1)} are eliminated using this operation; i.e.  \[
f_6  = 
f_7 \left[ v_1^{(0)} , \ldots , v_6^{(1)} , 
     v_7^{(0)} \left( v_4^{(0)} , v_6^{(0)} \right)  ,
     v_7^{(1)} \left( v_4^{(1)} , v_6^{(1)} \right)  
\right]
\] 
It follows that  \[
\begin{array}{rcll}
\D{f_6}{v_4^{(1)}} 
& = & \D{f_7}{v_4^{(1)}} + 
     \D{f_7}{v_7^{(1)}} * \D{v_7^{(1)}}{v_4^{(1)}} 
& = 1
\\
\D{f_6}{v_6^{(1)}} 
& = & \D{f_7}{v_6^{(1)}} + 
     \D{f_7}{v_7^{(1)}} * \D{v_7^{(1)}}{v_6^{(1)}} 
& = 1
\end{array}
\] 
All the other partial derivatives of  f_6 are zero.

3.3.7.f: Index 6: f_5
The previous operation has index 6,  \[
\begin{array}{rcl}
     v_6^{(0)} & = & v_5^{(0)} / 2
     \\
     v_6^{(1)} & = & v_5^{(1)} / 2
\end{array}
\] 
We define the function  f_5 \left( v_1^{(0)} , \ldots , v_5^{(1)} \right)  as equal to  f_6  except that  v_6^{(0)} and  v_6^{(1)} are eliminated using this operation; i.e.  \[
f_5 = 
f_6 \left[ v_1^{(0)} , \ldots , v_5^{(1)} , 
     v_6^{(0)} \left( v_5^{(0)} \right) ,
     v_6^{(1)} \left( v_5^{(1)} \right) 
\right]
\] 
It follows that  \[
\begin{array}{rcll}
\D{f_5}{v_4^{(1)}} 
& = & \D{f_6}{v_4^{(1)}} 
& = 1
\\
\D{f_5}{v_5^{(1)}} 
& = & \D{f_6}{v_5} + 
     \D{f_6}{v_6^{(1)}} * \D{v_6^{(1)}}{v_5^{(1)}} 
& = 0.5
\end{array}
\] 
All the other partial derivatives of  f_5 are zero.

3.3.7.g: Index 5: f_4
The previous operation has index 5,  \[
\begin{array}{rcl}
     v_5^{(0)} & = & v_3^{(0)} * v_1^{(0)}
     \\
     v_5^{(1)} & = & v_3^{(1)} * v_1^{(0)} + v_3^{(0)} * v_1^{(1)}
\end{array}
\] 
We define the function  f_4 \left( v_1^{(0)} , \ldots , v_4^{(1)} \right)  as equal to  f_5  except that  v_5^{(0)} and  v_5^{(1)} are eliminated using this operation; i.e.  \[
f_4 = 
f_5 \left[  v_1^{(0)} , \ldots , v_4^{(1)} ,
     v_5^{(0)} \left( v_1^{(0)}, v_3^{(0)} \right) ,
     v_5^{(1)} \left( v_1^{(0)}, v_1^{(1)}, v_3^{(0)} , v_3^{(1)} \right) ,
\right]
\] 
Given the information from the forward sweep, we have  v_1^{(0)} =  0.5 ,  v_3^{(0)} =  0.5 ,  v_1^{(1)} =  1 ,  v_3^{(1)} =  1 , and the fact that the partial of  f_5 with respect to  v_5^{(0)} is zero, we have  \[
\begin{array}{rcll}
\D{f_4}{v_1^{(0)}}
& = & \D{f_5}{v_1^{(0)}}
  +   \D{f_5}{v_5^{(1)}} * \D{v_5^{(1)}}{v_1^{(0)}} 
& = 0.5
\\
\D{f_4}{v_1^{(1)}}
& = & \D{f_5}{v_1^{(1)}}
  +   \D{f_5}{v_5^{(1)}} * \D{v_5^{(1)}}{v_1^{(1)}} 
& = 0.25
\\
\D{f_4}{v_3^{(0)}}
& = & \D{f_5}{v_3^{(0)}}
  +   \D{f_5}{v_5^{(1)}} * \D{v_5^{(1)}}{v_3^{(0)}} 
& = 0.5
\\
\D{f_4}{v_3^{(1)}}
& = & \D{f_3}{v_1^{(1)}}
  +   \D{f_5}{v_5^{(1)}} * \D{v_5^{(1)}}{v_3^{(1)}} 
& = 0.25
\\
\D{f_4}{v_4^{(1)}}
& = & \D{f_5}{v_4^{(1)}}
& = 1
\end{array}
\] 
All the other partial derivatives of  f_5 are zero.

3.3.7.h: Index 4: f_3
The previous operation has index 4,  \[
\begin{array}{rcl}
     v_4^{(0)} = 1 + v_3^{(0)}
     \\
     v_4^{(1)} = v_3^{(1)}
\end{array}
\] 
We define the function  f_3 \left( v_1^{(0)} , \ldots , v_3^{(1)} \right)  as equal to  f_4  except that  v_4^{(0)} and  v_4^{(1)} are eliminated using this operation; i.e.  \[
f_3 = 
f_4 \left[ v_1^{(0)} , \ldots , v_3^{(1)} ,
     v_4^{(0)} \left( v_3^{(0)} \right) ,
     v_4^{(1)} \left( v_3^{(1)} \right)  
\right]
\] 
It follows that  \[
\begin{array}{rcll}
\D{f_3}{v_1^{(0)}} 
& = & \D{f_4}{v_1^{(0)}}
& =  0.5
\\
\D{f_3}{v_1^{(1)}} 
& = & \D{f_4}{v_1^{(1)}}
& =  0.25
\\
\D{f_3}{v_2^{(0)}} 
& = & \D{f_4}{v_2^{(0)}}  
& = 0
\\
\D{f_3}{v_2^{(1)}} 
& = & \D{f_4}{v_2^{(1)}}  
& = 0
\\
\D{f_3}{v_3^{(0)}} 
& = & \D{f_4}{v_3^{(0)}} 
  +   \D{f_4}{v_4^{(0)}} * \D{v_4^{(0)}}{v_3^{(0)}} 
& = 0.5
\\
\D{f_3}{v_3^{(1)}} 
& = & \D{f_4}{v_3^{(1)}} 
  +   \D{f_4}{v_4^{(1)}} * \D{v_4^{(1)}}{v_3^{(1)}} 
& = 1.25
\end{array}
\] 


3.3.7.i: Index 3: f_2
The previous operation has index 3,  \[
\begin{array}{rcl}
     v_3^{(0)} & = & v_2^{(0)} / 1
     \\
     v_3^{(1)} & = & v_2^{(1)} / 1
\end{array}
\] 
We define the function  f_2 \left( v_1^{(0)} , \ldots , v_2^{(1)} \right)  as equal to  f_3  except that  v_3^{(0)} and  v_3^{(1)} are eliminated using this operation; i.e.  \[
f_2 = 
f_3 \left[ v_1^{(0)} , \ldots , v_2^{(1)} ,
     v_3^{(0)} \left( v_2^{(0)} \right) ,
     v_3^{(1)} \left( v_2^{(1)} \right)
\right]
\] 
It follows that  \[
\begin{array}{rcll}
\D{f_2}{v_1^{(0)}} 
& = & \D{f_3}{v_1^{(0)}}
& =  0.5
\\
\D{f_2}{v_1^{(1)}} 
& = & \D{f_3}{v_1^{(1)}}
& =  0.25
\\
\D{f_2}{v_2^{(0)}} 
& = & \D{f_3}{v_2^{(0)}}  
  +   \D{f_3}{v_3^{(0)}} * \D{v_3^{(0)}}{v_2^{(0)}}
& = 0.5
\\
\D{f_2}{v_2^{(1)}} 
& = & \D{f_3}{v_2^{(1)}}  
  +   \D{f_3}{v_3^{(1)}} * \D{v_3^{(1)}}{v_2^{(0)}}
& = 1.25
\end{array}
\] 


3.3.7.j: Index 2: f_1
The previous operation has index 1,  \[
\begin{array}{rcl}
     v_2^{(0)} & = & 1 * v_1^{(0)}
     \\
     v_2^{(1)} & = & 1 * v_1^{(1)}
\end{array}
\] 
We define the function  f_1 \left( v_1^{(0)} , v_1^{(1)} \right)  as equal to  f_2  except that  v_2^{(0)} and  v_2^{(1)} are eliminated using this operation; i.e.  \[
f_1 = 
f_2 \left[  v_1^{(0)} , v_1^{(1)} , 
     v_2^{(0)} \left( v_1^{(0)} \right)  ,
     v_2^{(1)} \left( v_1^{(1)} \right)  
\right]
\] 
It follows that  \[
\begin{array}{rcll}
\D{f_1}{v_1^{(0)}} 
& = & \D{f_2}{v_1^{(0)}}
  +   \D{f_2}{v_2^{(0)}} * \D{v_2^{(0)}}{v_1^{(0)}}
& =  1
\\
\D{f_1}{v_1^{(1)}} 
& = & \D{f_2}{v_1^{(1)}}
  +   \D{f_2}{v_2^{(1)}} * \D{v_2^{(1)}}{v_1^{(1)}}
& = 1.5
\end{array}
\] 
Note that  v_1 is equal to  x , so the second partial derivative of exp_eps(xepsilon) at x equal to .5 and epsilon equal .2 is  \[
\Dpow{2}{x} v_7^{(0)}
= \D{v_7^{(1)}}{x} 
= \D{f_1}{v_1^{(0)}}
= 1
\] 
There is a theorem about algorithmic differentiation that explains why the other partial of  f_1 is equal to the first partial of exp_eps(xepsilon) with respect to  x .

3.3.7.k: Verification
The file 3.3.7.1: exp_eps_rev2.cpp contains a routine that verifies the values computed above. It returns true for success and false for failure. It only tests the partial derivatives of  f_j that might not be equal to the corresponding partials of  f_{j+1} ; i.e., the other partials of  f_j must be equal to the corresponding partials of  f_{j+1} .

3.3.7.l: Exercises
  1. Consider the case where  x = .1 and we first preform a zero order forward mode sweep for the operation sequence used above (in reverse order). What are the results of a first order reverse mode sweep; i.e., what are the corresponding values for  \D{f_j}{v_k} for all  j, k such that  \D{f_j}{v_k} \neq 0 .
  2. Create a modified version of 3.3.7.1: exp_eps_rev2.cpp that verifies the values you obtained for the previous exercise. Also create and run a main program that reports the result of calling the modified version of 3.3.7.1: exp_eps_rev2.cpp .

Input File: introduction/exp_apx/exp_eps.omh
3.3.7.1: exp_eps: Verify Second Order Reverse Sweep
 # include <cstddef>                     // define size_t
# include <cmath>                       // for fabs function
extern bool exp_eps_for0(double *v0);   // computes zero order forward sweep
extern bool exp_eps_for1(double *v1);   // computes first order forward sweep
bool exp_eps_rev2(void)
{	bool ok = true;

	// set the value of v0[j], v1[j] for j = 1 , ... , 7
	double v0[8], v1[8];
	ok &= exp_eps_for0(v0);
	ok &= exp_eps_for1(v1);

	// initial all partial derivatives as zero
	double f_v0[8], f_v1[8];
	size_t j;
	for(j = 0; j < 8; j++)
	{	f_v0[j] = 0.;
		f_v1[j] = 0.;
	}

	// set partial derivative for f_7
	f_v1[7] = 1.;
	ok &= std::fabs( f_v1[7] - 1.  ) <= 1e-10; // partial f_7 w.r.t. v_7^1

	// f_6 = f_7( v_1^0 , ... , v_6^1 , v_4^0 + v_6^0, v_4^1 , v_6^1 )
	f_v0[4] += f_v0[7];
	f_v0[6] += f_v0[7];
	f_v1[4] += f_v1[7];
	f_v1[6] += f_v1[7];
	ok &= std::fabs( f_v0[4] - 0.  ) <= 1e-10; // partial f_6 w.r.t. v_4^0
	ok &= std::fabs( f_v0[6] - 0.  ) <= 1e-10; // partial f_6 w.r.t. v_6^0
	ok &= std::fabs( f_v1[4] - 1.  ) <= 1e-10; // partial f_6 w.r.t. v_4^1
	ok &= std::fabs( f_v1[6] - 1.  ) <= 1e-10; // partial f_6 w.r.t. v_6^1

	// f_5 = f_6( v_1^0 , ... , v_5^1 , v_5^0 / 2 , v_5^1 / 2 )
	f_v0[5] += f_v0[6] / 2.;
	f_v1[5] += f_v1[6] / 2.;
	ok &= std::fabs( f_v0[5] - 0.  ) <= 1e-10; // partial f_5 w.r.t. v_5^0
	ok &= std::fabs( f_v1[5] - 0.5 ) <= 1e-10; // partial f_5 w.r.t. v_5^1

	// f_4 = f_5( v_1^0 , ... , v_4^1 , v_3^0 * v_1^0 , 
	//            v_3^1 * v_1^0 + v_3^0 * v_1^1 )
	f_v0[1] += f_v0[5] * v0[3] + f_v1[5] * v1[3];
	f_v0[3] += f_v0[5] * v0[1] + f_v1[5] * v1[1];
	f_v1[1] += f_v1[5] * v0[3];
	f_v1[3] += f_v1[5] * v0[1];
	ok &= std::fabs( f_v0[1] - 0.5  ) <= 1e-10; // partial f_4 w.r.t. v_1^0
	ok &= std::fabs( f_v0[3] - 0.5  ) <= 1e-10; // partial f_4 w.r.t. v_3^0
	ok &= std::fabs( f_v1[1] - 0.25 ) <= 1e-10; // partial f_4 w.r.t. v_1^1
	ok &= std::fabs( f_v1[3] - 0.25 ) <= 1e-10; // partial f_4 w.r.t. v_3^1

	// f_3 = f_4(  v_1^0 , ... , v_3^1 , 1 + v_3^0 , v_3^1 )
	f_v0[3] += f_v0[4];
	f_v1[3] += f_v1[4];
	ok &= std::fabs( f_v0[3] - 0.5 ) <= 1e-10;  // partial f_3 w.r.t. v_3^0
	ok &= std::fabs( f_v1[3] - 1.25) <= 1e-10;  // partial f_3 w.r.t. v_3^1

	// f_2 = f_3( v_1^0 , ... , v_2^1 , v_2^0 , v_2^1 )
	f_v0[2] += f_v0[3];
	f_v1[2] += f_v1[3];
	ok &= std::fabs( f_v0[2] - 0.5 ) <= 1e-10;  // partial f_2 w.r.t. v_2^0
	ok &= std::fabs( f_v1[2] - 1.25) <= 1e-10;  // partial f_2 w.r.t. v_2^1

	// f_1 = f_2 ( v_1^0 , v_2^0 , v_1^0 , v_2^0 )
	f_v0[1] += f_v0[2];
	f_v1[1] += f_v1[2];
	ok &= std::fabs( f_v0[1] - 1.  ) <= 1e-10;  // partial f_1 w.r.t. v_1^0
	ok &= std::fabs( f_v1[1] - 1.5 ) <= 1e-10;  // partial f_1 w.r.t. v_1^1

	return ok;
}

Input File: introduction/exp_apx/exp_eps_rev2.cpp
3.3.8: exp_eps: CppAD Forward and Reverse Sweeps
.

3.3.8.a: Purpose
Use CppAD forward and reverse modes to compute the partial derivative with respect to  x , at the point  x = .5 and  \varepsilon = .2 , of the function
     exp_eps(
xepsilon)
as defined by the 3.3.1: exp_eps.hpp include file.

3.3.8.b: Exercises
  1. Create and test a modified version of the routine below that computes the same order derivatives with respect to  x , at the point  x = .1 and  \varepsilon = .2 , of the function
         exp_eps(
    xepsilon)
  2. Create and test a modified version of the routine below that computes partial derivative with respect to  x , at the point  x = .1 and  \varepsilon = .2 , of the function corresponding to the operation sequence for  x = .5 and  \varepsilon = .2 . Hint: you could define a vector u with two components and use
         
    f.Forward(0, u)
    to run zero order forward mode at a point different form the point where the operation sequence corresponding to f was recorded.
 
# include <cppad/cppad.hpp>  // http://www.coin-or.org/CppAD/ 
# include "exp_eps.hpp"      // our example exponential function approximation
bool exp_eps_cppad(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::vector;    // can use any simple vector template class
	using CppAD::NearEqual; // checks if values are nearly equal

	// domain space vector
	size_t n = 2; // dimension of the domain space
	vector< AD<double> > U(n);
	U[0] = .5;    // value of x for this operation sequence
	U[1] = .2;    // value of e for this operation sequence

	// declare independent variables and start recording operation sequence
	CppAD::Independent(U);

	// evaluate our exponential approximation
	AD<double> x       = U[0];
	AD<double> epsilon = U[1];
	AD<double> apx = exp_eps(x, epsilon);  

	// range space vector
	size_t m = 1;  // dimension of the range space
	vector< AD<double> > Y(m);
	Y[0] = apx;    // variable that represents only range space component

	// Create f: U -> Y corresponding to this operation sequence
	// and stop recording. This also executes a zero order forward 
	// mode sweep using values in U for x and e.
	CppAD::ADFun<double> f(U, Y);

	// first order forward mode sweep that computes partial w.r.t x
	vector<double> du(n);      // differential in domain space
	vector<double> dy(m);      // differential in range space
	du[0] = 1.;                // x direction in domain space
	du[1] = 0.;
	dy    = f.Forward(1, du);  // partial w.r.t. x
	double check = 1.5;
	ok   &= NearEqual(dy[0], check, 1e-10, 1e-10);

	// first order reverse mode sweep that computes the derivative
	vector<double>  w(m);     // weights for components of the range
	vector<double> dw(n);     // derivative of the weighted function
	w[0] = 1.;                // there is only one weight 
	dw   = f.Reverse(1, w);   // derivative of w[0] * exp_eps(x, epsilon)
	check = 1.5;              // partial w.r.t. x
	ok   &= NearEqual(dw[0], check, 1e-10, 1e-10);
	check = 0.;               // partial w.r.t. epsilon
	ok   &= NearEqual(dw[1], check, 1e-10, 1e-10);

	// second order forward sweep that computes
	// second partial of exp_eps(x, epsilon) w.r.t. x
	vector<double> x2(n);     // second order Taylor coefficients
	vector<double> y2(m);
	x2[0] = 0.;               // evaluate partial w.r.t x
	x2[1] = 0.;
	y2    = f.Forward(2, x2);
	check = 0.5 * 1.;         // Taylor coef is 1/2 second derivative
	ok   &= NearEqual(y2[0], check, 1e-10, 1e-10);

	// second order reverse sweep that computes
	// derivative of partial of exp_eps(x, epsilon) w.r.t. x
	dw.resize(2 * n);         // space for first and second derivative
	dw    = f.Reverse(2, w);
	check = 1.;               // result should be second derivative
	ok   &= NearEqual(dw[0*2+1], check, 1e-10, 1e-10);

	return ok;
}

Input File: introduction/exp_apx/exp_eps_cppad.cpp
3.4: Run the exp_2 and exp_eps Tests
 

// system include files used for I/O
# include <iostream>

// external complied tests
extern bool exp_2(void);
extern bool exp_2_cppad(void);
extern bool exp_2_for1(void);
extern bool exp_2_for2(void);
extern bool exp_2_rev1(void);
extern bool exp_2_rev2(void);
extern bool exp_2_for0(void);
extern bool exp_eps(void);
extern bool exp_eps_cppad(void);
extern bool exp_eps_for1(void);
extern bool exp_eps_for2(void);
extern bool exp_eps_for0(void);
extern bool exp_eps_rev1(void);
extern bool exp_eps_rev2(void);

namespace {
	static size_t Run_ok_count    = 0;
	static size_t Run_error_count = 0;
	bool Run(bool TestOk(void), std::string name)
	{	bool ok               = true;
		std::streamsize width =  20;         
		std::cout.width( width );
		std::cout.setf( std::ios_base::left );
		std::cout << name.c_str();
		//
		ok &= name.size() < size_t(width);
		ok &= TestOk();
		if( ok )
		{	std::cout << "OK" << std::endl;
			Run_ok_count++;
		}
		else
		{	std::cout << "Error" << std::endl;
			Run_error_count++;
		}
		return ok;
	}
}

// main program that runs all the tests
int main(void)
{	bool ok = true;
	using namespace std;

	// This comment is used by OneTest 

	// external compiled tests
	ok &= Run( exp_2,           "exp_2"          );
	ok &= Run( exp_2_cppad,     "exp_2_cppad"    );
	ok &= Run( exp_2_for0,      "exp_2_for0"     );
	ok &= Run( exp_2_for1,      "exp_2_for1"     );
	ok &= Run( exp_2_for2,      "exp_2_for2"     );
	ok &= Run( exp_2_rev1,      "exp_2_rev1"     );
	ok &= Run( exp_2_rev2,      "exp_2_rev2"     );
	ok &= Run( exp_eps,         "exp_eps"        );
	ok &= Run( exp_eps_cppad,   "exp_eps_cppad"  );
	ok &= Run( exp_eps_for0,    "exp_eps_for0"   );
	ok &= Run( exp_eps_for1,    "exp_eps_for1"   );
	ok &= Run( exp_eps_for2,    "exp_eps_for2"   );
	ok &= Run( exp_eps_rev1,    "exp_eps_rev1"   );
	ok &= Run( exp_eps_rev2,    "exp_eps_rev2"   );
	if( ok )
		cout << "All " << int(Run_ok_count) << " tests passed." << endl;
	else	cout << int(Run_error_count) << " tests failed." << endl;

	return static_cast<int>( ! ok );
}

Input File: introduction/exp_apx/main.cpp
4: AD Objects

4.a: Purpose
The sections listed below describe the operations that are available to 9.4.b: AD of Base objects. These objects are used to 9.4.j: tape an AD of Base 9.4.g.b: operation sequence . This operation sequence can be transferred to an 5: ADFun object where it can be used to evaluate the corresponding function and derivative values.

4.b: Base Type Requirements
The Base requirements are provided by the CppAD package for the following base types: float, double, std::complex<float>, std::complex<double>. Otherwise, see 4.7: base_require .

4.c: Contents
Default: 4.1AD Default Constructor
ad_copy: 4.2AD Copy Constructor and Assignment Operator
Convert: 4.3Conversion and Printing of AD Objects
ADValued: 4.4AD Valued Operations and Functions
BoolValued: 4.5Bool Valued Operations and Functions with AD Arguments
VecAD: 4.6AD Vectors that Record Index Operations
base_require: 4.7AD<Base> Requirements for Base Type

Input File: cppad/local/user_ad.hpp
4.1: AD Default Constructor

4.1.a: Syntax
AD<Basex;

4.1.b: Purpose
Constructs an AD object with an unspecified value. Directly after this construction, the object is a 9.4.h: parameter .

4.1.c: Example
The file 4.1.1: Default.cpp contains an example and test of this operation. It returns true if it succeeds and false otherwise.
Input File: cppad/local/default.hpp
4.1.1: Default AD Constructor: Example and Test
 

# include <cppad/cppad.hpp>

bool Default(void)
{	bool ok = true;
	using CppAD::AD;

	// default AD constructor
	AD<double> x, y;

	// check that they are parameters
	ok &= Parameter(x);
	ok &= Parameter(y);

	// assign them values
	x = 3.; 
	y = 4.;

	// just check a simple operation
	ok &= (x + y == 7.);

	return ok;
}

Input File: example/default.cpp
4.2: AD Copy Constructor and Assignment Operator

4.2.a: Syntax

4.2.a.a: Constructor
AD<Basey(x)
AD<Basey = x

4.2.a.b: Assignment
y = x

4.2.b: Purpose
The constructor creates a new AD<Base> object y and the assignment operator uses an existing y. In either case, y has the same value as x, and the same dependence on the 9.4.j.c: independent variables (y is a 9.4.l: variable if and only if x is a variable).

4.2.c: x
The argument x has prototype
     const 
Type &x
where Type is VecAD<Base>::reference, AD<Base>, Base, or double.

4.2.d: y
The target y has prototype
     AD<
Base> &y

4.2.e: Example
The following files contain examples and tests of these operations. Each test returns true if it succeeds and false otherwise.
4.2.1: CopyAD.cpp AD Copy Constructor: Example and Test
4.2.2: CopyBase.cpp AD Constructor From Base Type: Example and Test
4.2.3: Eq.cpp AD Assignment Operator: Example and Test

Input File: cppad/local/ad_copy.hpp
4.2.1: AD Copy Constructor: Example and Test
 

# include <cppad/cppad.hpp>

bool CopyAD(void)
{	bool ok = true;   // initialize test result flag
	using CppAD::AD;  // so can use AD in place of CppAD::AD

	// domain space vector
	size_t n = 1;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]     = 2.;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// create an AD<double> that does not depend on x
	AD<double> b = 3.;   

	// use copy constructor 
	AD<double> u(x[0]);    
	AD<double> v = b;

	// check which are parameters
	ok &= Variable(u);
	ok &= Parameter(v);

	// range space vector
	size_t m = 2;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0]  = u;
	y[1]  = v;

	// create f: x -> y and vectors used for derivative calculations
	CppAD::ADFun<double> f(x, y);
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
 
 	// check parameters flags
 	ok &= ! f.Parameter(0);
 	ok &=   f.Parameter(1);

	// check function values
	ok &= ( y[0] == 2. );
	ok &= ( y[1] == 3. );

	// forward computation of partials w.r.t. x[0]
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= ( dy[0] == 1. );   // du / dx
	ok   &= ( dy[1] == 0. );   // dv / dx

	return ok;
}

Input File: example/copy_ad.cpp
4.2.2: AD Constructor From Base Type: Example and Test
 

# include <cppad/cppad.hpp>

bool CopyBase(void)
{	bool ok = true;    // initialize test result flag
	using CppAD::AD;   // so can use AD in place of CppAD::AD

	// construct directly from Base where Base is double 
	AD<double> x(1.); 

	// construct from a type that converts to Base where Base is double
	AD<double> y = 2;

	// construct from a type that converts to Base where Base = AD<double>
	AD< AD<double> > z(3); 

	// check that resulting objects are parameters
	ok &= Parameter(x);
	ok &= Parameter(y);
	ok &= Parameter(z);

	// check values of objects (compare AD<double> with double)
	ok &= ( x == 1.);
	ok &= ( y == 2.);
	ok &= ( Value(z) == 3.);

	// user constructor through the static_cast template function
	x   = static_cast < AD<double> >( 4 );
	z  = static_cast < AD< AD<double> > >( 5 );

	ok &= ( x == 4. );
	ok &= ( Value(z) == 5. );

	return ok;
}

Input File: example/copy_base.cpp
4.2.3: AD Assignment Operator: Example and Test
 

# include <cppad/cppad.hpp>

bool Eq(void)
{	bool ok = true;
	using CppAD::AD;

	// domain space vector
	size_t n = 3;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]     = 2;      // AD<double> = int
	x[1]     = 3.;     // AD<double> = double
	x[2]     = x[1];   // AD<double> = AD<double>

	// declare independent variables and start tape recording
	CppAD::Independent(x);
	
	// range space vector 
	size_t m = 3;
	CPPAD_TEST_VECTOR< AD<double> > y(m);

	// assign an AD<Base> object equal to an independent variable
	// (choose the first independent variable to check a special case)
	// use the value returned by the assignment (for another assignment)
	y[0] = y[1] = x[0];  

	// assign an AD<Base> object equal to an expression 
	y[1] = x[1] + 1.;
	y[2] = x[2] + 2.;

	// check that all the resulting components of y depend on x
	ok &= Variable(y[0]);  // y[0] = x[0]
	ok &= Variable(y[1]);  // y[1] = x[1] + 1
	ok &= Variable(y[2]);  // y[2] = x[2] + 2

	// construct f : x -> y and stop the tape recording
	CppAD::ADFun<double> f(x, y);

	// check variable values
	ok &= ( y[0] == 2.);
	ok &= ( y[1] == 4.);
	ok &= ( y[2] == 5.);

	// compute partials w.r.t x[1]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 0.;
	dx[1] = 1.;
	dx[2] = 0.;
	dy   = f.Forward(1, dx);
	ok  &= (dy[0] == 0.);  // dy[0] / dx[1]
	ok  &= (dy[1] == 1.);  // dy[1] / dx[1]
	ok  &= (dy[2] == 0.);  // dy[2] / dx[1]

	// compute the derivative y[2]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0] = 0.;
	w[1] = 0.;
	w[2] = 1.;
	dw   = f.Reverse(1, w);
	ok  &= (dw[0] == 0.);  // dy[2] / dx[0]
	ok  &= (dw[1] == 0.);  // dy[2] / dx[1]
	ok  &= (dw[2] == 1.);  // dy[2] / dx[2]

	// assign a VecAD<Base>::reference
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero] = 5.;
	ok     &= (v[0] == 5.);

	return ok;
}

Input File: example/eq.cpp
4.3: Conversion and Printing of AD Objects
4.3.1: Value Convert From an AD Type to its Base Type
4.3.2: Integer Convert From AD to Integer
4.3.3: Output AD Output Stream Operator
4.3.4: PrintFor Printing AD Values During Forward Mode
4.3.5: Var2Par Convert an AD Variable to a Parameter

Input File: cppad/local/convert.hpp
4.3.1: Convert From an AD Type to its Base Type

4.3.1.a: Syntax
b = Value(x)

4.3.1.b: Purpose
Converts from an AD type to the corresponding 9.4.e: base type .

4.3.1.c: x
The argument x has prototype
     const AD<
Base> &x

4.3.1.d: b
The return value b has prototype
     
Base b

4.3.1.e: Operation Sequence
The result of this operation is not an 9.4.b: AD of Base object. Thus it will not be recorded as part of an AD of Base 9.4.g.b: operation sequence .

4.3.1.f: Restriction
If the argument x is a 9.4.l: variable its dependency information would not be included in the Value result (see above). For this reason, the argument x must be a 9.4.h: parameter ; i.e., it cannot depend on the current 9.4.j.c: independent variables .

4.3.1.g: Example
The file 4.3.1.1: Value.cpp contains an example and test of this operation.
Input File: cppad/local/value.hpp
4.3.1.1: Convert From AD to its Base Type: Example and Test
 

# include <cppad/cppad.hpp>

bool Value(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::Value;

	// domain space vector
	size_t n = 2;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0] = 3.;
	x[1] = 4.;

	// check value before recording
	ok &= (Value(x[0]) == 3.);
	ok &= (Value(x[1]) == 4.);

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = - x[1];

	// cannot call Value(x[j]) or Value(y[0]) here (currently variables)
	AD<double> p = 5.;        // p is a parameter (does not depend on x)
	ok &= (Value(p) == 5.);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y);

	// can call Value(x[j]) or Value(y[0]) here (currently parameters)
	ok &= (Value(x[0]) ==  3.);
	ok &= (Value(x[1]) ==  4.);
	ok &= (Value(y[0]) == -4.);

	return ok;
}

Input File: example/value.cpp
4.3.2: Convert From AD to Integer

4.3.2.a: Syntax
i = Integer(x)

4.3.2.b: Purpose
Converts from an AD type to the corresponding integer value.

4.3.2.c: i
The result i has prototype
     int 
i

4.3.2.d: x

4.3.2.d.a: Real Types
If the argument x has either of the following prototypes:
     const float                
  &x
     const double               
  &x
the fractional part is dropped to form the integer value. For example, if x is 1.5, i is 1. In general, if  x \geq 0 , i is the greatest integer less than or equal x. If  x \leq 0 , i is the smallest integer greater than or equal x.

4.3.2.d.b: Complex Types
If the argument x has either of the following prototypes:
     const std::complex<float>  
  &x
     const std::complex<double> 
  &x
The result i is given by
     
i = Integer(x.real())

4.3.2.d.c: AD Types
If the argument x has either of the following prototypes:
     const AD<
Base>               &x
     const VecAD<
Base>::reference &x
Base must support the Integer function and the conversion has the same meaning as for Base.

4.3.2.e: Operation Sequence
The result of this operation is not an 9.4.b: AD of Base object. Thus it will not be recorded as part of an AD of Base 9.4.g.b: operation sequence .

4.3.2.f: Example
The file 4.3.2.1: Integer.cpp contains an example and test of this operation.
Input File: cppad/local/integer.hpp
4.3.2.1: Convert From AD to Integer: Example and Test
 

# include <cppad/cppad.hpp>

bool Integer(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::Integer;

	// domain space vector
	size_t n = 2;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0] = 3.5;
	x[1] = 4.5;

	// check integer before recording
	ok &= (Integer(x[0]) == 3);
	ok &= (Integer(x[1]) == 4);

	// start recording

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// check integer during recording
	ok &= (Integer(x[0]) == 3);
	ok &= (Integer(x[1]) == 4);

	// check integer for VecAD element
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero] = 2;
	ok &= (Integer(v[zero]) == 2);

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = - x[1];

	// create f: x -> y and stop recording
	CppAD::ADFun<double> f(x, y);

	// check integer after recording
	ok &= (Integer(x[0]) ==  3.);
	ok &= (Integer(x[1]) ==  4.);
	ok &= (Integer(y[0]) == -4.);

	return ok;
}

Input File: example/integer.cpp
4.3.3: AD Output Stream Operator

4.3.3.a: Syntax
os << x

4.3.3.b: Purpose
Writes the Base value_, corresponding to x, to the output stream os.

4.3.3.c: os
The operand os has prototype
     std::ostream &
os

4.3.3.d: x
The operand x has one of the following prototypes
     const AD<
Base>               &x
     const VecAD<
Base>::reference &x

4.3.3.e: Result
The result of this operation can be used as a reference to os. For example, if the operand y has prototype
     AD<
Basey
then the syntax
     
os << x << y
will output the value corresponding to x followed by the value corresponding to y.

4.3.3.f: Operation Sequence
The result of this operation is not an 9.4.b: AD of Base object. Thus it will not be recorded as part of an AD of Base 9.4.g.b: operation sequence .

4.3.3.g: Example
The file 4.3.3.1: Output.cpp contains an example and test of this operation. It returns true if it succeeds and false otherwise.
Input File: cppad/local/output.hpp
4.3.3.1: AD Output Operator: Example and Test
 

# include <cppad/cppad.hpp>

# include <sstream>  // std::ostringstream
# include <string>   // std::string
# include <iomanip>  // std::setprecision, setw, setfill, right

namespace {
	template <class S>
	void set_ostream(S &os)
	{	os 
		<< std::setprecision(4) // 4 digits of precision
		<< std::setw(6)         // 6 characters per field
		<< std::setfill(' ')    // fill with spaces
		<< std::right;          // adjust value to the right
	}
}

bool Output(void)
{	bool ok = true;

	// This output stream is an ostringstream for testing purposes.
	// You can use << with other types of streams; i.e., std::cout.
	std::ostringstream stream;

	// ouput an AD<double> object
	CppAD::AD<double>  pi = 4. * atan(1.); // 3.1415926536
	set_ostream(stream);
	stream << pi;

	// ouput a VecAD<double>::reference object
	CppAD::VecAD<double> v(1);
	CppAD::AD<double> zero(0);
	v[zero]   = exp(1.);                  // 2.7182818285
	set_ostream(stream); 
	stream << v[zero];

	// convert output from stream to string
	std::string str = stream.str();

	// check the output
	ok      &= (str == " 3.142 2.718");

	return ok;
}

Input File: example/output.cpp
4.3.4: Printing AD Values During Forward Mode

4.3.4.a: Syntax
PrintFor(texty)
f.Forward(0, x)

4.3.4.b: Purpose
The current value of an AD<Base> object y is the result of an AD of Base operation. This operation may be part of the 9.4.g.b: operation sequence that is transferred to an 5: ADFun object f. The ADFun object can be evaluated at different values for the 9.4.j.c: independent variables . This may result in a corresponding value for y that is different from when the operation sequence was recorded. The routine PrintFor requests a printing, when f.Forward(0, x) is executed, of the value for y that corresponds to the independent variable values specified by x.

4.3.4.c: text
The argument text has prototype
     const char *
text
The corresponding text is written to std::cout before the value of y.

4.3.4.d: y
The argument y has one of the following prototypes
     const AD<
Base>               &y
     const VecAD<
Base>::reference &y
The value of y that corresponds to x is written to std::cout during the execution of
     
f.Forward(0, x)

4.3.4.e: f.Forward(0, x)
The objects f, x, and the purpose for this operation, are documented in 5.6.1: Forward .

4.3.4.f: Discussion
This is can be helpful for understanding why tape evaluations have trouble, for example, if the result of a tape calculation is the IEEE code for not a number Nan.

4.3.4.g: Alternative
The 4.3.3: Output section describes the normal printing of values; i.e., printing when the corresponding code is executed.

4.3.4.h: Example
The program 4.3.4.1: PrintFor.cpp is an example and test of this operation. The output of this program states the conditions for passing and failing the test.
Input File: cppad/local/print_for.hpp
4.3.4.1: Printing During Forward Mode: Example and Test

4.3.4.1.a: Program
 
# include <cppad/cppad.hpp>

int main(void)
{
	using namespace CppAD;
	using std::cout;
	using std::endl;

	// independent variable vector
	size_t n = 1;
	CPPAD_TEST_VECTOR< AD<double> > X(n);
	X[0] = 1.;
	Independent(X);

	// print a VecAD<double>::reference object that is a parameter
	VecAD<double> V(1);
	AD<double> Zero(0);
	V[Zero] = 0.;
	PrintFor("v[0] = ", V[Zero]); 

	// dependent variable vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > Y(m);
	Y[0] = V[Zero] + X[0];

	// First print a newline to separate this from previous output,
	// then print an AD<double> object that is a variable.
	PrintFor(  "\nv[0] + x[0] = ", Y[0]); 

	// define f: x -> y and stop tape recording
	ADFun<double> f(X, Y); 

	// zero order forward with x[0] = 2 
	CPPAD_TEST_VECTOR<double> x(n);
	x[0] = 2.;


	cout << "v[0] = 0" << endl; 
	cout << "v[0] + x[0] = 2" << endl; 
	// Developer Note: ./makefile.am "Test passes" to begin next output line
	cout << "Test passes if two lines above repeat below:" << endl;
	f.Forward(0, x);	

	// print a new line after output
	std::cout << std::endl;

	return 0;
}


4.3.4.1.b: Output
Executing the program above generates the following output:
 
	v[0] = 0
	v[0] + x[0] = 2
	Test passes if two lines above repeat below:
	v[0] = 0
	v[0] + x[0] = 2

Input File: print_for/print_for.cpp
4.3.5: Convert an AD Variable to a Parameter

4.3.5.a: Syntax
y = Var2Par(x)

4.3.5.b: Purpose
Returns a 9.4.h: parameter y with the same value as the 9.4.l: variable x.

4.3.5.c: x
The argument x has prototype
     const AD<
Base> &x
The argument x may be a variable or parameter.

4.3.5.d: y
The result y has prototype
     AD<
Base> &y
The return value y will be a parameter.

4.3.5.e: Example
The file 4.3.5.1: Var2Par.cpp contains an example and test of this operation. It returns true if it succeeds and false otherwise.
Input File: cppad/local/var2par.hpp
4.3.5.1: Convert an AD Variable to a Parameter: Example and Test
 

# include <cppad/cppad.hpp>


bool Var2Par(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::Value;
	using CppAD::Var2Par;

	// domain space vector
	size_t n = 2;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0] = 3.;
	x[1] = 4.;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = - x[1] * Var2Par(x[0]);    // same as y[0] = -x[1] * 3.;

	// cannot call Value(x[j]) or Value(y[0]) here (currently variables)
	ok &= ( Value( Var2Par(x[0]) ) == 3. );
	ok &= ( Value( Var2Par(x[1]) ) == 4. ); 
	ok &= ( Value( Var2Par(y[0]) ) == -12. ); 

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y);

	// can call Value(x[j]) or Value(y[0]) here (currently parameters)
	ok &= (Value(x[0]) ==  3.);
	ok &= (Value(x[1]) ==  4.);
	ok &= (Value(y[0]) == -12.);

	// evaluate derivative of y w.r.t x
	CPPAD_TEST_VECTOR<double> w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0] = 1.;
	dw   = f.Reverse(1, w);
	ok  &= (dw[0] == 0.);  // derivative of y[0] w.r.t x[0] is zero
	ok  &= (dw[1] == -3.); // derivative of y[0] w.r.t x[1] is 3

	return ok;
}

Input File: example/var_2par.cpp
4.4: AD Valued Operations and Functions

4.4.a: Contents
Arithmetic: 4.4.1AD Arithmetic Operators and Computed Assignments
std_math_ad: 4.4.2AD Standard Math Unary Functions
MathOther: 4.4.3Other AD Math Functions
CondExp: 4.4.4AD Conditional Expressions
Discrete: 4.4.5Discrete AD Functions

Input File: cppad/local/ad_valued.hpp
4.4.1: AD Arithmetic Operators and Computed Assignments

4.4.1.a: Contents
UnaryPlus: 4.4.1.1AD Unary Plus Operator
UnaryMinus: 4.4.1.2AD Unary Minus Operator
ad_binary: 4.4.1.3AD Binary Arithmetic Operators
compute_assign: 4.4.1.4AD Computed Assignment Operators

Input File: cppad/local/arithmetic.hpp
4.4.1.1: AD Unary Plus Operator

4.4.1.1.a: Syntax
y = + x

4.4.1.1.b: Purpose
Performs the unary plus operation (the result y is equal to the operand x).

4.4.1.1.c: x
The operand x has one of the following prototypes
     const AD<
Base>               &x
     const VecAD<
Base>::reference &x

4.4.1.1.d: y
The result y has type
     AD<
Basey
It is equal to the operand x.

4.4.1.1.e: Operation Sequence
This is an AD of Base 9.4.g.a: atomic operation and hence is part of the current AD of Base 9.4.g.b: operation sequence .

4.4.1.1.f: Derivative
If  f is a 9.4.d: Base function ,  \[
     \D{[ + f(x) ]}{x} = \D{f(x)}{x}
\] 


4.4.1.1.g: Example
The file 4.4.1.1.1: UnaryPlus.cpp contains an example and test of this operation.
Input File: cppad/local/unary_plus.hpp
4.4.1.1.1: AD Unary Plus Operator: Example and Test
 

# include <cppad/cppad.hpp>

bool UnaryPlus(void)
{	bool ok = true;
	using CppAD::AD;


	// domain space vector
	size_t n = 1;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = 3.;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = + x[0];

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y);

	// check values
	ok &= ( y[0] == 3. );

	// forward computation of partials w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	size_t p = 1;
	dx[0]    = 1.;
	dy       = f.Forward(p, dx);
	ok      &= ( dy[0] == 1. );   // dy[0] / dx[0]

	// reverse computation of dertivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0] = 1.;
	dw   = f.Reverse(p, w);
	ok &= ( dw[0] == 1. );       // dy[0] / dx[0]

	// use a VecAD<Base>::reference object with unary plus
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero] = x[0];
	AD<double> result = + v[zero];
	ok     &= (result == y[0]);
	 
	return ok;
}

Input File: example/unary_plus.cpp
4.4.1.2: AD Unary Minus Operator

4.4.1.2.a: Syntax
y = - x

4.4.1.2.b: Purpose
Computes the negative of x.

4.4.1.2.c: Base
The operation in the syntax above must be supported for the case where the operand is a const Base object.

4.4.1.2.d: x
The operand x has one of the following prototypes
     const AD<
Base>               &x
     const VecAD<
Base>::reference &x

4.4.1.2.e: y
The result y has type
     AD<
Basey
It is equal to the negative of the operand x.

4.4.1.2.f: Operation Sequence
This is an AD of Base 9.4.g.a: atomic operation and hence is part of the current AD of Base 9.4.g.b: operation sequence .

4.4.1.2.g: Derivative
If  f is a 9.4.d: Base function ,  \[
     \D{[ - f(x) ]}{x} = - \D{f(x)}{x}
\] 


4.4.1.2.h: Example
The file 4.4.1.2.1: UnaryMinus.cpp contains an example and test of this operation.
Input File: cppad/local/unary_minus.hpp
4.4.1.2.1: AD Unary Minus Operator: Example and Test
 

# include <cppad/cppad.hpp>

bool UnaryMinus(void)
{	bool ok = true;
	using CppAD::AD;


	// domain space vector
	size_t n = 1;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = 3.;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = - x[0];

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y);

	// check values
	ok &= ( y[0] == -3. );

	// forward computation of partials w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	size_t p = 1;
	dx[0]    = 1.;
	dy       = f.Forward(p, dx);
	ok      &= ( dy[0] == -1. );   // dy[0] / dx[0]

	// reverse computation of dertivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0] = 1.;
	dw   = f.Reverse(p, w);
	ok &= ( dw[0] == -1. );       // dy[0] / dx[0]

	// use a VecAD<Base>::reference object with unary minus
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero] = x[0];
	AD<double> result = - v[zero];
	ok     &= (result == y[0]);
	 
	return ok;
}

Input File: example/unary_minus.cpp
4.4.1.3: AD Binary Arithmetic Operators

4.4.1.3.a: Syntax
z = x Op y

4.4.1.3.b: Purpose
Performs arithmetic operations where either x or y has type AD<Base> or 4.6.d: VecAD<Base>::reference .

4.4.1.3.c: Op
The operator Op is one of the following
Op Meaning
+ z is x plus y
- z is x minus y
* z is x times y
/ z is x divided by y

4.4.1.3.d: Base
The type Base is determined by the operand that has type AD<Base> or VecAD<Base>::reference.

4.4.1.3.e: x
The operand x has the following prototype
     const 
Type &x
where Type is VecAD<Base>::reference, AD<Base>, Base, or double.

4.4.1.3.f: y
The operand y has the following prototype
     const 
Type &y
where Type is VecAD<Base>::reference, AD<Base>, Base, or double.

4.4.1.3.g: z
The result z has the following prototype
     
Type z
where Type is AD<Base>.

4.4.1.3.h: Operation Sequence
This is an 9.4.g.a: atomic 9.4.b: AD of Base operation and hence it is part of the current AD of Base 9.4.g.b: operation sequence .

4.4.1.3.i: Example
The following files contain examples and tests of these functions. Each test returns true if it succeeds and false otherwise.
4.4.1.3.1: Add.cpp AD Binary Addition: Example and Test
4.4.1.3.2: Sub.cpp AD Binary Subtraction: Example and Test
4.4.1.3.3: Mul.cpp AD Binary Multiplication: Example and Test
4.4.1.3.4: Div.cpp AD Binary Division: Example and Test

4.4.1.3.j: Derivative
If  f and  g are 9.4.d: Base functions

4.4.1.3.j.a: Addition
 \[
     \D{[ f(x) + g(x) ]}{x} = \D{f(x)}{x} + \D{g(x)}{x}
\] 


4.4.1.3.j.b: Subtraction
 \[
     \D{[ f(x) - g(x) ]}{x} = \D{f(x)}{x} - \D{g(x)}{x}
\] 


4.4.1.3.j.c: Multiplication
 \[
     \D{[ f(x) * g(x) ]}{x} = g(x) * \D{f(x)}{x} + f(x) * \D{g(x)}{x}
\] 


4.4.1.3.j.d: Division
 \[
     \D{[ f(x) / g(x) ]}{x} = 
          [1/g(x)] * \D{f(x)}{x} - [f(x)/g(x)^2] * \D{g(x)}{x}
\] 

Input File: cppad/local/ad_binary.hpp
4.4.1.3.1: AD Binary Addition: Example and Test
 
# include <cppad/cppad.hpp>

bool Add(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0; 

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// some binary addition operations
	AD<double> a = x[0] + 1.; // AD<double> + double
	AD<double> b = a    + 2;  // AD<double> + int
	AD<double> c = 3.   + b;  // double     + AD<double> 
	AD<double> d = 4    + c;  // int        + AD<double> 

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = d + x[0];          // AD<double> + AD<double> 

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	ok &= NearEqual(y[0] , 2. * x0 + 10,  1e-10 , 1e-10);

	// forward computation of partials w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], 2., 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], 2., 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with addition
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero] = a;
	AD<double> result = v[zero] + 2;
	ok     &= (result == b);

	return ok;
}

Input File: example/add.cpp
4.4.1.3.2: AD Binary Subtraction: Example and Test
 
# include <cppad/cppad.hpp>

bool Sub(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t  n =  1;
	double x0 = .5;
	CPPAD_TEST_VECTOR< AD<double> > x(1);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	AD<double> a = 2. * x[0] - 1.; // AD<double> - double
	AD<double> b = a  - 2;         // AD<double> - int
	AD<double> c = 3. - b;         // double     - AD<double> 
	AD<double> d = 4  - c;         // int        - AD<double> 

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = x[0] - d;              // AD<double> - AD<double>

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y);

	// check value 
	ok &= NearEqual(y[0], x0-4.+3.+2.-2.*x0+1.,  1e-10 , 1e-10);

	// forward computation of partials w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], -1., 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], -1., 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with subtraction
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero] = b;
	AD<double> result = 3. - v[zero];
	ok     &= (result == c);

	return ok;
}

Input File: example/sub.cpp
4.4.1.3.3: AD Binary Multiplication: Example and Test
 
# include <cppad/cppad.hpp>

bool Mul(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t n  = 1;
	double x0 = .5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// some binary multiplication operations
	AD<double> a = x[0] * 1.; // AD<double> * double
	AD<double> b = a    * 2;  // AD<double> * int
	AD<double> c = 3.   * b;  // double     * AD<double> 
	AD<double> d = 4    * c;  // int        * AD<double> 

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = x[0] * d;          // AD<double> * AD<double>

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	ok &= NearEqual(y[0] , x0*(4.*3.*2.*1.)*x0,  1e-10 , 1e-10);

	// forward computation of partials w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], (4.*3.*2.*1.)*2.*x0, 1e-10 , 1e-10); 

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n); 
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], (4.*3.*2.*1.)*2.*x0, 1e-10 , 1e-10); 

	// use a VecAD<Base>::reference object with multiplication
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero] = c;
	AD<double> result = 4 * v[zero];
	ok     &= (result == d);

	return ok;
}

Input File: example/mul.cpp
4.4.1.3.4: AD Binary Division: Example and Test
 
# include <cppad/cppad.hpp>

bool Div(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::NearEqual;


	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// some binary division operations
	AD<double> a = x[0] / 1.; // AD<double> / double
	AD<double> b = a  / 2;    // AD<double> / int
	AD<double> c = 3. / b;    // double     / AD<double> 
	AD<double> d = 4  / c;    // int        / AD<double> 

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = (x[0] * x[0]) / d;   // AD<double> / AD<double>

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	ok &= NearEqual(y[0], x0*x0*3.*2.*1./(4.*x0),  1e-10 , 1e-10);

	// forward computation of partials w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], 3.*2.*1./4., 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], 3.*2.*1./4., 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with division
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero] = d;
	AD<double> result = (x[0] * x[0]) / v[zero];
	ok     &= (result == y[0]);

	return ok;
}

Input File: example/div.cpp
4.4.1.4: AD Computed Assignment Operators

4.4.1.4.a: Syntax
x Op y

4.4.1.4.b: Purpose
Performs computed assignment operations where either x has type AD<Base>.

4.4.1.4.c: Op
The operator Op is one of the following
Op Meaning
+= x is assigned x plus y
-= x is assigned x minus y
*= x is assigned x times y
/= x is assigned x divided by y

4.4.1.4.d: Base
The type Base is determined by the operand x.

4.4.1.4.e: x
The operand x has the following prototype
     AD<
Base> &x

4.4.1.4.f: y
The operand y has the following prototype
     const 
Type &y
where Type is VecAD<Base>::reference, AD<Base>, Base, or double.

4.4.1.4.g: Result
The result of this assignment can be used as a reference to x. For example, if z has the following type
     AD<
Basez
then the syntax
     
z = x += y
will compute x plus y and then assign this value to both x and z.

4.4.1.4.h: Operation Sequence
This is an 9.4.g.a: atomic 9.4.b: AD of Base operation and hence it is part of the current AD of Base 9.4.g.b: operation sequence .

4.4.1.4.i: Example
The following files contain examples and tests of these functions. Each test returns true if it succeeds and false otherwise.
4.4.1.4.1: AddEq.cpp AD Computed Assignment Addition: Example and Test
4.4.1.4.2: SubEq.cpp AD Computed Assignment Subtraction: Example and Test
4.4.1.4.3: MulEq.cpp AD Computed Assignment Multiplication: Example and Test
4.4.1.4.4: DivEq.cpp AD Computed Assignment Division: Example and Test

4.4.1.4.j: Derivative
If  f and  g are 9.4.d: Base functions

4.4.1.4.j.a: Addition
 \[
     \D{[ f(x) + g(x) ]}{x} = \D{f(x)}{x} + \D{g(x)}{x}
\] 


4.4.1.4.j.b: Subtraction
 \[
     \D{[ f(x) - g(x) ]}{x} = \D{f(x)}{x} - \D{g(x)}{x}
\] 


4.4.1.4.j.c: Multiplication
 \[
     \D{[ f(x) * g(x) ]}{x} = g(x) * \D{f(x)}{x} + f(x) * \D{g(x)}{x}
\] 


4.4.1.4.j.d: Division
 \[
     \D{[ f(x) / g(x) ]}{x} = 
          [1/g(x)] * \D{f(x)}{x} - [f(x)/g(x)^2] * \D{g(x)}{x}
\] 

Input File: cppad/local/compute_assign.hpp
4.4.1.4.1: AD Computed Assignment Addition: Example and Test
 
# include <cppad/cppad.hpp>

bool AddEq(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t  n = 1;
	double x0 = .5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0; 

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// range space vector 
	size_t m = 2;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = x[0];         // initial value
	y[0] += 2;           // AD<double> += int
	y[0] += 4.;          // AD<double> += double
	y[1] = y[0] += x[0]; // use the result of a computed assignment

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	ok &= NearEqual(y[0] , x0+2.+4.+x0,  1e-10 , 1e-10);
	ok &= NearEqual(y[1] ,        y[0],  1e-10 , 1e-10);

	// forward computation of partials w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], 2., 1e-10, 1e-10);
	ok   &= NearEqual(dy[1], 2., 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	w[1]  = 0.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], 2., 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with computed addition
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	AD<double> result = 1;
	v[zero] = 2;
	result += v[zero];
	ok     &= (result == 3);

	return ok;
}

Input File: example/add_eq.cpp
4.4.1.4.2: AD Computed Assignment Subtraction: Example and Test
 
# include <cppad/cppad.hpp>

bool SubEq(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t  n = 1;
	double x0 = .5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0; 

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// range space vector 
	size_t m = 2;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = 3. * x[0];    // initial value
	y[0] -= 2;           // AD<double> -= int
	y[0] -= 4.;          // AD<double> -= double
	y[1] = y[0] -= x[0]; // use the result of a computed assignment

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	ok &= NearEqual(y[0] , 3.*x0-(2.+4.+x0),  1e-10 , 1e-10);
	ok &= NearEqual(y[1] ,             y[0],  1e-10 , 1e-10);

	// forward computation of partials w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], 2., 1e-10, 1e-10);
	ok   &= NearEqual(dy[1], 2., 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	w[1]  = 0.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], 2., 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with computed subtraction
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	AD<double> result = 1;
	v[zero] = 2;
	result -= v[zero];
	ok     &= (result == -1);

	return ok;
}

Input File: example/sub_eq.cpp
4.4.1.4.3: AD Computed Assignment Multiplication: Example and Test
 
# include <cppad/cppad.hpp>

bool MulEq(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t  n = 1;
	double x0 = .5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0; 

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// range space vector 
	size_t m = 2;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = x[0];         // initial value
	y[0] *= 2;           // AD<double> *= int
	y[0] *= 4.;          // AD<double> *= double
	y[1] = y[0] *= x[0]; // use the result of a computed assignment

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	ok &= NearEqual(y[0] , x0*2.*4.*x0,  1e-10 , 1e-10);
	ok &= NearEqual(y[1] ,        y[0],  1e-10 , 1e-10);

	// forward computation of partials w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], 8.*2.*x0, 1e-10, 1e-10);
	ok   &= NearEqual(dy[1], 8.*2.*x0, 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	w[1]  = 0.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], 8.*2.*x0, 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with computed multiplication
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	AD<double> result = 1;
	v[zero] = 2;
	result *= v[zero];
	ok     &= (result == 2);

	return ok;
}

Input File: example/mul_eq.cpp
4.4.1.4.4: AD Computed Assignment Division: Example and Test
 
# include <cppad/cppad.hpp>

bool DivEq(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t  n = 1;
	double x0 = .5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0; 

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// range space vector 
	size_t m = 2;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = x[0] * x[0];  // initial value
	y[0] /= 2;           // AD<double> /= int
	y[0] /= 4.;          // AD<double> /= double
	y[1] = y[0] /= x[0]; // use the result of a computed assignment

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	ok &= NearEqual(y[0] , x0*x0/(2.*4.*x0),  1e-10 , 1e-10);
	ok &= NearEqual(y[1] ,             y[0],  1e-10 , 1e-10);

	// forward computation of partials w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], 1./8., 1e-10, 1e-10);
	ok   &= NearEqual(dy[1], 1./8., 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	w[1]  = 0.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], 1./8., 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with computed division
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	AD<double> result = 2;
	v[zero] = 1;
	result /= v[zero];
	ok     &= (result == 2);

	return ok;
}

Input File: example/div_eq.cpp
4.4.2: AD Standard Math Unary Functions

4.4.2.a: Syntax
y = fun(x)

4.4.2.b: Purpose
Evaluates the one argument standard math function fun where its argument is an 9.4.b: AD of Base object.

4.4.2.c: x
The argument x has one of the following prototypes
     const AD<
Base>               &x
     const VecAD<
Base>::reference &x

4.4.2.d: y
The result y has prototype
     AD<
Basey

4.4.2.e: Operation Sequence
Most of these functions are AD of Base 9.4.g.a: atomic operations . In all cases, The AD of Base operation sequence used to calculate y is 9.4.g.d: independent of x.

4.4.2.f: fun
A definition of fun is included for each of the following functions: acos, asin, atan, cos, cosh, exp, log, log10, sin, sinh, sqrt, tan, tanh.

4.4.2.g: Examples
The following files contain examples and tests of these functions. Each test returns true if it succeeds and false otherwise.
4.4.2.1: Acos.cpp The AD acos Function: Example and Test
4.4.2.2: Asin.cpp The AD asin Function: Example and Test
4.4.2.3: Atan.cpp The AD atan Function: Example and Test
4.4.2.4: Cos.cpp The AD cos Function: Example and Test
4.4.2.5: Cosh.cpp The AD cosh Function: Example and Test
4.4.2.6: Exp.cpp The AD exp Function: Example and Test
4.4.2.7: Log.cpp The AD log Function: Example and Test
4.4.2.8: Log10.cpp The AD log10 Function: Example and Test
4.4.2.9: Sin.cpp The AD sin Function: Example and Test
4.4.2.10: Sinh.cpp The AD sinh Function: Example and Test
4.4.2.11: Sqrt.cpp The AD sqrt Function: Example and Test
4.4.2.12: Tan.cpp The AD tan Function: Example and Test
4.4.2.13: Tanh.cpp The AD tanh Function: Example and Test

4.4.2.h: Derivatives
Each of these functions satisfy a standard math function differential equation. Calculating derivatives using this differential equation is discussed for both 9.3.1.c: forward and 9.3.2.c: reverse mode. The exact form of the differential equation for each of these functions is listed below:

4.4.2.h.a: acos
 \[
\begin{array}{lcr}
     \D{[ {\rm acos} (x) ]}{x} & = & - (1 - x * x)^{-1/2}
\end{array}
\] 


4.4.2.h.b: asin
 \[
\begin{array}{lcr}
     \D{[ {\rm asin} (x) ]}{x} & = & (1 - x * x)^{-1/2}
\end{array}
\] 


4.4.2.h.c: atan
 \[
\begin{array}{lcr}
        \D{[ {\rm atan} (x) ]}{x} & = & \frac{1}{1 + x^2}
\end{array}
\] 


4.4.2.h.d: cos
 \[
\begin{array}{lcr}
        \D{[ \cos (x) ]}{x} & = & - \sin (x)  \\
        \D{[ \sin (x) ]}{x} & = & \cos (x)
\end{array}
\] 


4.4.2.h.e: cosh
 \[
\begin{array}{lcr}
        \D{[ \cosh (x) ]}{x} & = & \sinh (x)  \\
        \D{[ \sin (x) ]}{x}  & = & \cosh (x)
\end{array}
\] 


4.4.2.h.f: exp
 \[
\begin{array}{lcr}
        \D{[ \exp (x) ]}{x} & = & \exp (x)
\end{array}
\] 


4.4.2.h.g: log
 \[
\begin{array}{lcr}
        \D{[ \log (x) ]}{x} & = & \frac{1}{x}
\end{array}
\] 


4.4.2.h.h: log10
This function is special in that it's derivatives are calculated using the relation  \[
\begin{array}{lcr}
        {\rm log10} (x) & = & \log(x) / \log(10)
\end{array}
\] 


4.4.2.h.i: sin
 \[
\begin{array}{lcr}
        \D{[ \sin (x) ]}{x} & = & \cos (x) \\
        \D{[ \cos (x) ]}{x} & = & - \sin (x) 
\end{array}
\] 


4.4.2.h.j: sinh
 \[
\begin{array}{lcr}
        \D{[ \sinh (x) ]}{x} & = & \cosh (x)   \\
        \D{[ \cosh (x) ]}{x} & = & \sinh (x)
\end{array}
\] 


4.4.2.h.k: sqrt
 \[
\begin{array}{lcr}
        \D{[ {\rm sqrt} (x) ]}{x} & = & \frac{1}{2 {\rm sqrt} (x) }
\end{array}
\] 


4.4.2.h.l: tan
This function is special in that it's derivatives are calculated using the relation  \[
\begin{array}{lcr}
        \tan (x) & = & \sin(x) / \cos(x)
\end{array}
\] 


4.4.2.h.m: tanh
This function is also special in that it's derivatives are calculated using the relation  \[
\begin{array}{lcr}
        \tanh (x) & = & \sinh(x) / \cosh(x)
\end{array}
\] 

Input File: cppad/local/std_math_ad.hpp
4.4.2.1: The AD acos Function: Example and Test
 

# include <cppad/cppad.hpp>

bool Acos(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// a temporary value
	AD<double> cos_of_x0 = CppAD::cos(x[0]);

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = CppAD::acos(cos_of_x0);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	ok &= NearEqual(y[0] , x0,  1e-10 , 1e-10);

	// forward computation of first partial w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], 1., 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], 1., 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with acos
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero] = cos_of_x0;
	AD<double> result = CppAD::acos(v[zero]);
	ok     &= NearEqual(result, x0, 1e-10, 1e-10);

	return ok;
}

Input File: example/acos.cpp
4.4.2.2: The AD asin Function: Example and Test
 

# include <cppad/cppad.hpp>

bool Asin(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// a temporary value
	AD<double> sin_of_x0 = CppAD::sin(x[0]);

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = CppAD::asin(sin_of_x0);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	ok &= NearEqual(y[0] , x0,  1e-10 , 1e-10);

	// forward computation of first partial w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], 1., 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], 1., 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with asin
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero] = sin_of_x0;
	AD<double> result = CppAD::asin(v[zero]);
	ok     &= NearEqual(result, x0, 1e-10, 1e-10);

	return ok;
}

Input File: example/asin.cpp
4.4.2.3: The AD atan Function: Example and Test
 

# include <cppad/cppad.hpp>

bool Atan(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// a temporary value
	AD<double> tan_of_x0 = CppAD::tan(x[0]);

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = CppAD::atan(tan_of_x0);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	ok &= NearEqual(y[0] , x0,  1e-10 , 1e-10);

	// forward computation of first partial w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], 1., 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], 1., 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with atan
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero] = tan_of_x0;
	AD<double> result = CppAD::atan(v[zero]);
	ok     &= NearEqual(result, x0, 1e-10, 1e-10);

	return ok;
}

Input File: example/atan.cpp
4.4.2.4: The AD cos Function: Example and Test
 

# include <cppad/cppad.hpp>
# include <cmath>

bool Cos(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = CppAD::cos(x[0]);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	double check = std::cos(x0);
	ok &= NearEqual(y[0] , check,  1e-10 , 1e-10);

	// forward computation of first partial w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	check = - std::sin(x0);
	ok   &= NearEqual(dy[0], check, 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], check, 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with cos
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero]           = x0;
	AD<double> result = CppAD::cos(v[zero]);
	check = std::cos(x0);
	ok   &= NearEqual(result, check, 1e-10, 1e-10);

	return ok;
}

Input File: example/cos.cpp
4.4.2.5: The AD cosh Function: Example and Test
 

# include <cppad/cppad.hpp>
# include <cmath>

bool Cosh(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = CppAD::cosh(x[0]);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	double check = std::cosh(x0);
	ok &= NearEqual(y[0] , check,  1e-10 , 1e-10);

	// forward computation of first partial w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	check = std::sinh(x0);
	ok   &= NearEqual(dy[0], check, 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], check, 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with cosh
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero]           = x0;
	AD<double> result = CppAD::cosh(v[zero]);
	check = std::cosh(x0);
	ok   &= NearEqual(result, check, 1e-10, 1e-10);

	return ok;
}

Input File: example/cosh.cpp
4.4.2.6: The AD exp Function: Example and Test
 

# include <cppad/cppad.hpp>
# include <cmath>

bool Exp(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = CppAD::exp(x[0]);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	double check = std::exp(x0);
	ok &= NearEqual(y[0] , check,  1e-10 , 1e-10);

	// forward computation of first partial w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	check = std::exp(x0);
	ok   &= NearEqual(dy[0], check, 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], check, 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with exp
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero]           = x0;
	AD<double> result = CppAD::exp(v[zero]);
	ok   &= NearEqual(result, check, 1e-10, 1e-10);

	return ok;
}

Input File: example/exp.cpp
4.4.2.7: The AD log Function: Example and Test
 

# include <cppad/cppad.hpp>

bool Log(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// a temporary value
	AD<double> exp_of_x0 = CppAD::exp(x[0]);

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = CppAD::log(exp_of_x0);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	ok &= NearEqual(y[0] , x0,  1e-10 , 1e-10);

	// forward computation of first partial w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], 1., 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], 1., 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with log
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero]           = exp_of_x0;
	AD<double> result = CppAD::log(v[zero]);
	ok   &= NearEqual(result, x0, 1e-10, 1e-10);

	return ok;
}

Input File: example/log.cpp
4.4.2.8: The AD log10 Function: Example and Test
 

# include <cppad/cppad.hpp>

bool Log10(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// ten raised to the x0 power
	AD<double> ten = 10.;
	AD<double> pow_10_x0 = CppAD::pow(ten, x[0]); 

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = CppAD::log10(pow_10_x0);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	ok &= NearEqual(y[0] , x0,  1e-10 , 1e-10);

	// forward computation of first partial w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], 1., 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], 1., 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with log10
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero]           = pow_10_x0;
	AD<double> result = CppAD::log10(v[zero]);
	ok   &= NearEqual(result, x0, 1e-10, 1e-10);

	return ok;
}

Input File: example/log_10.cpp
4.4.2.9: The AD sin Function: Example and Test
 

# include <cppad/cppad.hpp>
# include <cmath>

bool Sin(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = CppAD::sin(x[0]);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	double check = std::sin(x0);
	ok &= NearEqual(y[0] , check,  1e-10 , 1e-10);

	// forward computation of first partial w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	check = std::cos(x0);
	ok   &= NearEqual(dy[0], check, 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], check, 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with sin
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero]           = x0;
	AD<double> result = CppAD::sin(v[zero]);
	check = std::sin(x0);
	ok   &= NearEqual(result, check, 1e-10, 1e-10);

	return ok;
}

Input File: example/sin.cpp
4.4.2.10: The AD sinh Function: Example and Test
 

# include <cppad/cppad.hpp>
# include <cmath>

bool Sinh(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = CppAD::sinh(x[0]);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	double check = std::sinh(x0);
	ok &= NearEqual(y[0] , check,  1e-10 , 1e-10);

	// forward computation of first partial w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	check = std::cosh(x0);
	ok   &= NearEqual(dy[0], check, 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], check, 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with sinh
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero]           = x0;
	AD<double> result = CppAD::sinh(v[zero]);
	check = std::sinh(x0);
	ok   &= NearEqual(result, check, 1e-10, 1e-10);

	return ok;
}

Input File: example/sinh.cpp
4.4.2.11: The AD sqrt Function: Example and Test
 

# include <cppad/cppad.hpp>
# include <cmath>

bool Sqrt(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = CppAD::sqrt(x[0]);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	double check = std::sqrt(x0);
	ok &= NearEqual(y[0] , check,  1e-10 , 1e-10);

	// forward computation of first partial w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	check = 1. / (2. * std::sqrt(x0) );
	ok   &= NearEqual(dy[0], check, 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], check, 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with sqrt
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero]           = x0;
	AD<double> result = CppAD::sqrt(v[zero]);
	check = std::sqrt(x0);
	ok   &= NearEqual(result, check, 1e-10, 1e-10);

	return ok;
}

Input File: example/sqrt.cpp
4.4.2.12: The AD tan Function: Example and Test
 

# include <cppad/cppad.hpp>
# include <cmath>
# include <limits>

bool Tan(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;
	double eps = 10. * std::numeric_limits<double>::epsilon();

	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = CppAD::tan(x[0]);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	double check = std::tan(x0);
	ok &= NearEqual(y[0] , check,  eps, eps);

	// forward computation of first partial w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	check = 1. + std::tan(x0) * std::tan(x0); 
	ok   &= NearEqual(dy[0], check, eps, eps);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], check, eps, eps);

	// use a VecAD<Base>::reference object with tan
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero]           = x0;
	AD<double> result = CppAD::tan(v[zero]);
	check = std::tan(x0);
	ok   &= NearEqual(result, check, eps, eps);

	return ok;
}

Input File: example/tan.cpp
4.4.2.13: The AD tanh Function: Example and Test
 

# include <cppad/cppad.hpp>
# include <cmath>
# include <limits>

bool Tanh(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;
	double eps = 10. * std::numeric_limits<double>::epsilon();

	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = CppAD::tanh(x[0]);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	double check = std::tanh(x0);
	ok &= NearEqual(y[0] , check,  eps, eps);

	// forward computation of first partial w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	check = 1. - std::tanh(x0) * std::tanh(x0); 
	ok   &= NearEqual(dy[0], check, eps, eps);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], check, eps, eps);

	// use a VecAD<Base>::reference object with tan
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero]           = x0;
	AD<double> result = CppAD::tanh(v[zero]);
	check = std::tanh(x0);
	ok   &= NearEqual(result, check, eps, eps);

	return ok;
}

Input File: example/tanh.cpp
4.4.3: Other AD Math Functions
4.4.3.1: abs AD Absolute Value Function
4.4.3.2: atan2 AD Two Argument Inverse Tangent Function
4.4.3.3: erf The AD Error Function
4.4.3.4: pow The AD Power Function

Input File: cppad/local/math_other.hpp
4.4.3.1: AD Absolute Value Function

4.4.3.1.a: Syntax
y = abs(x)

4.4.3.1.b: Purpose
Evaluates the absolute value function.

4.4.3.1.c: x
The argument x has one of the following prototypes
     const AD<
Base>               &x
     const VecAD<
Base>::reference &x

4.4.3.1.d: y
The result y has prototype
     AD<
Basey

4.4.3.1.e: Operation Sequence
This is an AD of Base 9.4.g.a: atomic operation and hence is part of the current AD of Base 9.4.g.b: operation sequence .

4.4.3.1.f: Complex Types
The function abs is not defined for the AD type sequences above std::complex<float> or std::complex<double> because the complex abs function is not complex differentiable (see 9.1.d: complex types faq ).

4.4.3.1.g: Directional Derivative
The derivative of the absolute value function is one for  x > 0 and minus one for  x < 0 . The subtitle issue is how to compute its directional derivative what  x = 0 .

The function corresponding to the argument x and the result y are represented by their Taylor coefficients; i.e.,  \[
\begin{array}{rcl}
     X(t) & = & x^{(0)} (t) + x^{(1)} t + \cdots + x^{(p)} t^p
     \\
     Y(t) & = & y^{(0)} (t) + y^{(1)} t + \cdots + y^{(p)} t^p
\end{array}
\] 
Note that  x^{(0)} = X(0) is the value of x and  y^{(0)} = Y(0) is the value of y. In the equations above, the order  p is specified by a call to 5.6.1: Forward or 5.6.2: Reverse as follows:
     
f.Forward(pdx)
     
f.Reverse(p+1, w)
If all of the Taylor coefficients of  X(t) are zero, we define  k = p . Otherwise, we define  k to be the minimal index such that  x^{(k)} \neq 0 . Note that if  x \neq 0 ,  k = 0 . The Taylor coefficient representation of  Y(t) (and hence it's derivatives) are computed as  \[
y^{(\ell)}
=
\left\{ \begin{array}{ll} 
      x^{(\ell)}   & {\rm if} \; x^{(k)} > 0         \\
      0                    & {\rm if} \; x^{(k)} = 0 \\
     - x^{(\ell)}  & {\rm if} \; x^{(k)} < 0
\end{array} \right.
\] 


4.4.3.1.h: Example
The file 4.4.3.1.1: Abs.cpp contains an example and test of this function. It returns true if it succeeds and false otherwise.
Input File: cppad/local/abs.hpp
4.4.3.1.1: AD Absolute Value Function: Example and Test
 

# include <cppad/cppad.hpp>

bool Abs(void)
{	bool ok = true;

	using CppAD::abs;
	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t n = 1;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]     = 0.;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// range space vector
	size_t m = 3;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0]     = abs(x[0] - 1.);
	y[1]     = abs(x[0]);
	y[2]     = abs(x[0] + 1.);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y);

	// check values
	ok &= (y[0] == 1.);
	ok &= (y[1] == 0.);
	ok &= (y[2] == 1.);

	// forward computation of partials w.r.t. a positive x[0] direction
	size_t p = 1;
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(p, dx);
	ok  &= (dy[0] == - dx[0]);
	ok  &= (dy[1] == + dx[0]);
	ok  &= (dy[2] == + dx[0]);

	// forward computation of partials w.r.t. a negative x[0] direction
	dx[0] = -1.;
	dy    = f.Forward(p, dx);
	ok  &= (dy[0] == - dx[0]);
	ok  &= (dy[1] == - dx[0]);
	ok  &= (dy[2] == + dx[0]);

	// reverse computation of derivative of y[0] 
	p    = 0;
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0] = 1.; w[1] = 0.; w[2] = 0.;
	dw   = f.Reverse(p+1, w);
	ok  &= (dw[0] == -1.);

	// reverse computation of derivative of y[1] 
	w[0] = 0.; w[1] = 1.; w[2] = 0.;
	dw   = f.Reverse(p+1, w);
	ok  &= (dw[0] == 0.);

	// reverse computation of derivative of y[2] 
	w[0] = 0.; w[1] = 0.; w[2] = 1.;
	dw   = f.Reverse(p+1, w);
	ok  &= (dw[0] == 1.);

	// use a VecAD<Base>::reference object with abs
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero]           = -1;
	AD<double> result = abs(v[zero]);
	ok   &= NearEqual(result, 1., 1e-10, 1e-10);

	return ok;
}

Input File: example/abs.cpp
4.4.3.2: AD Two Argument Inverse Tangent Function

4.4.3.2.a: Syntax
theta = atan2(yx)

4.4.3.2.b: Purpose
Determines an angle  \theta \in [ - \pi , + \pi ] such that  \[
\begin{array}{rcl}
     \sin ( \theta )  & = & y / \sqrt{ x^2 + y^2 }  \\
     \cos ( \theta )  & = & x / \sqrt{ x^2 + y^2 }
\end{array}
\] 


4.4.3.2.c: y
The argument y has one of the following prototypes
     const AD<
Base>               &y
     const VecAD<
Base>::reference &y

4.4.3.2.d: x
The argument x has one of the following prototypes
     const AD<
Base>               &x
     const VecAD<
Base>::reference &x

4.4.3.2.e: theta
The result theta has prototype
     AD<
Basetheta

4.4.3.2.f: Operation Sequence
The AD of Base operation sequence used to calculate theta is 9.4.g.d: independent of x and y.

4.4.3.2.g: Example
The file 4.4.3.2.1: Atan2.cpp contains an example and test of this function. It returns true if it succeeds and false otherwise.
Input File: cppad/local/atan2.hpp
4.4.3.2.1: The AD atan2 Function: Example and Test
 

# include <cppad/cppad.hpp>

bool Atan2(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// a temporary value
	AD<double> sin_of_x0 = CppAD::sin(x[0]);
	AD<double> cos_of_x0 = CppAD::cos(x[0]);

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = CppAD::atan2(sin_of_x0, cos_of_x0);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	ok &= NearEqual(y[0] , x0,  1e-10 , 1e-10);

	// forward computation of first partial w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], 1., 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], 1., 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with atan2
	CppAD::VecAD<double> v(2);
	AD<double> zero(0);
	AD<double> one(1);
	v[zero]           = sin_of_x0;
	v[one]            = cos_of_x0;
	AD<double> result = CppAD::atan2(v[zero], v[one]);
	ok               &= NearEqual(result, x0, 1e-10, 1e-10);

	return ok;
}

Input File: example/atan_2.cpp
4.4.3.3: The AD Error Function

4.4.3.3.a: Syntax
y = erf(x)

4.4.3.3.b: Description
Returns the value of the error function which is defined by  \[
{\rm erf} (x) = \frac{2}{ \sqrt{\pi} } \int_0^x \exp( - t * t ) \; {\bf d} t
\] 


4.4.3.3.c: x
The argument x , and the result y have one of the following paris of prototypes:
     const float
                  &x,     float    y
     const double
                 &x,     double   y
     const AD<
Base>               &x,     AD<Basey
     const VecAD<
Base>::reference &x,     AD<Basey

4.4.3.3.d: Operation Sequence
The AD of Base operation sequence used to calculate y is 9.4.g.d: independent of x .

4.4.3.3.e: Method
This is a fast approximation (few numerical operations) with relative error bound  4 \times 10^{-4} ; see Vedder, J.D., Simple approximations for the error function and its inverse, American Journal of Physics, v 55, n 8, 1987, p 762-3.

4.4.3.3.f: Example
The file 4.4.3.3.1: Erf.cpp contains an example and test of this function. It returns true if it succeeds and false otherwise.
Input File: cppad/local/erf.hpp
4.4.3.3.1: The AD erf Function: Example and Test
 

# include <cppad/cppad.hpp>
# include <cmath>
# include <limits>

bool Erf(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;
	double eps = 10. * std::numeric_limits<double>::epsilon();

	// domain space vector
	size_t n  = 1;
	double x0 = 0.5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0;

	// declare independent variables and start tape recording
	CppAD::Independent(x);

	// a temporary value

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = CppAD::erf(x[0]);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check relative erorr 
	double erf_x0 = 0.5205;
	ok &= NearEqual(y[0] , erf_x0,  4e-4 , 0.);

	// value of derivative of erf at x0
	double pi     = 4. * std::atan(1.);
	double factor = 2. / sqrt(pi);
	double check  = factor * std::exp(-x0 * x0);

	// forward computation of first partial w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], check, 4e-4, 0.);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], check, 4e-4, 0.);

	// use a VecAD<Base>::reference object with erf
	CppAD::VecAD<double> v(1);
	AD<double> zero(0);
	v[zero]           = x0;
	AD<double> result = CppAD::erf(v[zero]);
	ok   &= NearEqual(result, y[0], eps, eps);

	// use a double with erf
	ok   &= NearEqual(CppAD::erf(x0), y[0], eps, eps);

	return ok;
}

Input File: example/erf.cpp
4.4.3.4: The AD Power Function

4.4.3.4.a: Syntax
z = pow(xy)

4.4.3.4.b: Purpose
Determines the value of the power function which is defined by  \[
     {\rm pow} (x, y) = x^y
\] 
This version of the pow function may use logarithms and exponentiation to compute derivatives. This will not work if x is less than or equal zero. If the value of y is an integer, the 6.10: pow_int function is used to compute this value using only multiplication (and division if y is negative). (This will work even if x is less than or equal zero.)

4.4.3.4.c: x
The argument x has the following prototype
     const 
Type &x
where Type is VecAD<Base>::reference, AD<Base>, Base, double, or int.

4.4.3.4.d: y
The argument y has the following prototype
     const 
Type &y
where Type is VecAD<Base>::reference, AD<Base>, Base, double, or int.

4.4.3.4.e: z
The result z has prototype
     AD<
Basez

4.4.3.4.f: Standard Types
A definition for the pow function is included in the CppAD namespace for the case where both x and y have the same type and that type is float or double.

4.4.3.4.g: Operation Sequence
This is an AD of Base 9.4.g.a: atomic operation and hence is part of the current AD of Base 9.4.g.b: operation sequence .

4.4.3.4.h: Example
The files 4.4.3.4.1: Pow.cpp , 4.4.3.4.2: pow_int.cpp contain an examples and tests of this function. They returns true if they succeed and false otherwise.
Input File: cppad/local/pow.hpp
4.4.3.4.1: The AD Power Function: Example and Test
 

# include <cppad/cppad.hpp>
# include <cmath>

bool Pow(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t n  = 2;
	double x = 0.5;
	double y = 2.;
	CPPAD_TEST_VECTOR< AD<double> > XY(n);
	XY[0]      = x;
	XY[1]      = y;

	// declare independent variables and start tape recording
	CppAD::Independent(XY);

	// range space vector 
	size_t m = 3;
	CPPAD_TEST_VECTOR< AD<double> > Z(m);
	Z[0] = CppAD::pow(XY[0], XY[1]);  // pow(variable, variable)
	Z[1] = CppAD::pow(XY[0], y);      // pow(variable, parameter)
	Z[2] = CppAD::pow(x,     XY[1]);  // pow(parameter, variable)

	// create f: XY -> Z and stop tape recording
	CppAD::ADFun<double> f(XY, Z); 

	// check value 
	double check = std::pow(x, y);
	size_t i;
	for(i = 0; i < m; i++)
		ok &= NearEqual(Z[i] , check,  1e-10 , 1e-10);

	// forward computation of first partial w.r.t. x
	CPPAD_TEST_VECTOR<double> dxy(n);
	CPPAD_TEST_VECTOR<double> dz(m);
	dxy[0] = 1.;
	dxy[1] = 0.;
	dz    = f.Forward(1, dxy);
	check = y * std::pow(x, y-1.);
	ok   &= NearEqual(dz[0], check, 1e-10, 1e-10);
	ok   &= NearEqual(dz[1], check, 1e-10, 1e-10);
	ok   &= NearEqual(dz[2],    0., 1e-10, 1e-10);

	// forward computation of first partial w.r.t. y
	dxy[0] = 0.;
	dxy[1] = 1.;
	dz    = f.Forward(1, dxy);
	check = std::log(x) * std::pow(x, y);
	ok   &= NearEqual(dz[0], check, 1e-10, 1e-10);
	ok   &= NearEqual(dz[1],    0., 1e-10, 1e-10);
	ok   &= NearEqual(dz[2], check, 1e-10, 1e-10);

	// reverse computation of derivative of z[0] + z[1] + z[2]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	w[1]  = 1.;
	w[2]  = 1.;
	dw    = f.Reverse(1, w);
	check = y * std::pow(x, y-1.);
	ok   &= NearEqual(dw[0], 2. * check, 1e-10, 1e-10);
	check = std::log(x) * std::pow(x, y);
	ok   &= NearEqual(dw[1], 2. * check, 1e-10, 1e-10);

	// use a VecAD<Base>::reference object with pow
	CppAD::VecAD<double> v(2);
	AD<double> zero(0);
	AD<double> one(1);
	v[zero]           = XY[0];
	v[one]            = XY[1];
	AD<double> result = CppAD::pow(v[zero], v[one]);
	ok               &= NearEqual(result, Z[0], 1e-10, 1e-10);

	return ok;
}

Input File: example/pow.cpp
4.4.3.4.2: The Pow Integer Exponent: Example and Test
 

# include <cppad/cppad.hpp>
# include <cmath>

bool pow_int(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;

	// declare independent variables and start tape recording
	size_t n  = 1;
	double x0 = -0.5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0;
	CppAD::Independent(x);

	// dependent variable vector 
	size_t m = 7;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	int i;
	for(i = 0; i < int(m); i++) 
		y[i] = CppAD::pow(x[0], i - 3);

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	double check;
	for(i = 0; i < int(m); i++) 
	{	check = std::pow(x0, double(i - 3));
		ok &= NearEqual(y[i] , check,  1e-10 , 1e-10);
	}

	// forward computation of first partial w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dy    = f.Forward(1, dx);
	for(i = 0; i < int(m); i++) 
	{	check = double(i-3) * std::pow(x0, double(i - 4));
		ok &= NearEqual(dy[i] , check,  1e-10 , 1e-10);
	}

	// reverse computation of derivative of y[i]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	for(i = 0; i < int(m); i++) 
		w[i] = 0.;
	for(i = 0; i < int(m); i++) 
	{	w[i] = 1.;	
		dw    = f.Reverse(1, w);
		check = double(i-3) * std::pow(x0, double(i - 4));
		ok &= NearEqual(dw[0] , check,  1e-10 , 1e-10);
		w[i] = 0.;	
	}

	return ok;
}

Input File: example/pow_int.cpp
4.4.4: AD Conditional Expressions

4.4.4.a: Syntax
result = CondExpRel(leftrightexp_if_trueexp_if_false)

4.4.4.b: Purpose
Record, as part of an AD of Base 9.4.g.b: operation sequence , the conditional result
     if( 
left Cop right )
          
result = exp_if_true
     else 
result = exp_if_false
The relational Rel and comparison operator Cop above have the following correspondence:
Rel    Lt    Le    Eq    Ge    Gt
Cop < <= == >= >
If f is the 5: ADFun object corresponding to the AD operation sequence, the assignment choice for result in an AD conditional expression is made each time 5.6.1: f.Forward is used to evaluate the zero order Taylor coefficients with new values for the 9.4.j.c: independent variables . This is in contrast to the 4.5.1: AD comparison operators which are boolean valued and not included in the AD operation sequence.

4.4.4.c: Rel
In the syntax above, the relation Rel represents one of the following two characters: Lt, Le, Eq, Ge, Gt. As in the table above, Rel determines which comparison operator Cop is used when comparing left and right .

4.4.4.d: Type
These functions are defined in the CppAD namespace for arguments of Type is float , double, or any type of the form AD<Base> . (Note that all four arguments must have the same type.)

4.4.4.e: left
The argument left has prototype
     const 
Type &left
It specifies the value for the left side of the comparison operator.

4.4.4.f: right
The argument right has prototype
     const 
Type &right
It specifies the value for the right side of the comparison operator.

4.4.4.g: exp_if_true
The argument exp_if_true has prototype
     const 
Type &exp_if_true
It specifies the return value if the result of the comparison is true.

4.4.4.h: exp_if_false
The argument exp_if_false has prototype
     const 
Type &exp_if_false
It specifies the return value if the result of the comparison is false.

4.4.4.i: result
The result has prototype
     
Type &exp_if_false

4.4.4.j: CondExp
Previous versions of CppAD used
     CondExp(
flagexp_if_trueexp_if_false)
for the same meaning as
     CondExpGt(
flagType(0), exp_if_trueexp_if_false)
Use of CondExp is deprecated, but continues to be supported.

4.4.4.k: Operation Sequence
This is an AD of Base 9.4.g.a: atomic operation and hence is part of the current AD of Base 9.4.g.b: operation sequence .

4.4.4.l: Example

4.4.4.m: Test
The file 4.4.4.1: CondExp.cpp contains an example and test of this function. It returns true if it succeeds and false otherwise.

4.4.4.n: Atan2
The following implementation of the AD 4.4.3.2: atan2 function is a more complex example of using conditional expressions:
 
template <class Base>
AD<Base> atan2 (const AD<Base> &y, const AD<Base> &x)
{	AD<Base> alpha;
	AD<Base> beta;
	AD<Base> theta;

	AD<Base> zero = 0;
	AD<Base> pi2  = 2. * atan(1.);
	AD<Base> pi   = 2. * pi2;

	AD<Base> ax = abs(x);
	AD<Base> ay = abs(y);

	// if( ax > ay )
	// 	theta = atan(ay / ax);
	// else	theta = pi2 - atan(ax / ay);
	alpha = atan(ay / ax);
	beta  = pi2 - atan(ax / ay);
	theta = CondExpGt(ax, ay, alpha, beta);         // use of CondExp

	// if( x <= 0 )
	// 	theta = pi - theta;
	theta = CondExpLe(x, zero, pi - theta, theta);  // use of CondExp
	
	// if( y <= 0 )
	// 	theta = - theta;
	theta = CondExpLe(y, zero, -theta, theta);      // use of CondExp

	return theta;
}

Input File: cppad/local/cond_exp.hpp
4.4.4.1: Conditional Expressions: Example and Test

4.4.4.1.a: Description
Use CondExp to compute  \[
     f(x) = \sum_{j=0}^{m-1} x_j \log( x_j )
\] 
and its derivative at various argument values ( where  x_j \geq 0 ) with out having to re-tape; i.e., using only one 5: ADFun object. Note that  x_j \log ( x_j ) \rightarrow 0  as  x_j \downarrow 0 and we need to handle the case  x_j = 0 in a special way to avoid multiplying zero by infinity.
 

# include <cppad/cppad.hpp>
# include <limits>

bool CondExp(void)
{	bool ok = true;

	using CppAD::isnan;
	using CppAD::AD;
	using CppAD::NearEqual;
	using CppAD::log; 
	using CppAD::abs;
	double eps  = 100. * std::numeric_limits<double>::epsilon();
	double fmax = std::numeric_limits<double>::max();

	// domain space vector
	size_t n = 5;
	CPPAD_TEST_VECTOR< AD<double> > X(n);
	size_t j;
	for(j = 0; j < n; j++)
		X[j] = 1.;

	// declare independent variables and start tape recording
	CppAD::Independent(X);

	AD<double> Sum  = 0.;
	AD<double> Zero = 0.;
	for(j = 0; j < n; j++)
	{	// if x_j > 0, add x_j * log( x_j ) to the sum
		Sum += CppAD::CondExpGt(X[j], Zero, X[j] * log(X[j]),    Zero);
	}

	// range space vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > Y(m);
	Y[0] = Sum;

	// create f: X -> Y and stop tape recording
	CppAD::ADFun<double> f(X, Y);

	// vectors for arguments to the function object f
	CPPAD_TEST_VECTOR<double> x(n);   // argument values
	CPPAD_TEST_VECTOR<double> y(m);   // function values 
	CPPAD_TEST_VECTOR<double> w(m);   // function weights 
	CPPAD_TEST_VECTOR<double> dw(n);  // derivative of weighted function

	// a case where x[j] > 0 for all j
	double check  = 0.;
	for(j = 0; j < n; j++)
	{	x[j]   = double(j + 1); 
		check += x[j] * log( x[j] );
	}

	// function value 
	y  = f.Forward(0, x);
	ok &= NearEqual(y[0], check, eps, eps);

	// compute derivative of y[0]
	w[0] = 1.;
	dw   = f.Reverse(1, w);
	for(j = 0; j < n; j++)
		ok &= NearEqual(dw[j], log(x[j]) + 1., eps, eps); 

	// a case where x[3] is equal to zero
	check -= x[3] * log( x[3] );
	x[3]   = 0.;

	// function value 
	y   = f.Forward(0, x);
	ok &= NearEqual(y[0], check, eps, eps);

	// check derivative of y[0]
	w[0] = 1.;
	dw   = f.Reverse(1, w);
	for(j = 0; j < n; j++)
	{	if( x[j] > 0 )
			ok &= NearEqual(dw[j], log(x[j]) + 1., eps, eps); 
		else
		{	// In this case computing dw[j] is computed using 
			//      log(x[j]) + x[j] / x[j] 
			// which has limit minus infinity but computes as nan.
			ok &= ( isnan( dw[j] ) || dw[j] <= -fmax );
		}
	}
	
	return ok;
}

Input File: example/cond_exp.cpp
4.4.5: Discrete AD Functions

4.4.5.a: Syntax
CPPAD_DISCRETE_FUNCTION(Basename)
v = name(u)
y = name(x)

4.4.5.b: Purpose
Record the evaluation of a discrete function as part of an AD<Base> 9.4.g.b: operation sequence . The value of a discrete function can depend on the 9.4.j.c: independent variables , but its derivative is identically zero. For example, suppose that the integer part of a 9.4.l: variable x is the index into an array of values.

4.4.5.c: Base
This is the 4.7: base type corresponding to the operations sequence; i.e., use of the name with arguments of type AD<Base> can be recorded in an operation sequence.

4.4.5.d: name
This is the name of the function (as it is used in the source code). The user must provide a version of name where the argument has type Base. CppAD uses this to create a version of name where the argument has type AD<Base>.

4.4.5.e: u
The argument u has prototype
     const 
Base &u
It is the value at which the user provided version of name is to be evaluated.

4.4.5.f: v
The result v has prototype
     
Base v
It is the return value for the user provided version of name.

4.4.5.g: x
The argument x has prototype
     const AD<
Base> &x
It is the value at which the CppAD provided version of name is to be evaluated.

4.4.5.h: y
The result y has prototype
     AD<
Basev
It is the return value for the CppAD provided version of name.

4.4.5.i: Create AD Version
The preprocessor macro invocation
     CPPAD_DISCRETE_FUNCTION(
Basename)
defines the AD<Base> version of name. This can be with in a namespace (not the CppAD namespace) but must be outside of any routine.

4.4.5.j: Operation Sequence
This is an AD of Base 9.4.g.a: atomic operation and hence is part of the current AD of Base 9.4.g.b: operation sequence .

4.4.5.k: Derivatives
During a zero order 5.6.1: Forward operation, an 5: ADFun object will compute the value of name using the user provided Base version of this routine. All the derivatives of name will be evaluated as zero.

4.4.5.l: Example
The file 4.4.5.1: TapeIndex.cpp contains an example and test that uses a discrete function to vary an array index during 5.6.1: Forward mode calculations. The file 4.4.5.2: interp_onetape.cpp contains an example and test that uses discrete functions to avoid retaping a calculation that requires interpolation. (The file 4.4.5.3: interp_retape.cpp shows how interpolation can be done with retaping.)

4.4.5.m: Deprecated
The preprocessor symbol CppADCreateDiscrete is defined to be the same as CPPAD_DISCRETE_FUNCTION but its use is deprecated.
Input File: cppad/local/discrete.hpp
4.4.5.1: Taping Array Index Operation: Example and Test
 
# include <cppad/cppad.hpp>

namespace {
	double Array(const double &index)
	{	static double array[] = {
			5.,
			4.,
			3.,
			2.,
			1.
		};
		static size_t number = sizeof(array) / sizeof(array[0]);
		if( index < 0. )
			return array[0];

		size_t i = static_cast<size_t>(index);
		if( i >= number )
			return array[number-1];

		return array[i];
	}
	// in empty namespace and outside any other routine
	CPPAD_DISCRETE_FUNCTION(double, Array)
}

bool TapeIndex(void)
{	bool ok = true;
	using CppAD::AD;

	// domain space vector
	size_t n = 2;
	CPPAD_TEST_VECTOR< AD<double> > X(n);
	X[0] = 2.;   // array index value
	X[1] = 3.;   // multiplier of array index value

	// declare independent variables and start tape recording
	CppAD::Independent(X);

	// range space vector
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > Y(m);
	Y[0] = X[1] * Array( X[0] );

	// create f: X -> Y and stop tape recording
	CppAD::ADFun<double> f(X, Y);

	// vectors for arguments to the function object f
	CPPAD_TEST_VECTOR<double> x(n);   // argument values
	CPPAD_TEST_VECTOR<double> y(m);   // function values 
	CPPAD_TEST_VECTOR<double> w(m);   // function weights 
	CPPAD_TEST_VECTOR<double> dw(n);  // derivative of weighted function

	// check function value
	x[0] = Value(X[0]);
	x[1] = Value(X[1]);
	y[0] = Value(Y[0]);
	ok  &= y[0] == x[1] * Array(x[0]);

	// evaluate f where x has different values
	x[0] = x[0] + 1.;  // new array index value
	x[1] = x[1] + 1.;  // new multiplier value
	y    = f.Forward(0, x);
	ok  &= y[0] == x[1] * Array(x[0]);

	// evaluate derivaitve of y[0] 
	w[0] = 1.;
	dw   = f.Reverse(1, w);
	ok   &= dw[0] == 0.;              // partial w.r.t array index
	ok   &= dw[1] == Array(x[0]);     // partial w.r.t multiplier

	return ok;
}

Input File: example/tape_index.cpp
4.4.5.2: Interpolation With Out Retaping: Example and Test

4.4.5.2.a: See Also
4.4.5.3: interp_retape.cpp

 
# include <cppad/cppad.hpp>
# include <cassert>
# include <cmath>

namespace {
	double ArgumentValue[] = {
		.0 ,
		.2 ,
		.4 ,
		.8 ,
		1.
	};
	double FunctionValue[] = {
		std::sin( ArgumentValue[0] ) ,
		std::sin( ArgumentValue[1] ) ,
		std::sin( ArgumentValue[2] ) ,
		std::sin( ArgumentValue[3] ) ,
		std::sin( ArgumentValue[4] )
	};
	size_t TableLength = 5;

	size_t Index(const double &x)
	{	// determine the index j such that x is between
		// ArgumentValue[j] and ArgumentValue[j+1] 
		static size_t j = 0;
		while ( x < ArgumentValue[j] && j > 0 )
			j--;
		while ( x > ArgumentValue[j+1] && j < TableLength - 2)
			j++;
		// assert conditions that must be true given logic above
		assert( j >= 0 && j < TableLength - 1 );
		return j;
	}

	double Argument(const double &x)
	{	size_t j = Index(x);
		return ArgumentValue[j];
	}
	double Function(const double &x)
	{	size_t j = Index(x);
		return FunctionValue[j];
	}

	double Slope(const double &x)
	{	size_t j  = Index(x);
		double dx = ArgumentValue[j+1] - ArgumentValue[j];
		double dy = FunctionValue[j+1] - FunctionValue[j];
		return dy / dx;
	}
	CPPAD_DISCRETE_FUNCTION(double, Argument)
	CPPAD_DISCRETE_FUNCTION(double, Function)
	CPPAD_DISCRETE_FUNCTION(double, Slope)
}


bool interp_onetape(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t n = 1;
	CPPAD_TEST_VECTOR< AD<double> > X(n);
	X[0] = .4 * ArgumentValue[1] + .6 * ArgumentValue[2];

	// declare independent variables and start tape recording
	CppAD::Independent(X);

	// evaluate piecewise linear interpolant at X[0]
	AD<double> A = Argument(X[0]); 
	AD<double> F = Function(X[0]);
	AD<double> S = Slope(X[0]);
	AD<double> I = F + (X[0] - A) * S;

	// range space vector
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > Y(m);
	Y[0] = I;

	// create f: X -> Y and stop tape recording
	CppAD::ADFun<double> f(X, Y);

	// vectors for arguments to the function object f
	CPPAD_TEST_VECTOR<double> x(n);   // argument values
	CPPAD_TEST_VECTOR<double> y(m);   // function values 
	CPPAD_TEST_VECTOR<double> dx(n);  // differentials in x space
	CPPAD_TEST_VECTOR<double> dy(m);  // differentials in y space

	// to check function value we use the fact that X[0] is between 
	// ArgumentValue[1] and ArgumentValue[2]
	x[0]          = Value(X[0]);
	double delta  = ArgumentValue[2] - ArgumentValue[1];
	double check  = FunctionValue[2] * (x[0] - ArgumentValue[1]) / delta
	              + FunctionValue[1] * (ArgumentValue[2] - x[0]) / delta; 
	ok  &= NearEqual(Y[0], check, 1e-10, 1e-10);

	// evaluate f where x has different value
	x[0]   = .7 * ArgumentValue[2] + .3 * ArgumentValue[3];
	y      = f.Forward(0, x);

	// check function value 
	delta  = ArgumentValue[3] - ArgumentValue[2];
	check  = FunctionValue[3] * (x[0] - ArgumentValue[2]) / delta
	              + FunctionValue[2] * (ArgumentValue[3] - x[0]) / delta; 
	ok  &= NearEqual(y[0], check, 1e-10, 1e-10);

	// evaluate partials w.r.t. x[0] 
	dx[0] = 1.;
	dy    = f.Forward(1, dx);

	// check that the derivative is the slope
	check = (FunctionValue[3] - FunctionValue[2])
	      / (ArgumentValue[3] - ArgumentValue[2]);
	ok   &= NearEqual(dy[0], check, 1e-10, 1e-10);

	return ok;
}

Input File: example/interp_onetape.cpp
4.4.5.3: Interpolation With Retaping: Example and Test

4.4.5.3.a: See Also
4.4.5.2: interp_onetape.cpp

 
# include <cppad/cppad.hpp>
# include <cassert>
# include <cmath>

namespace {
	double ArgumentValue[] = {
		.0 ,
		.2 ,
		.4 ,
		.8 ,
		1.
	};
	double FunctionValue[] = {
		std::sin( ArgumentValue[0] ) ,
		std::sin( ArgumentValue[1] ) ,
		std::sin( ArgumentValue[2] ) ,
		std::sin( ArgumentValue[3] ) ,
		std::sin( ArgumentValue[4] )
	};
	size_t TableLength = 5;

	size_t Index(const CppAD::AD<double> &x)
	{	// determine the index j such that x is between
		// ArgumentValue[j] and ArgumentValue[j+1] 
		static size_t j = 0;
		while ( x < ArgumentValue[j] && j > 0 )
			j--;
		while ( x > ArgumentValue[j+1] && j < TableLength - 2)
			j++;
		// assert conditions that must be true given logic above
		assert( j >= 0 && j < TableLength - 1 );
		return j;
	}
	double Argument(const CppAD::AD<double> &x)
	{	size_t j = Index(x);
		return ArgumentValue[j];
	}
	double Function(const CppAD::AD<double> &x)
	{	size_t j = Index(x);
		return FunctionValue[j];
	}
	double Slope(const CppAD::AD<double> &x)
	{	size_t j  = Index(x);
		double dx = ArgumentValue[j+1] - ArgumentValue[j];
		double dy = FunctionValue[j+1] - FunctionValue[j];
		return dy / dx;
	}
}

bool interp_retape(void)
{	bool ok = true;

	using CppAD::AD;
	using CppAD::NearEqual;

	// domain space vector
	size_t n = 1;
	CPPAD_TEST_VECTOR< AD<double> > X(n);

	// loop over argument values
	size_t k;
	for(k = 0; k < TableLength - 1; k++)
	{
		X[0] = .4 * ArgumentValue[k] + .6 * ArgumentValue[k+1];

		// declare independent variables and start tape recording
		// (use a different tape for each argument value)
		CppAD::Independent(X);

		// evaluate piecewise linear interpolant at X[0]
		AD<double> A = Argument(X[0]); 
		AD<double> F = Function(X[0]);
		AD<double> S = Slope(X[0]);
		AD<double> I = F + (X[0] - A) * S;

		// range space vector
		size_t m = 1;
		CPPAD_TEST_VECTOR< AD<double> > Y(m);
		Y[0] = I;

		// create f: X -> Y and stop tape recording
		CppAD::ADFun<double> f(X, Y);

		// vectors for arguments to the function object f
		CPPAD_TEST_VECTOR<double> x(n);   // argument values
		CPPAD_TEST_VECTOR<double> y(m);   // function values 
		CPPAD_TEST_VECTOR<double> dx(n);  // differentials in x space
		CPPAD_TEST_VECTOR<double> dy(m);  // differentials in y space

		// to check function value we use the fact that X[0] is between
		// ArgumentValue[k] and ArgumentValue[k+1]
		double delta, check;
		x[0]   = Value(X[0]);
		delta  = ArgumentValue[k+1] - ArgumentValue[k];
		check  = FunctionValue[k+1] * (x[0]-ArgumentValue[k]) / delta
	               + FunctionValue[k] * (ArgumentValue[k+1]-x[0]) / delta; 
		ok    &= NearEqual(Y[0], check, 1e-10, 1e-10);

		// evaluate partials w.r.t. x[0] 
		dx[0] = 1.;
		dy    = f.Forward(1, dx);

		// check that the derivative is the slope
		check = (FunctionValue[k+1] - FunctionValue[k])
		      / (ArgumentValue[k+1] - ArgumentValue[k]);
		ok   &= NearEqual(dy[0], check, 1e-10, 1e-10);
	}
	return ok;
}

Input File: example/interp_retape.cpp
4.5: Bool Valued Operations and Functions with AD Arguments
4.5.1: Compare AD Binary Comparison Operators
4.5.2: NearEqualExt Compare AD and Base Objects for Nearly Equal
4.5.3: BoolFun AD Boolean Functions
4.5.4: ParVar Is an AD Object a Parameter or Variable
4.5.5: EqualOpSeq Check if Equal and Correspond to Same Operation Sequence

Input File: cppad/local/bool_valued.hpp
4.5.1: AD Binary Comparison Operators

4.5.1.a: Syntax
b = x Op y

4.5.1.b: Purpose
Compares two operands where one of the operands is an AD<Base> object. The comparison has the same interpretation as for the Base type.

4.5.1.c: Op
The operator Op is one of the following:
Op   Meaning
< is x less than y
<= is x less than or equal y
> is x greater than y
>= is x greater than or equal y
== is x equal to y
!= is x not equal to y

4.5.1.d: x
The operand x has prototype
     const 
Type &x
where Type is AD<Base>, Base, or int.

4.5.1.e: y
The operand y has prototype
     const 
Type &y
where Type is AD<Base>, Base, or int.

4.5.1.f: b
The result b has type
     bool 
b

4.5.1.g: Operation Sequence
The result of this operation is a bool value (not an 9.4.b: AD of Base object). Thus it will not be recorded as part of an AD of Base 9.4.g.b: operation sequence .

For example, suppose x and y are AD<Base> objects, the tape corresponding to AD<Base> is recording, b is true, and the subsequent code is
     if( 
b )
          
y = cos(x);
     else 
y = sin(x); 
only the assignment y = cos(x) is recorded on the tape (if x is a 9.4.h: parameter , nothing is recorded). The 5.6.1.5: CompareChange function can yield some information about changes in comparison operation results. You can use 4.4.4: CondExp to obtain comparison operations that depends on the 9.4.j.c: independent variable values with out re-taping the AD sequence of operations.

4.5.1.h: Assumptions
If one of the Op operators listed above is used with an AD<Base> object, it is assumed that the same operator is supported by the base type Base.

4.5.1.i: Example
The file 4.5.1.1: Compare.cpp contains an example and test of these operations. It returns true if it succeeds and false otherwise.
Input File: cppad/local/compare.hpp
4.5.1.1: AD Binary Comparison Operators: Example and Test
 
# include <cppad/cppad.hpp>

bool Compare(void)
{	bool ok = true;
	using CppAD::AD;
	using CppAD::NearEqual;

	// declare independent variables and start tape recording
	size_t n  = 2;
	double x0 = 0.5;
	double x1 = 1.5;
	CPPAD_TEST_VECTOR< AD<double> > x(n);
	x[0]      = x0; 
	x[1]      = x1; 
	CppAD::Independent(x);

	// some binary comparision operations
	AD<double> p;
	if( x[0] < x[1] )
		p = x[0];   // values in x choose this case
	else	p = x[1];
	if( x[0] <= x[1] )
		p *= x[0];  // values in x choose this case
	else	p *= x[1];
	if( x[0] >  x[1] )
		p *= x[0]; 
	else	p *= x[1];  // values in x choose this case
	if( x[0] >= x[1] )
		p *= x[0]; 
	else	p *= x[1];  // values in x choose this case
	if( x[0] == x[1] )
		p *= x[0]; 
	else	p *= x[1];  // values in x choose this case
	if( x[0] != x[1] )
		p *= x[0];  // values in x choose this case
	else	p *= x[1]; 

	// dependent variable vector 
	size_t m = 1;
	CPPAD_TEST_VECTOR< AD<double> > y(m);
	y[0] = p;

	// create f: x -> y and stop tape recording
	CppAD::ADFun<double> f(x, y); 

	// check value 
	ok &= NearEqual(y[0] , x0*x0*x1*x1*x1*x0,  1e-10 , 1e-10);

	// forward computation of partials w.r.t. x[0]
	CPPAD_TEST_VECTOR<double> dx(n);
	CPPAD_TEST_VECTOR<double> dy(m);
	dx[0] = 1.;
	dx[1] = 0.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], 3.*x0*x0*x1*x1*x1, 1e-10, 1e-10);

	// forward computation of partials w.r.t. x[1]
	dx[0] = 0.;
	dx[1] = 1.;
	dy    = f.Forward(1, dx);
	ok   &= NearEqual(dy[0], 3.*x0*x0*x1*x1*x0, 1e-10, 1e-10);

	// reverse computation of derivative of y[0]
	CPPAD_TEST_VECTOR<double>  w(m);
	CPPAD_TEST_VECTOR<double> dw(n);
	w[0]  = 1.;
	dw    = f.Reverse(1, w);
	ok   &= NearEqual(dw[0], 3.*x0*x0*x1*x1*x1, 1e-10, 1e-10);
	ok   &= NearEqual(dw[1], 3.*x0*x0*x1*x1*x0, 1e-10, 1e-10);

	return ok;
}

Input File: example/compare.cpp
4.5.2: Compare AD and Base Objects for Nearly Equal

4.5.2.a: Syntax
b = NearEqual(xyra)

4.5.2.b: Purpose
The routine 6.2: NearEqual determines if two objects of the same type are nearly. This routine is extended to the case where one object can have type Type while the other can have type AD<Type> or AD< std::complex<Type> >.

4.5.2.c: x
The arguments x has one of the following possible prototypes:
     const 
Type                     &x
     const AD<
Type>                 &x
     const AD< std::complex<
Type> > &x

4.5.2.d: y
The arguments y has one of the following possible prototypes:
     const 
Type                     &y
     const AD<
Type>                 &y
     const AD< std::complex<
Type> > &x

4.5.2.e: r
The relative error criteria r has prototype
     const 
Type &r
It must be greater than or equal to zero. The relative error condition is defined as:  \[
     \frac{ | x - y | } { |x| + |y| } \leq r
\] 


4.5.2.f: a
The absolute error criteria a has prototype
     const 
Type &a
It must be greater than or equal to zero. The absolute error condition is defined as:  \[
     | x - y | \leq a
\] 


4.5.2.g: b
The return value b has prototype
     bool 
b
If either x or y is infinite or not a number, the return value is false. Otherwise, if either the relative or absolute error condition (defined above) is satisfied, the return value is true. Otherwise, the return value is false.

4.5.2.h: Type
The type Type must be a 6.5: NumericType . The routine 6.6: CheckNumericType will generate an error message if this is not the case. If a and b have type Type, the following operation must be defined
Operation Description
a <= b less that or equal operator (returns a bool object)

4.5.2.i: Operation Sequence
The result of this operation is not an 9.4.b: AD of Base object. Thus it will not be recorded as part of an AD of Base 9.4.g.b: operation sequence .

4.5.2.j: Example
The file 4.5.2.1: NearEqualExt.cpp contains an example and test of this extension of 6.2: NearEqual . It return true if it succeeds and false otherwise.
Input File: cppad/local/near_equal_ext.hpp
4.5.2.1: Compare AD with Base Objects: Example and Test
 

# include <cppad/cppad.hpp>
# include <complex>

bool NearEqualExt(void)
{	bool ok = true;
	using