Example AD<Base> Where Base Constructor Allocates Memory
Keywords: example ad<base> where base constructor allocates memory purpose include file computed assignment macro binary operator boolean class definition condexpop condexprel equalopseq identical output integer azmul ordered unary standard math erf asinh acosh atanh expm1 log1p sign pow numeric_limits

| Prev | Next |  |  |  |  |  | base_alloc.hpp |

Example AD<Base> Where Base Constructor Allocates Memory
Purpose
Demonstrate use of `AD<Base>` where memory is allocated for each element of the type `Base` . In addition, this is a complete example where all the required Base type operations are defined (as apposed to other examples where some of the operations for the Base type are already defined).
Include File
This file uses some of the definitions in base_require and thread_alloc . `

    # include <cppad/base_require.hpp>
    # include <cppad/utility/thread_alloc.hpp>

`
Computed Assignment Macro
This macro is used for the `base_alloc` computed assignment operators; to be specific, used with `op` equal to `+=`, `-=`, `*=`, `/=`. `

    # define BASE_ALLOC_ASSIGN_OPERATOR(op) \
         void operator op (const base_alloc& x) \
         {    *ptrdbl_ op *x.ptrdbl_; }

`
Binary Operator Macro
This macro is used for the `base_alloc` binary operators (as member functions); to be specific, used with `op` equal to `+`, `-`, `*`, `/`. `

    # define BASE_ALLOC_BINARY_OPERATOR(op) const \
         base_alloc operator op (const base_alloc& x) const \
         {    base_alloc result; \
              double   dbl = *ptrdbl_; \
              double x_dbl = *x.ptrdbl_; \
              *result.ptrdbl_ = dbl op x_dbl; \
              return result; \
         }

`
Boolean Operator Macro
This macro can be used for the `base_alloc` binary operators that have a `bool` result; to be specific, used with `op` equal to `==`, `!=`, `<`, `<=`, `>=`, and `>`, `

    # define BASE_ALLOC_BOOL_OPERATOR(op) const \
         bool operator op (const base_alloc& x) const \
         {    double   dbl = *ptrdbl_; \
              double x_dbl = *x.ptrdbl_; \
              return dbl op x_dbl; \
         }

`
Class Definition
The following example class defines the necessary base_member functions. It is made more complicated by storing a pointer to a `double` instead of the `double` value itself. `

    class base_alloc {
    public:
         double* ptrdbl_;

         base_alloc(void)
         {    size_t cap;
              void* v  = CppAD::thread_alloc::get_memory(sizeof(double), cap);
              ptrdbl_  = static_cast<double*>(v);
         }
         base_alloc(double dbl)
         {    size_t cap;
              void *v  = CppAD::thread_alloc::get_memory(sizeof(double), cap);
              ptrdbl_  = static_cast<double*>(v);
              *ptrdbl_ = dbl;
         }
         base_alloc(const base_alloc& x)
         {    size_t cap;
              void *v  = CppAD::thread_alloc::get_memory(sizeof(double), cap);
              ptrdbl_  = static_cast<double*>(v);
              *ptrdbl_ = *x.ptrdbl_;
         }
         ~base_alloc(void)
         {    void* v  = static_cast<void*>(ptrdbl_);
              CppAD::thread_alloc::return_memory(v);
         }
         base_alloc operator-(void) const
         {    base_alloc result;
              *result.ptrdbl_ = - *ptrdbl_;
              return result;
         }
         base_alloc operator+(void) const
         {    return *this; }
         void operator=(const base_alloc& x)
         {    *ptrdbl_ = *x.ptrdbl_; }
         BASE_ALLOC_ASSIGN_OPERATOR(+=)
         BASE_ALLOC_ASSIGN_OPERATOR(-=)
         BASE_ALLOC_ASSIGN_OPERATOR(*=)
         BASE_ALLOC_ASSIGN_OPERATOR(/=)
         BASE_ALLOC_BINARY_OPERATOR(+)
         BASE_ALLOC_BINARY_OPERATOR(-)
         BASE_ALLOC_BINARY_OPERATOR(*)
         BASE_ALLOC_BINARY_OPERATOR(/)
         BASE_ALLOC_BOOL_OPERATOR(==)
         BASE_ALLOC_BOOL_OPERATOR(!=)
         // The <= operator is not necessary for the base type requirements
         // (needed so we can use NearEqual with base_alloc arguments).
         BASE_ALLOC_BOOL_OPERATOR(<=)
    };

`
CondExpOp
The type `base_alloc` does not use CondExp operations. Hence its `CondExpOp` function is defined by `

    namespace CppAD {
         inline base_alloc CondExpOp(
              enum CompareOp     cop          ,
              const base_alloc&       left         ,
              const base_alloc&       right        ,
              const base_alloc&       exp_if_true  ,
              const base_alloc&       exp_if_false )
         {    // not used
              assert(false);

              // to void compiler error
              return base_alloc();
         }
    }

`
CondExpRel
The CPPAD_COND_EXP_REL macro invocation `

    namespace CppAD {
         CPPAD_COND_EXP_REL(base_alloc)
    }

` uses `CondExpOp` above to define `CondExpRel` for `base_alloc` arguments and `Rel` equal to `Lt`, `Le`, `Eq`, `Ge`, and `Gt`.
EqualOpSeq
The type `base_alloc` is simple (in this respect) and so we define `

    namespace CppAD {
         inline bool EqualOpSeq(const base_alloc& x, const base_alloc& y)
         {    return *x.ptrdbl_ == *y.ptrdbl_; }
    }

`
Identical
The type `base_alloc` is simple (in this respect) and so we define `

    namespace CppAD {
         inline bool IdenticalPar(const base_alloc& x)
         {    return true; }
         inline bool IdenticalZero(const base_alloc& x)
         {    return (*x.ptrdbl_ == 0.0); }
         inline bool IdenticalOne(const base_alloc& x)
         {    return (*x.ptrdbl_ == 1.0); }
         inline bool IdenticalEqualPar(const base_alloc& x, const base_alloc& y)
         {    return (*x.ptrdbl_ == *y.ptrdbl_); }
    }

`
Output Operator `

    namespace CppAD {
         std::ostream& operator << (std::ostream &os, const base_alloc& x)
         {    os << *x.ptrdbl_;
              return os;
         }
    }

`
Integer `

    namespace CppAD {
         inline int Integer(const base_alloc& x)
         {    return static_cast<int>(*x.ptrdbl_); }
    }

`
azmul `

    namespace CppAD {
         CPPAD_AZMUL( base_alloc )
    }

`
Ordered
The `base_alloc` type supports ordered comparisons `

    namespace CppAD {
         inline bool GreaterThanZero(const base_alloc& x)
         {    return *x.ptrdbl_ > 0.0; }
         inline bool GreaterThanOrZero(const base_alloc& x)
         {    return *x.ptrdbl_ >= 0.0; }
         inline bool LessThanZero(const base_alloc& x)
         {    return *x.ptrdbl_ < 0.0; }
         inline bool LessThanOrZero(const base_alloc& x)
         {    return *x.ptrdbl_ <= 0.f; }
         inline bool abs_geq(const base_alloc& x, const base_alloc& y)
         {    return std::fabs(*x.ptrdbl_) >= std::fabs(*y.ptrdbl_); }
    }

`
Unary Standard Math
The macro CPPAD_STANDARD_MATH_UNARY would not work with the type `base_alloc` so we define a special macro for this type: `

    # define BASE_ALLOC_STD_MATH(fun) \
         inline base_alloc fun (const base_alloc& x) \
         { return   std::fun(*x.ptrdbl_); }

` The following invocations of the macro above define the unary standard math functions (except for `abs`): `

    namespace CppAD {
         BASE_ALLOC_STD_MATH(acos)
         BASE_ALLOC_STD_MATH(asin)
         BASE_ALLOC_STD_MATH(atan)
         BASE_ALLOC_STD_MATH(cos)
         BASE_ALLOC_STD_MATH(cosh)
         BASE_ALLOC_STD_MATH(exp)
         BASE_ALLOC_STD_MATH(log)
         BASE_ALLOC_STD_MATH(log10)
         BASE_ALLOC_STD_MATH(sin)
         BASE_ALLOC_STD_MATH(sinh)
         BASE_ALLOC_STD_MATH(sqrt)
         BASE_ALLOC_STD_MATH(tan)
         BASE_ALLOC_STD_MATH(tanh)
    }

` The absolute value function is special because its `std` name is `fabs` `

    namespace CppAD {
         inline base_alloc abs(const base_alloc& x)
         {    return std::fabs(*x.ptrdbl_); }
    }

`
erf, asinh, acosh, atanh, expm1, log1p
The following defines the erf, asinh, acosh, atanh, expm1, log1p functions required by `AD<base_alloc>`: `

    # if CPPAD_USE_CPLUSPLUS_2011
         BASE_ALLOC_STD_MATH(erf)
         BASE_ALLOC_STD_MATH(asinh)
         BASE_ALLOC_STD_MATH(acosh)
         BASE_ALLOC_STD_MATH(atanh)
         BASE_ALLOC_STD_MATH(expm1)
         BASE_ALLOC_STD_MATH(log1p)
    # endif

`
sign
The following defines the `CppAD::sign` function that is required to use `AD<base_alloc>`: `

    namespace CppAD {
         inline base_alloc sign(const base_alloc& x)
         {    if( *x.ptrdbl_ > 0.0 )
                   return 1.0;
              if( *x.ptrdbl_ == 0.0 )
                   return 0.0;
              return -1.0;
         }
    }

`
pow
The following defines a `CppAD::pow` function that is required to use `AD<base_alloc>`: `

    namespace CppAD {
         inline base_alloc pow(const base_alloc& x, const base_alloc& y)
         { return std::pow(*x.ptrdbl_, *y.ptrdbl_); }
    }

`
numeric_limits
The following defines the CppAD numeric_limits for the type `base_alloc`: `

    namespace CppAD {
         CPPAD_NUMERIC_LIMITS(double, base_alloc)
    }

`

Input File: example/base_alloc.hpp