monitor.cpp
1 /*
2  * This file is part of CasADi.
3  *
4  * CasADi -- A symbolic framework for dynamic optimization.
5  * Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl,
6  * KU 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 #include "monitor.hpp"
27 
28 namespace casadi {
29 
30  Monitor::Monitor(const MX& x, const std::string& comment) : comment_(comment) {
31  casadi_assert_dev(x.nnz()>0);
32  set_dep(x);
34  }
35 
36  std::string Monitor::disp(const std::vector<std::string>& arg) const {
37  return "monitor(" + arg.at(0) + ", " + comment_ + ")";
38  }
39 
40  void Monitor::eval_mx(const std::vector<MX>& arg, std::vector<MX>& res) const {
41  res[0] = arg[0].monitor(comment_);
42  }
43 
44  void Monitor::ad_forward(const std::vector<std::vector<MX> >& fseed,
45  std::vector<std::vector<MX> >& fsens) const {
46  for (casadi_int d=0; d<fsens.size(); ++d) {
47  std::stringstream ss;
48  ss << "fwd(" << d << ") of " << comment_;
49  fsens[d][0] = fseed[d][0].monitor(ss.str());
50  }
51  }
52 
53  void Monitor::ad_reverse(const std::vector<std::vector<MX> >& aseed,
54  std::vector<std::vector<MX> >& asens) const {
55  for (casadi_int d=0; d<aseed.size(); ++d) {
56  std::stringstream ss;
57  ss << "adj(" << d << ") of " << comment_;
58  asens[d][0] += aseed[d][0].monitor(ss.str());
59  }
60  }
61 
62  int Monitor::eval_sx(const SXElem** arg, SXElem** res, casadi_int* iw, SXElem* w) const {
63  if (arg[0]!=res[0]) {
64  std::copy(arg[0], arg[0]+nnz(), res[0]);
65  }
66  return 0;
67  }
68 
69  int Monitor::eval(const double** arg, double** res, casadi_int* iw, double* w) const {
70  // Print comment
71  uout() << comment_ << ":" << std::endl;
72  uout() << "[";
73  casadi_int n = nnz();
74  for (casadi_int i=0; i<n; ++i) {
75  if (i!=0) uout() << ", ";
76  uout() << arg[0][i];
77  }
78  uout() << "]" << std::endl;
79 
80  // Perform operation
81  if (arg[0]!=res[0]) {
82  std::copy(arg[0], arg[0]+n, res[0]);
83  }
84  return 0;
85  }
86 
87  int Monitor::sp_forward(const bvec_t** arg, bvec_t** res, casadi_int* iw, bvec_t* w) const {
88  if (arg[0]!=res[0]) {
89  std::copy(arg[0], arg[0]+nnz(), res[0]);
90  }
91  return 0;
92  }
93 
94  int Monitor::sp_reverse(bvec_t** arg, bvec_t** res, casadi_int* iw, bvec_t* w) const {
95  bvec_t *a = arg[0];
96  bvec_t *r = res[0];
97  casadi_int n = nnz();
98  if (a != r) {
99  for (casadi_int i=0; i<n; ++i) {
100  *a++ |= *r;
101  *r++ = 0;
102  }
103  }
104  return 0;
105  }
106 
108  const std::vector<casadi_int>& arg,
109  const std::vector<casadi_int>& res,
110  const std::vector<bool>& arg_is_ref,
111  std::vector<bool>& res_is_ref) const {
112  // Print comment
113  g.local("cr", "const casadi_real", "*");
114  g.local("i", "casadi_int");
115  g << g.printf(comment_ + "\\n[") << "\n"
116  << " for (i=0, cr=" << g.work(arg[0], dep(0).nnz(), arg_is_ref[0])
117  << "; i!=" << nnz() << "; ++i) {\n"
118  << " if (i!=0) " << g.printf(", ") << "\n"
119  << " " << g.printf("%g", "*cr++") << "\n"
120  << " }\n"
121  << " " << g.printf("]\\n") << "\n";
122 
123  generate_copy(g, arg, res, arg_is_ref, res_is_ref, 0);
124  }
125 
128  s.pack("Monitor::comment", comment_);
129  }
130 
132  s.unpack("Monitor::comment", comment_);
133  }
134 
135 } // namespace casadi
Helper class for C code generation.
std::string work(casadi_int n, casadi_int sz, bool is_ref) const
std::string printf(const std::string &str, const std::vector< std::string > &arg=std::vector< std::string >())
Printf.
void local(const std::string &name, const std::string &type, const std::string &ref="")
Declare a local variable.
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
casadi_int nnz() const
Get the number of (structural) non-zero elements.
Node class for MX objects.
Definition: mx_node.hpp:51
void generate_copy(CodeGenerator &g, const std::vector< casadi_int > &arg, const std::vector< casadi_int > &res, const std::vector< bool > &arg_is_ref, std::vector< bool > &res_is_ref, casadi_int i) const
Definition: mx_node.cpp:457
casadi_int nnz(casadi_int i=0) const
Definition: mx_node.hpp:389
const MX & dep(casadi_int ind=0) const
dependencies - functions that have to be evaluated before this one
Definition: mx_node.hpp:354
virtual void serialize_body(SerializingStream &s) const
Serialize an object without type information.
Definition: mx_node.cpp:523
void set_sparsity(const Sparsity &sparsity)
Set the sparsity.
Definition: mx_node.cpp:222
void set_dep(const MX &dep)
Set unary dependency.
Definition: mx_node.cpp:226
MX - Matrix expression.
Definition: mx.hpp:92
const Sparsity & sparsity() const
Get the sparsity pattern.
Definition: mx.cpp:592
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
Definition: monitor.cpp:36
int sp_forward(const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate sparsity forward.
Definition: monitor.cpp:87
void ad_forward(const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens) const override
Calculate forward mode directional derivatives.
Definition: monitor.cpp:44
void ad_reverse(const std::vector< std::vector< MX > > &aseed, std::vector< std::vector< MX > > &asens) const override
Calculate reverse mode directional derivatives.
Definition: monitor.cpp:53
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res) const override
Evaluate symbolically (MX)
Definition: monitor.cpp:40
int eval_sx(const SXElem **arg, SXElem **res, casadi_int *iw, SXElem *w) const override
Evaluate the function symbolically (SX)
Definition: monitor.cpp:62
int eval(const double **arg, double **res, casadi_int *iw, double *w) const override
Evaluate the function numerically.
Definition: monitor.cpp:69
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
Definition: monitor.cpp:126
Monitor(const MX &x, const std::string &comment)
Constructor.
Definition: monitor.cpp:30
void generate(CodeGenerator &g, const std::vector< casadi_int > &arg, const std::vector< casadi_int > &res, const std::vector< bool > &arg_is_ref, std::vector< bool > &res_is_ref) const override
Generate code for the operation.
Definition: monitor.cpp:107
int sp_reverse(bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate sparsity backwards.
Definition: monitor.cpp:94
The basic scalar symbolic class of CasADi.
Definition: sx_elem.hpp:75
Helper class for Serialization.
void pack(const Sparsity &e)
Serializes an object to the output stream.
The casadi namespace.
Definition: archiver.cpp:28
unsigned long long bvec_t
std::ostream & uout()