1 #ifndef CPPAD_CG_SOLVER_INCLUDED 2 #define CPPAD_CG_SOLVER_INCLUDED 18 #include <cppad/cg/evaluator/evaluator_solve.hpp> 19 #include <cppad/cg/lang/dot/dot.hpp> 30 if (&expression == &var)
33 size_t bifurcations = (std::numeric_limits<size_t>::max)();
35 std::vector<SourceCodePath> paths;
39 while (bifurcations > 0) {
40 CPPADCG_ASSERT_UNKNOWN(root !=
nullptr);
43 size_t oldBif = bifurcations;
45 foundGraph = findPathGraph(*root, var, bifurcations, 50000);
46 CPPADCG_ASSERT_UNKNOWN(oldBif > bifurcations);
48 if (!foundGraph.contains(var)) {
49 std::cerr <<
"Missing variable " << var << std::endl;
50 printExpression(expression, std::cerr);
51 throw CGException(
"The provided variable ", var.
getName() !=
nullptr ? (
"(" + *var.
getName() +
")") :
"",
" is not present in the expression");
58 throw CGException(
"The provided variable is not present in the expression");
60 }
else if (paths.size() == 1) {
61 CPPADCG_ASSERT_UNKNOWN(paths[0][0].node == root);
62 CPPADCG_ASSERT_UNKNOWN(paths[0].back().node == &var);
64 return solveFor(paths[0]);
67 CPPADCG_ASSERT_UNKNOWN(paths.size() >= 1);
68 CPPADCG_ASSERT_UNKNOWN(paths[0].back().node == &var);
70 CG<Base> expression2 = collectVariable(*root, paths[0], paths[1], bifPos);
71 root = expression2.getOperationNode();
72 if (root ==
nullptr) {
73 throw CGException(
"It is not possible to solve the expression for the requested variable: the variable disappears after symbolic manipulations (e.g., y=x-x).");
78 CPPADCG_ASSERT_UNKNOWN(paths.size() == 1);
79 return solveFor(paths[0]);
87 for (
size_t n = 0; n < path.size() - 1; ++n) {
90 const std::vector<Argument<Base> >& args = pnodeOp.
node->getArguments();
92 CGOpCode op = pnodeOp.
node->getOperationType();
106 rightHs =
CG<Base>(other) / rightHs;
110 case CGOpCode::UnMinus:
111 rightHs *= Base(-1.0);
119 case CGOpCode::Alias:
127 rightHs =
CG<Base>(args[0]) - rightHs;
132 rightHs = log(rightHs);
135 rightHs = exp(rightHs);
142 if (exponent.getParameter() !=
nullptr && *exponent.getParameter() == Base(0.0)) {
144 }
else if (exponent.getParameter() !=
nullptr && *exponent.getParameter() == Base(1.0)) {
147 throw CGException(
"Unable to invert operation '", op,
"'");
159 rightHs = log(rightHs) / log(
CG<Base>(base));
171 rightHs = log(rightHs + sqrt(rightHs * rightHs - Base(1.0)));
176 rightHs = log(rightHs + sqrt(rightHs * rightHs + Base(1.0)));
180 rightHs = Base(0.5) * (log(Base(1.0) + rightHs) - log(Base(1.0) - rightHs));
184 throw CGException(
"Unable to invert operation '", op,
"'");
194 size_t bifurcations = 0;
197 if(bifurcations == 0) {
200 if (paths.empty() || paths[0].empty())
203 return isSolvable(paths[0]);
208 solveFor(expression, var);
218 for (
size_t n = 0; n < path.size() - 1; ++n) {
221 const std::vector<Argument<Base> >& args = pnodeOp.
node->getArguments();
223 CGOpCode op = pnodeOp.
node->getOperationType();
227 case CGOpCode::UnMinus:
229 case CGOpCode::Alias:
243 if (exponent.getParameter() !=
nullptr && *exponent.getParameter() == Base(0.0)) {
245 }
else if (exponent.getParameter() !=
nullptr && *exponent.getParameter() == Base(1.0)) {
std::vector< SourceCodePath > findSingleBifurcation(Node &expression, Node &target, size_t &bifIndex) const
const std::string * getName() const
CGB solveFor(Node &expression, Node &var)
OperationNode< Base > * node