call_sx.hpp
1 /*
2  * This file is part of CasADi.
3  *
4  * CasADi -- A symbolic framework for dynamic optimization.
5  * Copyright (C) 2010-2014 Joel Andersson, Joris Gillis, Moritz Diehl,
6  * K.U. Leuven. All rights reserved.
7  * Copyright (C) 2011-2014 Greg Horn
8  *
9  * CasADi is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 3 of the License, or (at your option) any later version.
13  *
14  * CasADi is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with CasADi; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 
26 #ifndef CASADI_CALL_SX_HPP
27 #define CASADI_CALL_SX_HPP
28 
29 #include "sx_node.hpp"
30 #include "output_sx.hpp"
31 #include "function.hpp"
32 #include <deque>
33 #include <stack>
34 
35 // Caching of outputs requires a map
36 #include <unordered_map>
37 #define CACHING_MAP std::unordered_map
38 
40 namespace casadi {
41 
42 class CASADI_EXPORT CallSX : public SXNode {
43  private:
44 
48  CallSX(const Function& f, const std::vector<SXElem>& dep) :
49  f_(f), dep_(dep) {}
50 
51  mutable WeakCache<casadi_int, SharedSXElem> cache_;
52  public:
53 
57  inline static SXElem create(const Function& f, const std::vector<SXElem>& dep) {
58  casadi_assert(f.nnz_in()==dep.size(),
59  "CallSX::create(f,dep): dimension mismatch: " + str(f.nnz_in()) + " vs " + str(dep.size()));
60  return SXElem::create(new CallSX(f, dep));
61  }
62 
63  inline static int eval_sx(const Function& f, const SXElem** arg, SXElem** res) {
64  // Collect dep from arg
65  std::vector<SXElem> dep;
66  for (casadi_int i=0;i<f.n_in();++i) {
67  dep.insert(dep.end(), arg[i], arg[i]+f.nnz_in(i));
68  }
69 
70  std::vector<SXElem> ret = SXElem::call(f, dep);
71 
72  // Copy ret to res
73  casadi_int offset = 0;
74  for (casadi_int i=0;i<f.n_out();++i) {
75  casadi_copy(get_ptr(ret)+offset, f.nnz_out(i), res[i]);
76  offset += f.nnz_out(i);
77  }
78 
79  return 0;
80  }
81 
88  ~CallSX() override {
89  for (auto & d : dep_)
90  safe_delete(d.assignNoDelete(casadi_limits<SXElem>::nan));
91  }
92 
93  // Class name
94  std::string class_name() const override {return "CallSX";}
95 
96  bool is_op(casadi_int op) const override { return OP_CALL==op; }
97 
101  casadi_int n_dep() const override { return dep_.size();}
102 
106  SXElem get_output(casadi_int oind) const override {
107  SharedSXElem ret;
108  // If not found, add it,
109  if (!cache_.incache(oind, ret)) {
110  ret.own(new OutputSX(SXNode::shared_from_this(), oind));
111  cache_.tocache_if_missing(oind, ret);
112  }
113  return SXElem::create(ret.get());
114  }
115 
119  const SXElem& dep(casadi_int i) const override { return dep_[i];}
120  SXElem& dep(casadi_int i) override { return dep_[i];}
121 
125  casadi_int op() const override { return OP_CALL; }
126 
130  bool is_call() const override { return true; }
131 
135  bool has_output() const override { return true; }
136 
140  Function which_function() const override { return f_; }
141 
145  std::string print(const std::string& arg1, const std::string& arg2) const override {
146  return f_.name();
147  }
148 
149  Function f_;
150 
154  std::vector<SXElem> dep_;
155 
156  void serialize_node(SerializingStream& s) const override {
157  s.pack("CallSX::f", f_);
158  s.pack("CallSX::dep", dep_);
159  }
160 
161  static SXNode* deserialize(DeserializingStream& s) {
162  std::vector<SXElem> dep;
163  Function f;
164  s.unpack("CallSX::f", f);
165  s.unpack("CallSX::dep", dep);
166  return new CallSX(f, dep);
167  }
168 
169 };
170 
171 
172 } // namespace casadi
174 
175 #endif // CASADI_CALL_SX_HPP
The casadi namespace.
Definition: archiver.hpp:32