assertion.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 "assertion.hpp"
27 #include "serializing_stream.hpp"
28 
29 namespace casadi {
30 
31  Assertion::Assertion(const MX& x, const MX& y, const std::string & fail_message)
32  : fail_message_(fail_message) {
33  casadi_assert(y.is_scalar(),
34  "Assertion:: assertion expression y must be scalar, but got " + y.dim());
35  set_dep(x, y);
37  }
38 
39  std::string Assertion::disp(const std::vector<std::string>& arg) const {
40  return "assertion(" + arg.at(0) + ", " + arg.at(1) + ")";
41  }
42 
43  void Assertion::eval_mx(const std::vector<MX>& arg, std::vector<MX>& res) const {
44  res[0] = arg[0].attachAssert(arg[1], fail_message_);
45  }
46 
47  void Assertion::ad_forward(const std::vector<std::vector<MX> >& fseed,
48  std::vector<std::vector<MX> >& fsens) const {
49  for (casadi_int d=0; d<fsens.size(); ++d) {
50  fsens[d][0] = fseed[d][0];
51  }
52  }
53 
54  void Assertion::ad_reverse(const std::vector<std::vector<MX> >& aseed,
55  std::vector<std::vector<MX> >& asens) const {
56  for (casadi_int d=0; d<aseed.size(); ++d) {
57  asens[d][0] += aseed[d][0];
58  }
59  }
60 
61  int Assertion::eval_sx(const SXElem** arg, SXElem** res, casadi_int* iw, SXElem* w) const {
62  if (arg[0]!=res[0]) {
63  std::copy(arg[0], arg[0]+nnz(), res[0]);
64  }
65  return 0;
66  }
67 
68  int Assertion::eval(const double** arg, double** res, casadi_int* iw, double* w) const {
69  if (arg[1][0]!=1) {
70  casadi_error("Assertion error: " + fail_message_);
71  return 1;
72  }
73 
74  if (arg[0]!=res[0]) {
75  std::copy(arg[0], arg[0]+nnz(), res[0]);
76  }
77  return 0;
78  }
79 
80  int Assertion::sp_forward(const bvec_t** arg, bvec_t** res, casadi_int* iw, bvec_t* w) const {
81  if (arg[0]!=res[0]) {
82  std::copy(arg[0], arg[0]+nnz(), res[0]);
83  }
84  return 0;
85  }
86 
87  int Assertion::sp_reverse(bvec_t** arg, bvec_t** res, casadi_int* iw, bvec_t* w) const {
88  bvec_t *a = arg[0];
89  bvec_t *r = res[0];
90  casadi_int n = nnz();
91  if (a != r) {
92  for (casadi_int i=0; i<n; ++i) {
93  *a++ |= *r;
94  *r++ = 0;
95  }
96  }
97  return 0;
98  }
99 
101  const std::vector<casadi_int>& arg,
102  const std::vector<casadi_int>& res,
103  const std::vector<bool>& arg_is_ref,
104  std::vector<bool>& res_is_ref) const {
105  // Generate assertion
106  g << "if (" << g.workel(arg[1]) << "!=1.) {\n"
107  << " /* " << fail_message_ << " */\n"
108  << " return 1;\n"
109  << " }\n";
110 
111  generate_copy(g, arg, res, arg_is_ref, res_is_ref, 0);
112  }
113 
116  s.pack("Assertion::fail_message", fail_message_);
117  }
118 
120  s.unpack("Assertion::fail_message", fail_message_);
121  }
122 
123 } // namespace casadi
int eval_sx(const SXElem **arg, SXElem **res, casadi_int *iw, SXElem *w) const override
Evaluate the function symbolically (SX)
Definition: assertion.cpp:61
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
Definition: assertion.cpp:39
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: assertion.cpp:100
int sp_reverse(bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate sparsity backwards.
Definition: assertion.cpp:87
int eval(const double **arg, double **res, casadi_int *iw, double *w) const override
Evaluate the function numerically.
Definition: assertion.cpp:68
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res) const override
Evaluate symbolically (MX)
Definition: assertion.cpp:43
void ad_forward(const std::vector< std::vector< MX > > &fseed, std::vector< std::vector< MX > > &fsens) const override
Calculate forward mode directional derivatives.
Definition: assertion.cpp:47
int sp_forward(const bvec_t **arg, bvec_t **res, casadi_int *iw, bvec_t *w) const override
Propagate sparsity forward.
Definition: assertion.cpp:80
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
Definition: assertion.cpp:114
Assertion(const MX &x, const MX &y, const std::string &fail_message)
Constructor.
Definition: assertion.cpp:31
void ad_reverse(const std::vector< std::vector< MX > > &aseed, std::vector< std::vector< MX > > &asens) const override
Calculate reverse mode directional derivatives.
Definition: assertion.cpp:54
Helper class for C code generation.
std::string workel(casadi_int n) const
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
std::string dim(bool with_nz=false) const
Get string representation of dimensions.
bool is_scalar(bool scalar_and_dense=false) const
Check if the matrix expression is scalar.
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
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
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