1 // $Id$ 2 # ifndef CPPAD_CORE_DIV_EQ_HPP 3 # define CPPAD_CORE_DIV_EQ_HPP 4 5 /* -------------------------------------------------------------------------- 6 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 Bradley M. Bell 7 8 CppAD is distributed under multiple licenses. This distribution is under 9 the terms of the 10 Eclipse Public License Version 1.0. 11 12 A copy of this license is included in the COPYING file of this distribution. 13 Please visit http://www.coin-or.org/CppAD/ for information on other licenses. 14 -------------------------------------------------------------------------- */ 15 16 // BEGIN CppAD namespace 17 namespace CppAD { 18 19 template <class Base> operator /=(const AD<Base> & right)20AD<Base>& AD<Base>::operator /= (const AD<Base> &right) 21 { 22 // compute the Base part 23 Base left; 24 left = value_; 25 value_ /= right.value_; 26 27 // check if there is a recording in progress 28 local::ADTape<Base>* tape = AD<Base>::tape_ptr(); 29 if( tape == CPPAD_NULL ) 30 return *this; 31 tape_id_t tape_id = tape->id_; 32 33 // tape_id cannot match the default value for tape_id_; i.e., 0 34 CPPAD_ASSERT_UNKNOWN( tape_id > 0 ); 35 bool var_left = tape_id_ == tape_id; 36 bool var_right = right.tape_id_ == tape_id; 37 38 if( var_left ) 39 { if( var_right ) 40 { // this = variable / variable 41 CPPAD_ASSERT_UNKNOWN( local::NumRes(local::DivvvOp) == 1 ); 42 CPPAD_ASSERT_UNKNOWN( local::NumArg(local::DivvvOp) == 2 ); 43 44 // put operand addresses in tape 45 tape->Rec_.PutArg(taddr_, right.taddr_); 46 // put operator in the tape 47 taddr_ = tape->Rec_.PutOp(local::DivvvOp); 48 // make this a variable 49 CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id ); 50 } 51 else if( IdenticalOne( right.value_ ) ) 52 { // this = variable * 1 53 } 54 else 55 { // this = variable / parameter 56 CPPAD_ASSERT_UNKNOWN( local::NumRes(local::DivvpOp) == 1 ); 57 CPPAD_ASSERT_UNKNOWN( local::NumArg(local::DivvpOp) == 2 ); 58 59 // put operand addresses in tape 60 addr_t p = tape->Rec_.PutPar(right.value_); 61 tape->Rec_.PutArg(taddr_, p); 62 // put operator in the tape 63 taddr_ = tape->Rec_.PutOp(local::DivvpOp); 64 // make this a variable 65 CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id ); 66 } 67 } 68 else if( var_right ) 69 { if( IdenticalZero(left) ) 70 { // this = 0 / variable 71 } 72 else 73 { // this = parameter / variable 74 CPPAD_ASSERT_UNKNOWN( local::NumRes(local::DivpvOp) == 1 ); 75 CPPAD_ASSERT_UNKNOWN( local::NumArg(local::DivpvOp) == 2 ); 76 77 // put operand addresses in tape 78 addr_t p = tape->Rec_.PutPar(left); 79 tape->Rec_.PutArg(p, right.taddr_); 80 // put operator in the tape 81 taddr_ = tape->Rec_.PutOp(local::DivpvOp); 82 // make this a variable 83 tape_id_ = tape_id; 84 } 85 } 86 return *this; 87 } 88 89 CPPAD_FOLD_ASSIGNMENT_OPERATOR(/=) 90 91 } // END CppAD namespace 92 93 # endif 94