26 #ifndef CASADI_CONSTANT_SX_HPP
27 #define CASADI_CONSTANT_SX_HPP
29 #include "sx_node.hpp"
30 #include "serializing_stream.hpp"
36 #include <unordered_map>
37 #define CACHING_MAP std::unordered_map
47 class ConstantSX :
public SXNode {
51 ~ConstantSX()
override {}
54 std::string class_name()
const override {
return "ConstantSX";}
59 double to_double()
const override = 0;
64 bool is_constant()
const override {
return true; }
69 casadi_int op()
const override {
return OP_CONST;}
74 bool is_equal(
const SXNode* node, casadi_int depth)
const override {
75 const ConstantSX* n =
dynamic_cast<const ConstantSX*
>(node);
76 return n && n->to_double()==to_double();
84 std::string print(
const std::string& arg1,
const std::string& arg2)
const override {
102 class RealtypeSX :
public ConstantSX {
105 explicit RealtypeSX(
double value) : value(value) {}
110 ~RealtypeSX()
override {
111 size_t num_erased = cached_constants_.erase(value);
112 assert(num_erased==1);
117 inline static RealtypeSX* create(
double value) {
119 CACHING_MAP<double, RealtypeSX*>::iterator it = cached_constants_.find(value);
122 if (it==cached_constants_.end()) {
124 RealtypeSX* n =
new RealtypeSX(value);
127 cached_constants_.insert(it, std::make_pair(value, n));
140 double to_double()
const override {
return value;}
141 casadi_int to_int()
const override {
return static_cast<casadi_int
>(value);}
144 bool is_almost_zero(
double tol)
const override {
return fabs(value)<=tol; }
146 void serialize_node(SerializingStream& s)
const override {
147 s.pack(
"ConstantSX::type",
'r');
148 s.pack(
"ConstantSX::value", value);
157 static CACHING_MAP<double, RealtypeSX*> cached_constants_;
172 class IntegerSX :
public ConstantSX {
175 explicit IntegerSX(casadi_int value) : value(static_cast<int>(value)) {
176 casadi_assert(value<=std::numeric_limits<int>::max() &&
177 value>=std::numeric_limits<int>::min(),
"Integer overflow");
183 ~IntegerSX()
override {
184 size_t num_erased = cached_constants_.erase(value);
185 assert(num_erased==1);
190 inline static IntegerSX* create(casadi_int value) {
192 CACHING_MAP<casadi_int, IntegerSX*>::iterator it = cached_constants_.find(value);
195 if (it==cached_constants_.end()) {
197 IntegerSX* n =
new IntegerSX(value);
200 cached_constants_.insert(it, std::make_pair(value, n));
213 double to_double()
const override {
return static_cast<double>(value); }
214 casadi_int to_int()
const override {
return static_cast<casadi_int
>(value); }
220 bool is_integer()
const override {
return true; }
222 void serialize_node(SerializingStream& s)
const override {
223 s.pack(
"ConstantSX::type",
'i');
224 s.pack(
"ConstantSX::value", value);
234 static CACHING_MAP<casadi_int, IntegerSX*> cached_constants_;
248 class ZeroSX :
public ConstantSX {
251 explicit ZeroSX() {this->count++;}
254 static ZeroSX* singleton() {
255 static ZeroSX instance;
259 ~ZeroSX()
override {this->count--;}
264 double to_double()
const override {
return 0;}
265 casadi_int to_int()
const override {
return 0;}
272 bool is_integer()
const override {
return true; }
273 bool is_zero()
const override {
return true; }
274 bool is_almost_zero(
double tol)
const override {
return true; }
277 void serialize_node(SerializingStream& s)
const override {
278 s.pack(
"ConstantSX::type",
'0');
289 class OneSX :
public ConstantSX {
292 explicit OneSX() {this->count++;}
295 static OneSX* singleton() {
296 static OneSX instance;
300 ~OneSX()
override {this->count--;}
304 double to_double()
const override {
return 1;}
305 casadi_int to_int()
const override {
return 1;}
310 bool is_integer()
const override {
return true; }
311 bool is_one()
const override {
return true; }
313 void serialize_node(SerializingStream& s)
const override {
314 s.pack(
"ConstantSX::type",
'1');
326 class MinusOneSX :
public ConstantSX {
329 explicit MinusOneSX() {this->count++;}
332 static MinusOneSX* singleton() {
333 static MinusOneSX instance;
337 ~MinusOneSX()
override {this->count--;}
343 double to_double()
const override {
return -1;}
344 casadi_int to_int()
const override {
return -1;}
351 bool is_integer()
const override {
return true; }
352 bool is_minus_one()
const override {
return true; }
355 void serialize_node(SerializingStream& s)
const override {
356 s.pack(
"ConstantSX::type",
'm');
368 class InfSX :
public ConstantSX {
371 explicit InfSX() {this->count++;}
374 static InfSX* singleton() {
375 static InfSX instance;
379 ~InfSX()
override {this->count--;}
383 double to_double()
const override {
return std::numeric_limits<double>::infinity();}
388 bool is_inf()
const override {
return true; }
390 void serialize_node(SerializingStream& s)
const override {
391 s.pack(
"ConstantSX::type",
'F');
403 class MinusInfSX :
public ConstantSX {
406 explicit MinusInfSX() {this->count++;}
409 static MinusInfSX* singleton() {
410 static MinusInfSX instance;
414 ~MinusInfSX()
override {this->count--;}
419 double to_double()
const override {
return -std::numeric_limits<double>::infinity();}
424 bool is_minus_inf()
const override {
return true; }
426 void serialize_node(SerializingStream& s)
const override {
427 s.pack(
"ConstantSX::type",
'f');
437 class NanSX :
public ConstantSX {
440 explicit NanSX() {this->count++;}
443 static NanSX* singleton() {
444 static NanSX instance;
448 ~NanSX()
override {this->count--;}
452 double to_double()
const override {
return std::numeric_limits<double>::quiet_NaN();}
457 bool is_nan()
const override {
return true; }
459 void serialize_node(SerializingStream& s)
const override {
460 s.pack(
"ConstantSX::type",
'n');
465 inline SXNode* ConstantSX_deserialize(DeserializingStream& s) {
467 s.unpack(
"ConstantSX::type", type);
473 s.unpack(
"ConstantSX::value", value);
474 return RealtypeSX::create(value);
478 s.unpack(
"ConstantSX::value", value);
480 return IntegerSX::create(value);
482 case 'n':
return casadi_limits<SXElem>::nan.get();
483 case 'f':
return casadi_limits<SXElem>::minus_inf.get();
484 case 'F':
return casadi_limits<SXElem>::inf.get();
486 default: casadi_error(
"ConstantSX::deserialize error");