sbml.cpp
1 #include <symengine/printers/sbml.h>
2 #include <symengine/printers.h>
3 
4 namespace SymEngine
5 {
6 
7 static std::vector<std::string> init_sbml_printer_names()
8 {
9  std::vector<std::string> names = init_str_printer_names();
10  names[SYMENGINE_LOG] = "ln";
11  names[SYMENGINE_ASIN] = "arcsin";
12  names[SYMENGINE_ACOS] = "arccos";
13  names[SYMENGINE_ASEC] = "arcsec";
14  names[SYMENGINE_ACSC] = "arccsc";
15  names[SYMENGINE_ATAN] = "arctan";
16  names[SYMENGINE_ACOT] = "arccot";
17  names[SYMENGINE_ASINH] = "arcsinh";
18  names[SYMENGINE_ACSCH] = "arccsch";
19  names[SYMENGINE_ACOSH] = "arccosh";
20  names[SYMENGINE_ATANH] = "arctanh";
21  names[SYMENGINE_ACOTH] = "arccoth";
22  names[SYMENGINE_ASECH] = "arcsech";
23  return names;
24 }
25 
26 const std::vector<std::string> SbmlPrinter::names_ = init_sbml_printer_names();
27 
28 void SbmlPrinter::_print_pow(std::ostringstream &o, const RCP<const Basic> &a,
29  const RCP<const Basic> &b)
30 {
31  if (eq(*a, *E)) {
32  o << "exp(" << apply(b) << ")";
33  } else if (eq(*b, *rational(1, 2))) {
34  o << "sqrt(" << apply(a) << ")";
35  } else {
36  o << parenthesizeLE(a, PrecedenceEnum::Pow);
37  o << "^";
38  o << parenthesizeLE(b, PrecedenceEnum::Pow);
39  }
40 }
41 
42 void SbmlPrinter::bvisit(const BooleanAtom &x)
43 {
44  if (x.get_val()) {
45  str_ = "true";
46  } else {
47  str_ = "false";
48  }
49 }
50 
51 void SbmlPrinter::bvisit(const And &x)
52 {
54  const auto &container = x.get_container();
55  s << "and(";
56  s << apply(*container.begin());
57  for (auto it = ++(container.begin()); it != container.end(); ++it) {
58  s << ", " << apply(*it);
59  }
60  s << ")";
61  str_ = s.str();
62 }
63 
64 void SbmlPrinter::bvisit(const Or &x)
65 {
67  const auto &container = x.get_container();
68  s << "or(";
69  s << apply(*container.begin());
70  for (auto it = ++(container.begin()); it != container.end(); ++it) {
71  s << ", " << apply(*it);
72  }
73  s << ")";
74  str_ = s.str();
75 }
76 
77 void SbmlPrinter::bvisit(const Xor &x)
78 {
80  const auto &container = x.get_container();
81  s << "xor(";
82  s << apply(*container.begin());
83  for (auto it = ++(container.begin()); it != container.end(); ++it) {
84  s << ", " << apply(*it);
85  }
86  s << ")";
87  str_ = s.str();
88 }
89 
90 void SbmlPrinter::bvisit(const Not &x)
91 {
93  s << "not(" << *x.get_arg() << ")";
94  str_ = s.str();
95 }
96 
97 void SbmlPrinter::bvisit(const Piecewise &x)
98 {
100  auto vec = x.get_vec();
101  auto it = vec.begin();
102  s << "piecewise(";
103  while (it != vec.end()) {
104  s << apply((*it).first);
105  s << ", ";
106  s << apply((*it).second);
107  ++it;
108  if (it != vec.end()) {
109  s << ", ";
110  }
111  }
112  s << ")";
113  str_ = s.str();
114 }
115 
116 void SbmlPrinter::bvisit(const Infty &x)
117 {
118  str_ = "inf";
119 }
120 
121 void SbmlPrinter::bvisit(const Constant &x)
122 {
123  if (eq(x, *E)) {
124  str_ = "exponentiale";
125  } else {
126  str_ = x.get_name();
127  std::transform(str_.begin(), str_.end(), str_.begin(), ::tolower);
128  }
129 }
130 
131 void SbmlPrinter::bvisit(const Function &x)
132 {
134  vec_basic vec = x.get_args();
135  if (x.get_type_code() == SYMENGINE_GAMMA) {
136  // sbml only has factorial, no gamma function
137  o << "factorial(" << apply(vec) << " - 1)";
138  } else if (x.get_type_code() == SYMENGINE_LOG && vec.size() == 2) {
139  // sbml log has order of arguments inverted
140  o << "log(" << apply(vec[1]) << ", " << apply(vec[0]) << ")";
141  } else {
142  o << names_[x.get_type_code()];
143  o << parenthesize(apply(vec));
144  }
145  str_ = o.str();
146 }
147 
148 std::string sbml(const Basic &x)
149 {
150  SbmlPrinter m;
151  return m.apply(x);
152 }
153 
154 } // namespace SymEngine
T begin(T... args)
T end(T... args)
Main namespace for SymEngine package.
Definition: add.cpp:19
bool eq(const Basic &a, const Basic &b)
Checks equality for a and b
Definition: basic-inl.h:21
RCP< const Number > rational(long n, long d)
convenience creator from two longs
Definition: rational.h:328
T str(T... args)
T transform(T... args)