CppAD: A C++ Algorithmic Differentiation Package  20130918
div.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_DIV_INCLUDED
00003 # define CPPAD_DIV_INCLUDED
00004 
00005 /* --------------------------------------------------------------------------
00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-13 Bradley M. Bell
00007 
00008 CppAD is distributed under multiple licenses. This distribution is under
00009 the terms of the 
00010                     Eclipse Public License Version 1.0.
00011 
00012 A copy of this license is included in the COPYING file of this distribution.
00013 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
00014 -------------------------------------------------------------------------- */
00015 
00016 //  BEGIN CppAD namespace
00017 namespace CppAD {
00018 
00019 template <class Base>
00020 AD<Base> operator / (const AD<Base> &left , const AD<Base> &right)
00021 {
00022      // compute the Base part
00023      AD<Base> result;
00024      result.value_  = left.value_ / right.value_;
00025      CPPAD_ASSERT_UNKNOWN( Parameter(result) );
00026 
00027      // check if there is a recording in progress
00028      ADTape<Base>* tape = AD<Base>::tape_ptr();
00029      if( tape == CPPAD_NULL )
00030           return result;
00031      tape_id_t tape_id = tape->id_;
00032 
00033      // tape_id cannot match the default value for tape_id_; i.e., 0
00034      CPPAD_ASSERT_UNKNOWN( tape_id > 0 );
00035      bool var_left  = left.tape_id_  == tape_id;
00036      bool var_right = right.tape_id_ == tape_id;
00037 
00038      if( var_left )
00039      {    if( var_right )
00040           {    // result = variable / variable
00041                CPPAD_ASSERT_KNOWN(
00042                     left.tape_id_ == right.tape_id_,
00043                     "Dividing AD objects that are"
00044                     " variables on different tapes."
00045                );
00046                CPPAD_ASSERT_UNKNOWN( NumRes(DivvvOp) == 1 );
00047                CPPAD_ASSERT_UNKNOWN( NumArg(DivvvOp) == 2 );
00048 
00049                // put operand addresses in tape
00050                tape->Rec_.PutArg(left.taddr_, right.taddr_);
00051                // put operator in the tape
00052                result.taddr_ = tape->Rec_.PutOp(DivvvOp);
00053                // make result a variable
00054                result.tape_id_ = tape_id;
00055           }
00056           else if( IdenticalOne(right.value_) )
00057           {    // result = variable / 1
00058                result.make_variable(left.tape_id_, left.taddr_);
00059           }
00060           else
00061           {    // result = variable / parameter
00062                CPPAD_ASSERT_UNKNOWN( NumRes(DivvpOp) == 1 );
00063                CPPAD_ASSERT_UNKNOWN( NumArg(DivvpOp) == 2 );
00064 
00065                // put operand addresses in tape
00066                addr_t p = tape->Rec_.PutPar(right.value_);
00067                tape->Rec_.PutArg(left.taddr_, p);
00068                // put operator in the tape
00069                result.taddr_ = tape->Rec_.PutOp(DivvpOp);
00070                // make result a variable
00071                result.tape_id_ = tape_id;
00072           }
00073      }
00074      else if( var_right )
00075      {    if( IdenticalZero(left.value_) )
00076           {    // result = 0 / variable
00077           }
00078           else
00079           {    // result = parameter / variable
00080                CPPAD_ASSERT_UNKNOWN( NumRes(DivpvOp) == 1 );
00081                CPPAD_ASSERT_UNKNOWN( NumArg(DivpvOp) == 2 );
00082 
00083                // put operand addresses in tape
00084                addr_t p = tape->Rec_.PutPar(left.value_);
00085                tape->Rec_.PutArg(p, right.taddr_);
00086                // put operator in the tape
00087                result.taddr_ = tape->Rec_.PutOp(DivpvOp);
00088                // make result a variable
00089                result.tape_id_ = tape_id;
00090           }
00091      }
00092      return result;
00093 }
00094 
00095 // convert other cases into the case above
00096 CPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(/)
00097 
00098 
00099 } // END CppAD namespace
00100 
00101 # endif 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines