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)20 AD<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