CppADCodeGen  HEAD
A C++ Algorithmic Differentiation Package with Source Code Generation
graph_mod.hpp
1 #ifndef CPPAD_CG_GRAPH_MOD_INCLUDED
2 #define CPPAD_CG_GRAPH_MOD_INCLUDED
3 /* --------------------------------------------------------------------------
4  * CppADCodeGen: C++ Algorithmic Differentiation with Source Code Generation:
5  * Copyright (C) 2012 Ciengis
6  *
7  * CppADCodeGen is distributed under multiple licenses:
8  *
9  * - Eclipse Public License Version 1.0 (EPL1), and
10  * - GNU General Public License Version 3 (GPL3).
11  *
12  * EPL1 terms and conditions can be found in the file "epl-v10.txt", while
13  * terms and conditions for the GPL3 can be found in the file "gpl3.txt".
14  * ----------------------------------------------------------------------------
15  * Author: Joao Leal
16  */
17 
18 namespace CppAD {
19 namespace cg {
20 
21 template<class Base>
23  const CG<Base>& dep,
24  bool removeFromIndependents) {
25  substituteIndependent(*indep.getOperationNode(), *dep.getOperationNode(), removeFromIndependents);
26 }
27 
28 template<class Base>
31  bool removeFromIndependents) {
32  using std::vector;
33  using CGBase = CG<Base>;
34 
35  //check if the independent variable belongs to this handler
36  size_t indepIndex = getIndependentVariableIndex(indep);
37 
38  //check if the dependent variable belongs to this handler
39  size_t pos = dep.getHandlerPosition();
40  if (pos >= _codeBlocks.size() || &dep != _codeBlocks[pos]) {
41  throw CGException("The dependent variable does not belong to this handler");
42  }
43 
44  // determine the expression for the independent variable
45  CGBase dummyExp = solveFor(dep, indep);
46 
47  Argument<Base> arg;
48  // change the independent variable
49  if (dummyExp.isVariable()) {
50  arg = Argument<Base> (*dummyExp.getOperationNode());
51  } else {
52  // create a bogus variable to avoid searching for all occurrences of the independent variable
53  arg = Argument<Base> (dummyExp.getValue());
54  }
55 
56  indep.makeAlias(arg);
57 
58  if (removeFromIndependents) {
59  // remove the substituted variable from the independent variable vector
60  _independentVariables.erase(_independentVariables.begin() + indepIndex);
61  }
62 }
63 
64 template<class Base>
66  typename std::vector<OperationNode<Base> *>::const_iterator it =
67  std::find(_independentVariables.begin(), _independentVariables.end(), &indep);
68  if (it == _independentVariables.end()) {
69  throw CGException("Variable not found in the independent variable vector");
70  }
71 
72  indep.setOperation(CGOpCode::Inv);
73 }
74 
75 template<class Base>
77  if (indep.getOperationType() != CGOpCode::Alias) {
78  throw CGException("Cannot remove independent variable: not an alias");
79  }
80 
81  typename std::vector<OperationNode<Base> *>::iterator it =
82  std::find(_independentVariables.begin(), _independentVariables.end(), &indep);
83  if (it == _independentVariables.end()) {
84  throw CGException("Variable not found in the independent variable vector");
85  }
86  _independentVariables.erase(it);
87 }
88 
89 } // END cg namespace
90 } // END CppAD namespace
91 
92 #endif
void substituteIndependent(const CGB &indep, const CGB &dep, bool removeFromIndeps=true)
Definition: graph_mod.hpp:22
size_t getHandlerPosition() const
void removeIndependent(Node &indep)
Definition: graph_mod.hpp:76
CGOpCode getOperationType() const
void undoSubstituteIndependent(Node &indep)
Definition: graph_mod.hpp:65
void makeAlias(const Argument< Base > &other)
void setOperation(CGOpCode op, const std::vector< Argument< Base > > &arguments=std::vector< Argument< Base > >())