Loading...
Searching...
No Matches
cg.hpp
Go to the documentation of this file.
1/*
2 * Copyright 2021 INRIA
3 */
4
5#ifndef __pycppad_codegen_cg_hpp__
6#define __pycppad_codegen_cg_hpp__
7
8#include <cppad/cg/cppadcg.hpp>
9
10#include <eigenpy/user-type.hpp>
11#include <eigenpy/ufunc.hpp>
12
13#include "pycppad/cast.hpp"
14
15namespace eigenpy {
16
17template <typename Scalar, typename To>
18struct cast<::CppAD::cg::CG<Scalar>, To>
19{
20 typedef ::CppAD::cg::CG<Scalar> From;
21 static To run(const From & from) {
22 return ::pycppad::internal::Cast<From, To>::run(from);
23 }
24};
25
26template <typename From, typename Scalar>
27struct cast<From,::CppAD::cg::CG<Scalar>>
28{
29 typedef ::CppAD::cg::CG<Scalar> To;
30 static To run(const From & from) {
31 return To(static_cast<Scalar>(from));
32 }
33};
34
35namespace internal {
36
37template <typename Scalar>
38struct getitem<::CppAD::cg::CG<Scalar>> {
39
40 typedef ::CppAD::cg::CG<Scalar> CG;
41
42 static PyObject* run(void* data, void* /* arr */) {
43 CG & cg = *static_cast<CG*>(data);
44
45 if(!cg.isValueDefined()) // not initialized
46 cg.setValue(static_cast<Scalar>(0));
47
48 bp::object m(cg);
49 Py_INCREF(m.ptr());
50 return m.ptr();
51 }
52};
53
54} // namespace internal
55} // namespace eigenpy
56
57namespace pycppad
58{
59 namespace internal
60 {
61
62 template<typename Scalar>
63 struct CppADValue<::CppAD::cg::CG<Scalar>>
64 {
65 static const Scalar & get(const ::CppAD::AD<::CppAD::cg::CG<Scalar>> & v)
66 {
67 return ::CppAD::Value<::CppAD::cg::CG<Scalar>>(v).getValue();
68 }
69 };
70
71 template<typename Scalar, typename To>
72 struct Cast<::CppAD::cg::CG<Scalar>,To>
73 {
74 typedef ::CppAD::cg::CG<Scalar> From;
75 static To run(const From & from)
76 {
77 return static_cast<To>(::CppAD::Value<From>(from).getValue());
78 }
79 };
80 }
81
82 namespace codegen
83 {
84
85 namespace bp = boost::python;
86
87 template<typename Scalar>
89 : public bp::def_visitor< CGVisitor<Scalar> >
90 {
91 public:
92 typedef ::CppAD::cg::CG<Scalar> CG;
93
94 template<class PyClass>
95 void visit(PyClass& cl) const
96 {
97 cl
98 .def(bp::init<>(bp::arg("self"),"Default constructor"))
99 .def(bp::init<Scalar>(bp::args("self","value"),
100 std::string("Constructor from a ").append(bp::type_id<Scalar>().name()).c_str()))
101 .def(bp::init<CG>(bp::args("self","other"),"Copy constructor"))
102 .def("isIdenticalZero", &CG::isIdenticalZero, bp::arg("self"))
103 .def("isIdenticalOne", &CG::isIdenticalOne, bp::arg("self"))
104 .def("isValueDefined", &CG::isValueDefined, bp::arg("self"))
105 .def("isParameter", &CG::isParameter, bp::arg("self"))
106 .def("isVariable", &CG::isVariable, bp::arg("self"))
107
108 .def(bp::self + bp::self)
109 .def(bp::self - bp::self)
110 .def(bp::self * bp::self)
111 .def(bp::self / bp::self)
112 .def(bp::self += bp::self)
113#ifdef __clang__
114#pragma GCC diagnostic push
115#pragma GCC diagnostic ignored "-Wself-assign-overloaded"
116#endif
117 .def(bp::self /= bp::self)
118 .def(bp::self -= bp::self) // See https://bugs.llvm.org/show_bug.cgi?id=43124 for the bug
119#ifdef __clang__
120#pragma GCC diagnostic pop
121#endif
122 .def(bp::self *= bp::self)
123 .add_property("value",
124 bp::make_function(&CG::getValue,
125 bp::return_value_policy<bp::copy_const_reference>()),
126 &CG::setValue)
127 .def("__str__",&print)
128 .def("__repr__",&print)
129 .add_property("__float__",
130 bp::make_function(&CG::getValue,
131 bp::return_value_policy<bp::copy_const_reference>()),
132 &CG::setValue)
133 .def("__int__",&internal::Cast<CG,int64_t>::run)
134 ;
135 }
136
137 private:
138
139 static std::string print(const CG & self)
140 {
141 std::stringstream ss;
142 ss << get_class_name() << "(" << self <<")";
143 return ss.str();
144 }
145
146 protected:
147
148 static std::string & get_class_name()
149 {
150 static std::string class_name;
151 return class_name;
152 }
153
154 static void set_class_name(const std::string & class_name)
155 {
156 get_class_name() = class_name;
157 }
158
159 public:
160
161 static void expose(const std::string & class_name = "CG")
162 {
163 set_class_name(class_name);
164 bp::class_<CG>(class_name.c_str(),
165 std::string("CG type corresponding to the scalar type ").append(bp::type_id<Scalar>().name()).c_str(),
166 bp::no_init)
167 .def(CGVisitor<Scalar>());
168
169 eigenpy::registerNewType<CG>();
170 eigenpy::registerCommonUfunc<CG>();
171
172 eigenpy::registerCast<CG,double>(false);
173 eigenpy::registerCast<double,CG>(true);
174 eigenpy::registerCast<CG,float>(false);
175 eigenpy::registerCast<float,CG>(true);
176 eigenpy::registerCast<CG,long>(false);
177 eigenpy::registerCast<long,CG>(true);
178 eigenpy::registerCast<CG,int>(false);
179 eigenpy::registerCast<int,CG>(true);
180 }
181 };
182
183 }
184}
185#endif //#ifndef __pycppad_codegen_cg_hpp__
Definition cg.hpp:90
static void set_class_name(const std::string &class_name)
Definition cg.hpp:154
static std::string & get_class_name()
Definition cg.hpp:148
::CppAD::cg::CG< Scalar > CG
Definition cg.hpp:92
void visit(PyClass &cl) const
Definition cg.hpp:95
static void expose(const std::string &class_name="CG")
Definition cg.hpp:161
Definition cast.hpp:47
Definition ad.hpp:15
static To run(const From &from)
Definition cg.hpp:30
::CppAD::cg::CG< Scalar > To
Definition cg.hpp:29
static To run(const From &from)
Definition cg.hpp:21
::CppAD::cg::CG< Scalar > From
Definition cg.hpp:20
::CppAD::cg::CG< Scalar > CG
Definition cg.hpp:40
static PyObject * run(void *data, void *)
Definition cg.hpp:42
static To run(const From &from)
Definition cg.hpp:75
::CppAD::cg::CG< Scalar > From
Definition cg.hpp:74
Definition cast.hpp:19
static const Scalar & get(const ::CppAD::AD<::CppAD::cg::CG< Scalar > > &v)
Definition cg.hpp:65
Definition cast.hpp:28