From f55fda0938a9b570482afb485f3c27286e78088f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Tue, 11 Mar 2014 17:33:46 +0100
Subject: [PATCH] Implement cloneDynamic() for
 {First,Second}DerivExternalFunction.

Since the method was not implement, the method of the parent class was used.
This was leading to wrong results in the context of Ramsey Policy (basically
derivative operators on external functions were dropped from FOCs).
---
 preprocessor/ExprNode.cc | 22 ++++++++++++++++++++++
 preprocessor/ExprNode.hh |  2 ++
 2 files changed, 24 insertions(+)

diff --git a/preprocessor/ExprNode.cc b/preprocessor/ExprNode.cc
index fcf19ec511..5620b11a27 100644
--- a/preprocessor/ExprNode.cc
+++ b/preprocessor/ExprNode.cc
@@ -5140,6 +5140,17 @@ FirstDerivExternalFunctionNode::compileExternalFunctionOutput(ostream &CompileCo
     }
 }
 
+expr_t
+FirstDerivExternalFunctionNode::cloneDynamic(DataTree &dynamic_datatree) const
+{
+  vector<expr_t> dynamic_arguments;
+  for (vector<expr_t>::const_iterator it = arguments.begin();
+       it != arguments.end(); it++)
+    dynamic_arguments.push_back((*it)->cloneDynamic(dynamic_datatree));
+  return dynamic_datatree.AddFirstDerivExternalFunctionNode(symb_id, dynamic_arguments,
+                                                            inputIndex);
+}
+
 SecondDerivExternalFunctionNode::SecondDerivExternalFunctionNode(DataTree &datatree_arg,
                                                                  int top_level_symb_id_arg,
                                                                  const vector<expr_t> &arguments_arg,
@@ -5336,3 +5347,14 @@ SecondDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, Ex
       output << ");" << endl;
     }
 }
+
+expr_t
+SecondDerivExternalFunctionNode::cloneDynamic(DataTree &dynamic_datatree) const
+{
+  vector<expr_t> dynamic_arguments;
+  for (vector<expr_t>::const_iterator it = arguments.begin();
+       it != arguments.end(); it++)
+    dynamic_arguments.push_back((*it)->cloneDynamic(dynamic_datatree));
+  return dynamic_datatree.AddSecondDerivExternalFunctionNode(symb_id, dynamic_arguments,
+                                                             inputIndex1, inputIndex2);
+}
diff --git a/preprocessor/ExprNode.hh b/preprocessor/ExprNode.hh
index c77c8cbcf7..c0de01b82e 100644
--- a/preprocessor/ExprNode.hh
+++ b/preprocessor/ExprNode.hh
@@ -874,6 +874,7 @@ public:
                                              bool lhs_rhs, const temporary_terms_t &temporary_terms,
                                              const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
                                              deriv_node_temp_terms_t &tef_terms) const;
+  virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
 };
 
 class SecondDerivExternalFunctionNode : public ExternalFunctionNode
@@ -899,6 +900,7 @@ public:
   virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
                                            const temporary_terms_t &temporary_terms,
                                            deriv_node_temp_terms_t &tef_terms) const;
+  virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
 };
 
 #endif
-- 
GitLab