26 #ifndef CASADI_CONSTANT_SX_HPP
27 #define CASADI_CONSTANT_SX_HPP
29 #include "sx_node.hpp"
30 #include "serializing_stream.hpp"
31 #include "matrix_decl.hpp"
37 #include <unordered_map>
38 #define CACHING_MAP std::unordered_map
48 class ConstantSX :
public SXNode {
52 ~ConstantSX()
override {}
55 std::string class_name()
const override {
return "ConstantSX";}
60 double to_double()
const override = 0;
65 bool is_constant()
const override {
return true; }
70 casadi_int op()
const override {
return OP_CONST;}
75 bool is_value(
double v)
const override {
84 bool is_equal(
const SXNode* node, casadi_int depth)
const override {
85 const ConstantSX* n =
dynamic_cast<const ConstantSX*
>(node);
86 return n && n->to_double()==to_double();
94 std::string print(
const std::string& arg1,
const std::string& arg2)
const override {
99 ss.setf(std::ios::scientific);
101 ss.unsetf(std::ios::scientific);
119 class RealtypeSX :
public ConstantSX {
122 explicit RealtypeSX(
double value) : value(value) {}
127 ~RealtypeSX()
override {
128 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
130 std::lock_guard<std::mutex> lock(mutex_cached_constants);
132 size_t num_erased = cached_constants_.erase(value);
133 assert(num_erased==1);
138 inline static RealtypeSX* create(
double value) {
139 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
141 std::lock_guard<std::mutex> lock(mutex_cached_constants);
144 CACHING_MAP<double, RealtypeSX*>::iterator it = cached_constants_.find(value);
147 if (it==cached_constants_.end()) {
149 RealtypeSX* n =
new RealtypeSX(value);
152 cached_constants_.insert(it, std::make_pair(value, n));
165 double to_double()
const override {
return value;}
166 casadi_int to_int()
const override {
return static_cast<casadi_int
>(value);}
169 bool is_almost_zero(
double tol)
const override {
return fabs(value)<=tol; }
171 void serialize_node(SerializingStream& s)
const override {
172 s.pack(
"ConstantSX::type",
'r');
173 s.pack(
"ConstantSX::value", value);
182 static CACHING_MAP<double, RealtypeSX*> cached_constants_;
184 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
185 static std::mutex mutex_cached_constants;
201 class IntegerSX :
public ConstantSX {
204 explicit IntegerSX(casadi_int value) : value(static_cast<int>(value)) {
205 casadi_assert(value<=std::numeric_limits<int>::max() &&
206 value>=std::numeric_limits<int>::min(),
"Integer overflow");
212 ~IntegerSX()
override {
213 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
215 std::lock_guard<std::mutex> lock(mutex_cached_constants);
217 size_t num_erased = cached_constants_.erase(value);
218 assert(num_erased==1);
223 inline static IntegerSX* create(casadi_int value) {
224 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
226 std::lock_guard<std::mutex> lock(mutex_cached_constants);
229 CACHING_MAP<casadi_int, IntegerSX*>::iterator it = cached_constants_.find(value);
232 if (it==cached_constants_.end()) {
234 IntegerSX* n =
new IntegerSX(value);
237 cached_constants_.insert(it, std::make_pair(value, n));
250 double to_double()
const override {
return static_cast<double>(value); }
251 casadi_int to_int()
const override {
return static_cast<casadi_int
>(value); }
257 bool is_integer()
const override {
return true; }
259 void serialize_node(SerializingStream& s)
const override {
260 s.pack(
"ConstantSX::type",
'i');
261 s.pack(
"ConstantSX::value", value);
271 static CACHING_MAP<casadi_int, IntegerSX*> cached_constants_;
273 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
274 static std::mutex mutex_cached_constants;
289 class ZeroSX :
public ConstantSX {
292 explicit ZeroSX() {this->count++;}
295 static ZeroSX* singleton() {
296 static ZeroSX instance;
300 ~ZeroSX()
override {this->count--;}
305 double to_double()
const override {
return 0;}
306 casadi_int to_int()
const override {
return 0;}
313 bool is_integer()
const override {
return true; }
314 bool is_zero()
const override {
return true; }
315 bool is_almost_zero(
double tol)
const override {
return true; }
318 void serialize_node(SerializingStream& s)
const override {
319 s.pack(
"ConstantSX::type",
'0');
330 class OneSX :
public ConstantSX {
333 explicit OneSX() {this->count++;}
336 static OneSX* singleton() {
337 static OneSX instance;
341 ~OneSX()
override {this->count--;}
345 double to_double()
const override {
return 1;}
346 casadi_int to_int()
const override {
return 1;}
351 bool is_integer()
const override {
return true; }
352 bool is_one()
const override {
return true; }
354 void serialize_node(SerializingStream& s)
const override {
355 s.pack(
"ConstantSX::type",
'1');
367 class MinusOneSX :
public ConstantSX {
370 explicit MinusOneSX() {this->count++;}
373 static MinusOneSX* singleton() {
374 static MinusOneSX instance;
378 ~MinusOneSX()
override {this->count--;}
384 double to_double()
const override {
return -1;}
385 casadi_int to_int()
const override {
return -1;}
392 bool is_integer()
const override {
return true; }
393 bool is_minus_one()
const override {
return true; }
396 void serialize_node(SerializingStream& s)
const override {
397 s.pack(
"ConstantSX::type",
'm');
409 class InfSX :
public ConstantSX {
412 explicit InfSX() {this->count++;}
415 static InfSX* singleton() {
416 static InfSX instance;
420 ~InfSX()
override {this->count--;}
424 double to_double()
const override {
return std::numeric_limits<double>::infinity();}
429 bool is_inf()
const override {
return true; }
431 void serialize_node(SerializingStream& s)
const override {
432 s.pack(
"ConstantSX::type",
'F');
444 class MinusInfSX :
public ConstantSX {
447 explicit MinusInfSX() {this->count++;}
450 static MinusInfSX* singleton() {
451 static MinusInfSX instance;
455 ~MinusInfSX()
override {this->count--;}
460 double to_double()
const override {
return -std::numeric_limits<double>::infinity();}
465 bool is_minus_inf()
const override {
return true; }
467 void serialize_node(SerializingStream& s)
const override {
468 s.pack(
"ConstantSX::type",
'f');
478 class NanSX :
public ConstantSX {
481 explicit NanSX() {this->count++;}
484 static NanSX* singleton() {
485 static NanSX instance;
489 ~NanSX()
override {this->count--;}
493 double to_double()
const override {
return std::numeric_limits<double>::quiet_NaN();}
498 bool is_nan()
const override {
return true; }
500 void serialize_node(SerializingStream& s)
const override {
501 s.pack(
"ConstantSX::type",
'n');
506 inline SXNode* ConstantSX_deserialize(DeserializingStream& s) {
508 s.unpack(
"ConstantSX::type", type);
514 s.unpack(
"ConstantSX::value", value);
515 return RealtypeSX::create(value);
519 s.unpack(
"ConstantSX::value", value);
521 return IntegerSX::create(value);
523 case 'n':
return casadi_limits<SXElem>::nan.get();
524 case 'f':
return casadi_limits<SXElem>::minus_inf.get();
525 case 'F':
return casadi_limits<SXElem>::inf.get();
527 default: casadi_error(
"ConstantSX::deserialize error");
static casadi_int get_precision()
Get the 'precision, width & scientific' used in printing and serializing to streams.
static casadi_int get_width()
static bool get_scientific()
static bool is_half(const T &val)
static bool is_integer(const T &val)
static bool is_value(const T &val, T v)