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 
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 
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 
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
casadi_int n_dep() const override
Number of dependencies.
Definition: call_sx.hpp:101
static SXNode * deserialize(DeserializingStream &s)
Definition: call_sx.hpp:161
SXElem & dep(casadi_int i) override
get the reference of a child
Definition: call_sx.hpp:120
bool has_output() const override
Check if a multiple output node.
Definition: call_sx.hpp:135
bool is_op(casadi_int op) const override
check properties of a node
Definition: call_sx.hpp:96
SXElem get_output(casadi_int oind) const override
Get an output.
Definition: call_sx.hpp:106
std::vector< SXElem > dep_
The dependencies of the node.
Definition: call_sx.hpp:154
bool is_call() const override
Check if call node.
Definition: call_sx.hpp:130
Function which_function() const override
Get function.
Definition: call_sx.hpp:140
const SXElem & dep(casadi_int i) const override
get the reference of a dependency
Definition: call_sx.hpp:119
static SXElem create(const Function &f, const std::vector< SXElem > &dep)
Create a binary expression.
Definition: call_sx.hpp:57
void serialize_node(SerializingStream &s) const override
Definition: call_sx.hpp:156
casadi_int op() const override
Get the operation.
Definition: call_sx.hpp:125
std::string print(const std::string &arg1, const std::string &arg2) const override
Print expression.
Definition: call_sx.hpp:145
Function f_
Definition: call_sx.hpp:149
static int eval_sx(const Function &f, const SXElem **arg, SXElem **res)
Definition: call_sx.hpp:63
~CallSX() override
Destructor.
Definition: call_sx.hpp:88
std::string class_name() const override
Get type name.
Definition: call_sx.hpp:94
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
Function object.
Definition: function.hpp:60
casadi_int nnz_out() const
Get number of output nonzeros.
Definition: function.cpp:855
casadi_int n_out() const
Get the number of function outputs.
Definition: function.cpp:823
casadi_int n_in() const
Get the number of function inputs.
Definition: function.cpp:819
casadi_int nnz_in() const
Get number of input nonzeros.
Definition: function.cpp:851
Internal * get() const
Get a const pointer to the node.
void own(Internal *node)
The basic scalar symbolic class of CasADi.
Definition: sx_elem.hpp:75
static std::vector< SXElem > call(const Function &f, const std::vector< SXElem > &deps)
Definition: sx_elem.cpp:403
static SXElem create(SXNode *node)
Definition: sx_elem.cpp:62
Internal node class for SX.
Definition: sx_node.hpp:49
SXElem shared_from_this()
Get a shared object from the current internal object.
Definition: sx_node.cpp:261
Helper class for Serialization.
void pack(const Sparsity &e)
Serializes an object to the output stream.
bool incache(const K &key, T &f, bool needs_lock=true) const
void tocache_if_missing(const K &key, T &f)
casadi_limits class
The casadi namespace.
Definition: archiver.cpp:28
void casadi_copy(const T1 *x, casadi_int n, T1 *y)
COPY: y <-x.
std::string str(const T &v)
String representation, any type.
T * get_ptr(std::vector< T > &v)
Get a pointer to the data contained in the vector.
@ OP_CALL
Definition: calculus.hpp:88