CppAD: A C++ Algorithmic Differentiation Package
20130102
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_MUL_EQ_INCLUDED 00003 # define CPPAD_MUL_EQ_INCLUDED 00004 00005 /* -------------------------------------------------------------------------- 00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-12 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>& AD<Base>::operator *= (const AD<Base> &right) 00021 { 00022 // compute the Base part 00023 Base left; 00024 left = value_; 00025 value_ *= right.value_; 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 *this; 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 = tape_id_ == tape_id; 00036 bool var_right = right.tape_id_ == tape_id; 00037 00038 if( var_left ) 00039 { if( var_right ) 00040 { // this = variable * variable 00041 CPPAD_ASSERT_UNKNOWN( NumRes(MulvvOp) == 1 ); 00042 CPPAD_ASSERT_UNKNOWN( NumArg(MulvvOp) == 2 ); 00043 00044 // put operand addresses in tape 00045 tape->Rec_.PutArg(taddr_, right.taddr_); 00046 // put operator in the tape 00047 taddr_ = tape->Rec_.PutOp(MulvvOp); 00048 // make this a variable 00049 CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id ); 00050 } 00051 else if( IdenticalOne( right.value_ ) ) 00052 { // this = variable * 1 00053 } 00054 else if( IdenticalZero( right.value_ ) ) 00055 { // this = variable * 0 00056 make_parameter(); 00057 } 00058 else 00059 { // this = variable * parameter 00060 // = parameter * variable 00061 CPPAD_ASSERT_UNKNOWN( NumRes(MulpvOp) == 1 ); 00062 CPPAD_ASSERT_UNKNOWN( NumArg(MulpvOp) == 2 ); 00063 00064 // put operand addresses in tape 00065 addr_t p = tape->Rec_.PutPar(right.value_); 00066 tape->Rec_.PutArg(p, taddr_); 00067 // put operator in the tape 00068 taddr_ = tape->Rec_.PutOp(MulpvOp); 00069 // make this a variable 00070 CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id ); 00071 } 00072 } 00073 else if( var_right ) 00074 { if( IdenticalZero(left) ) 00075 { // this = 0 * right 00076 } 00077 else if( IdenticalOne(left) ) 00078 { // this = 1 * right 00079 make_variable(right.tape_id_, right.taddr_); 00080 } 00081 else 00082 { // this = parameter * variable 00083 CPPAD_ASSERT_UNKNOWN( NumRes(MulpvOp) == 1 ); 00084 CPPAD_ASSERT_UNKNOWN( NumArg(MulpvOp) == 2 ); 00085 00086 // put operand addresses in tape 00087 addr_t p = tape->Rec_.PutPar(left); 00088 tape->Rec_.PutArg(p, right.taddr_); 00089 // put operator in the tape 00090 taddr_ = tape->Rec_.PutOp(MulpvOp); 00091 // make this a variable 00092 tape_id_ = tape_id; 00093 } 00094 } 00095 return *this; 00096 } 00097 00098 CPPAD_FOLD_ASSIGNMENT_OPERATOR(*=) 00099 00100 } // END CppAD namespace 00101 00102 # endif