CppAD: A C++ Algorithmic Differentiation Package 20110419
sub_eq.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_SUB_EQ_INCLUDED
00003 # define CPPAD_SUB_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 
00038         Base left;
00039         left    = value_;
00040         value_ -= right.value_;
00041 
00042         if( var_left )
00043         {       if( var_right )
00044                 {       // this = variable - variable
00045                         CPPAD_ASSERT_UNKNOWN( NumRes(SubvvOp) == 1 );
00046                         CPPAD_ASSERT_UNKNOWN( NumArg(SubvvOp) == 2 );
00047 
00048                         // put operand addresses in tape
00049                         tape->Rec_.PutArg(taddr_, right.taddr_);
00050                         // put operator in the tape
00051                         taddr_ = tape->Rec_.PutOp(SubvvOp);
00052                         // make this a variable
00053                         CPPAD_ASSERT_UNKNOWN( id_ == tape_id );
00054                 }
00055                 else if( IdenticalZero( right.value_ ) )
00056                 {       // this = variable - 0
00057                 }
00058                 else
00059                 {       // this = variable - parameter
00060                         CPPAD_ASSERT_UNKNOWN( NumRes(SubvpOp) == 1 );
00061                         CPPAD_ASSERT_UNKNOWN( NumArg(SubvpOp) == 2 );
00062 
00063                         // put operand addresses in tape
00064                         size_t p = tape->Rec_.PutPar(right.value_);
00065                         tape->Rec_.PutArg(taddr_, p);
00066                         // put operator in the tape
00067                         taddr_ = tape->Rec_.PutOp(SubvpOp);
00068                         // make this a variable
00069                         CPPAD_ASSERT_UNKNOWN( id_ == tape_id );
00070                 }
00071         }
00072         else if( var_right  )
00073         {       // this = parameter - variable
00074                 CPPAD_ASSERT_UNKNOWN( NumRes(SubpvOp) == 1 );
00075                 CPPAD_ASSERT_UNKNOWN( NumArg(SubpvOp) == 2 );
00076 
00077                 // put operand addresses in tape
00078                 size_t p = tape->Rec_.PutPar(left);
00079                 tape->Rec_.PutArg(p, right.taddr_);
00080                 // put operator in the tape
00081                 taddr_ = tape->Rec_.PutOp(SubpvOp);
00082                 // make this a variable
00083                 id_ = tape_id;
00084         }
00085         return *this;
00086 }
00087 
00088 CPPAD_FOLD_ASSIGNMENT_OPERATOR(-=)
00089 
00090 } // END CppAD namespace
00091 
00092 # endif