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 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
113 std::lock_guard<std::mutex> lock(mutex_cached_constants);
115 size_t num_erased = cached_constants_.erase(value);
116 assert(num_erased==1);
121 inline static RealtypeSX* create(
double value) {
122 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
124 std::lock_guard<std::mutex> lock(mutex_cached_constants);
127 CACHING_MAP<double, RealtypeSX*>::iterator it = cached_constants_.find(value);
130 if (it==cached_constants_.end()) {
132 RealtypeSX* n =
new RealtypeSX(value);
135 cached_constants_.insert(it, std::make_pair(value, n));
148 double to_double()
const override {
return value;}
149 casadi_int to_int()
const override {
return static_cast<casadi_int
>(value);}
152 bool is_almost_zero(
double tol)
const override {
return fabs(value)<=tol; }
154 void serialize_node(SerializingStream& s)
const override {
155 s.pack(
"ConstantSX::type",
'r');
156 s.pack(
"ConstantSX::value", value);
165 static CACHING_MAP<double, RealtypeSX*> cached_constants_;
167 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
168 static std::mutex mutex_cached_constants;
184 class IntegerSX :
public ConstantSX {
187 explicit IntegerSX(casadi_int value) : value(static_cast<int>(value)) {
188 casadi_assert(value<=std::numeric_limits<int>::max() &&
189 value>=std::numeric_limits<int>::min(),
"Integer overflow");
195 ~IntegerSX()
override {
196 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
198 std::lock_guard<std::mutex> lock(mutex_cached_constants);
200 size_t num_erased = cached_constants_.erase(value);
201 assert(num_erased==1);
206 inline static IntegerSX* create(casadi_int value) {
207 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
209 std::lock_guard<std::mutex> lock(mutex_cached_constants);
212 CACHING_MAP<casadi_int, IntegerSX*>::iterator it = cached_constants_.find(value);
215 if (it==cached_constants_.end()) {
217 IntegerSX* n =
new IntegerSX(value);
220 cached_constants_.insert(it, std::make_pair(value, n));
233 double to_double()
const override {
return static_cast<double>(value); }
234 casadi_int to_int()
const override {
return static_cast<casadi_int
>(value); }
240 bool is_integer()
const override {
return true; }
242 void serialize_node(SerializingStream& s)
const override {
243 s.pack(
"ConstantSX::type",
'i');
244 s.pack(
"ConstantSX::value", value);
254 static CACHING_MAP<casadi_int, IntegerSX*> cached_constants_;
256 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
257 static std::mutex mutex_cached_constants;
272 class ZeroSX :
public ConstantSX {
275 explicit ZeroSX() {this->count++;}
278 static ZeroSX* singleton() {
279 static ZeroSX instance;
283 ~ZeroSX()
override {this->count--;}
288 double to_double()
const override {
return 0;}
289 casadi_int to_int()
const override {
return 0;}
296 bool is_integer()
const override {
return true; }
297 bool is_zero()
const override {
return true; }
298 bool is_almost_zero(
double tol)
const override {
return true; }
301 void serialize_node(SerializingStream& s)
const override {
302 s.pack(
"ConstantSX::type",
'0');
313 class OneSX :
public ConstantSX {
316 explicit OneSX() {this->count++;}
319 static OneSX* singleton() {
320 static OneSX instance;
324 ~OneSX()
override {this->count--;}
328 double to_double()
const override {
return 1;}
329 casadi_int to_int()
const override {
return 1;}
334 bool is_integer()
const override {
return true; }
335 bool is_one()
const override {
return true; }
337 void serialize_node(SerializingStream& s)
const override {
338 s.pack(
"ConstantSX::type",
'1');
350 class MinusOneSX :
public ConstantSX {
353 explicit MinusOneSX() {this->count++;}
356 static MinusOneSX* singleton() {
357 static MinusOneSX instance;
361 ~MinusOneSX()
override {this->count--;}
367 double to_double()
const override {
return -1;}
368 casadi_int to_int()
const override {
return -1;}
375 bool is_integer()
const override {
return true; }
376 bool is_minus_one()
const override {
return true; }
379 void serialize_node(SerializingStream& s)
const override {
380 s.pack(
"ConstantSX::type",
'm');
392 class InfSX :
public ConstantSX {
395 explicit InfSX() {this->count++;}
398 static InfSX* singleton() {
399 static InfSX instance;
403 ~InfSX()
override {this->count--;}
407 double to_double()
const override {
return std::numeric_limits<double>::infinity();}
412 bool is_inf()
const override {
return true; }
414 void serialize_node(SerializingStream& s)
const override {
415 s.pack(
"ConstantSX::type",
'F');
427 class MinusInfSX :
public ConstantSX {
430 explicit MinusInfSX() {this->count++;}
433 static MinusInfSX* singleton() {
434 static MinusInfSX instance;
438 ~MinusInfSX()
override {this->count--;}
443 double to_double()
const override {
return -std::numeric_limits<double>::infinity();}
448 bool is_minus_inf()
const override {
return true; }
450 void serialize_node(SerializingStream& s)
const override {
451 s.pack(
"ConstantSX::type",
'f');
461 class NanSX :
public ConstantSX {
464 explicit NanSX() {this->count++;}
467 static NanSX* singleton() {
468 static NanSX instance;
472 ~NanSX()
override {this->count--;}
476 double to_double()
const override {
return std::numeric_limits<double>::quiet_NaN();}
481 bool is_nan()
const override {
return true; }
483 void serialize_node(SerializingStream& s)
const override {
484 s.pack(
"ConstantSX::type",
'n');
489 inline SXNode* ConstantSX_deserialize(DeserializingStream& s) {
491 s.unpack(
"ConstantSX::type", type);
497 s.unpack(
"ConstantSX::value", value);
498 return RealtypeSX::create(value);
502 s.unpack(
"ConstantSX::value", value);
504 return IntegerSX::create(value);
506 case 'n':
return casadi_limits<SXElem>::nan.get();
507 case 'f':
return casadi_limits<SXElem>::minus_inf.get();
508 case 'F':
return casadi_limits<SXElem>::inf.get();
510 default: casadi_error(
"ConstantSX::deserialize error");