CppAD: A C++ Algorithmic Differentiation Package 20110419
add_eq.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_ADD_EQ_INCLUDED
00003 # define CPPAD_ADD_EQ_INCLUDED
00004 
00005 /* --------------------------------------------------------------------------
00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-11 Bradley M. Bell
00007 
00008 CppAD is distributed under multiple licenses. This distribution is under
00009 the terms of the 
00010                     Common 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>& AD<Base>::operator += (const AD<Base> &right)
00021 {       ADTape<Base> *tape = AD<Base>::tape_ptr();
00022         size_t tape_id = 0;
00023         if( tape != CPPAD_NULL )
00024                 tape_id = tape->id_;
00025 
00026         // id_ setting for parameters cannot match 0
00027         bool var_left  = id_       == tape_id;
00028         bool var_right = right.id_ == tape_id;
00029         CPPAD_ASSERT_KNOWN(
00030                 Parameter(*this) || var_left ,
00031                 "+=: left operand is a variable for a different thread"
00032         );
00033         CPPAD_ASSERT_KNOWN(
00034                 Parameter(right) || var_right ,
00035                 "+=: right operand is a variable for a different thread"
00036         );
00037         Base left;
00038         left    = value_;
00039         value_ += right.value_;
00040 
00041         if( var_left )
00042         {       if( var_right )
00043                 {       // this = variable + variable
00044                         CPPAD_ASSERT_UNKNOWN( NumRes(AddvvOp) == 1 );
00045                         CPPAD_ASSERT_UNKNOWN( NumArg(AddvvOp) == 2 );
00046 
00047                         // put operand addresses in tape
00048                         tape->Rec_.PutArg(taddr_, right.taddr_);
00049                         // put operator in the tape
00050                         taddr_ = tape->Rec_.PutOp(AddvvOp);
00051                         // make this a variable
00052                         CPPAD_ASSERT_UNKNOWN( id_ == tape_id );
00053                 }
00054                 else if( ! IdenticalZero( right.value_ ) )
00055                 {       // this = variable  + parameter
00056                         //      = parameter + variable
00057                         CPPAD_ASSERT_UNKNOWN( NumRes(AddpvOp) == 1 );
00058                         CPPAD_ASSERT_UNKNOWN( NumArg(AddpvOp) == 2 );
00059 
00060                         // put operand addresses in tape
00061                         size_t p = tape->Rec_.PutPar(right.value_);
00062                         tape->Rec_.PutArg(p, taddr_);
00063                         // put operator in the tape
00064                         taddr_ = tape->Rec_.PutOp(AddpvOp);
00065                         // make this a variable
00066                         CPPAD_ASSERT_UNKNOWN( id_ == tape_id );
00067                 }
00068         }
00069         else if( var_right  )
00070         {       if( IdenticalZero(left) )
00071                 {       // this = 0 + right
00072                         make_variable(right.id_, right.taddr_);
00073                 }
00074                 else
00075                 {       // this = parameter + variable
00076                         CPPAD_ASSERT_UNKNOWN( NumRes(AddpvOp) == 1 );
00077                         CPPAD_ASSERT_UNKNOWN( NumArg(AddpvOp) == 2 );
00078 
00079                         // put operand addresses in tape
00080                         size_t p = tape->Rec_.PutPar(left);
00081                         tape->Rec_.PutArg(p, right.taddr_);
00082                         // put operator in the tape
00083                         taddr_ = tape->Rec_.PutOp(AddpvOp);
00084                         // make this a variable
00085                         id_ = tape_id;
00086                 }
00087         }
00088         return *this;
00089 }
00090 
00091 CPPAD_FOLD_ASSIGNMENT_OPERATOR(+=)
00092 
00093 } // END CppAD namespace
00094 
00095 # endif