GiNaC  1.8.0
symbol.cpp
Go to the documentation of this file.
1 
5 /*
6  * GiNaC Copyright (C) 1999-2020 Johannes Gutenberg University Mainz, Germany
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include "symbol.h"
24 #include "lst.h"
25 #include "archive.h"
26 #include "utils.h"
27 #include "hash_seed.h"
28 #include "inifcns.h"
29 
30 #include <map>
31 #include <stdexcept>
32 #include <string>
33 
34 namespace GiNaC {
35 
38  print_func<print_latex>(&symbol::do_print_latex).
39  print_func<print_tree>(&symbol::do_print_tree).
40  print_func<print_python_repr>(&symbol::do_print_python_repr))
41 
42 // default constructor
45 
46 // symbol
47 
48 symbol::symbol() : serial(next_serial++), name(""), TeX_name("")
49 {
51 }
52 
53 // realsymbol
54 
55 realsymbol::realsymbol() : symbol() { }
56 
57 // possymbol
58 
60 
62 // other constructors
64 
65 // public
66 
67 // symbol
68 
69 symbol::symbol(const std::string & initname) : serial(next_serial++),
70  name(initname), TeX_name("")
71 {
73 }
74 
75 symbol::symbol(const std::string & initname, const std::string & texname) :
76  serial(next_serial++), name(initname), TeX_name(texname)
77 {
79 }
80 
81 // realsymbol
82 
83 realsymbol::realsymbol(const std::string & initname) : symbol(initname) { }
84 
85 realsymbol::realsymbol(const std::string & initname, const std::string & texname)
86  : symbol(initname, texname) { }
87 
88 // possymbol
89 
90 possymbol::possymbol(const std::string & initname) : realsymbol(initname) { }
91 
92 possymbol::possymbol(const std::string & initname, const std::string & texname)
93  : realsymbol(initname, texname) { }
94 
96 // archiving
98 
100 void symbol::read_archive(const archive_node &n, lst &sym_lst)
101 {
102  inherited::read_archive(n, sym_lst);
103  serial = next_serial++;
104  std::string tmp_name;
105  n.find_string("name", tmp_name);
106 
107  // If symbol is in sym_lst, return the existing symbol
108  for (auto & s : sym_lst) {
109  if (is_a<symbol>(s) && (ex_to<symbol>(s).name == tmp_name)) {
110  *this = ex_to<symbol>(s);
111  // XXX: This method is responsible for reading realsymbol
112  // and possymbol objects too. But
113  // basic::operator=(const basic& other)
114  // resets status_flags::evaluated if other and *this are
115  // of different types. Usually this is a good idea, but
116  // doing this for symbols is wrong (for one, nothing is
117  // going to set status_flags::evaluated, evaluation will
118  // loop forever). Therefore we need to restore flags.
120  return;
121  }
122  }
123  name = tmp_name;
124  if (!n.find_string("TeXname", TeX_name))
125  TeX_name = std::string("");
127 
129  sym_lst.append(*this);
130 }
131 
134 {
135  inherited::archive(n);
136  // XXX: we should not archive anonymous symbols.
137  if (!name.empty())
138  n.add_string("name", name);
139  if (!TeX_name.empty())
140  n.add_string("TeX_name", TeX_name);
141 }
142 
144 // functions overriding virtual functions from base classes
146 
148 static const std::string& get_default_TeX_name(const std::string& name);
149 
150 // public
151 
152 std::string symbol::get_name() const
153 {
154  if (name.empty()) {
155  name = "symbol" + std::to_string(serial);
156  }
157  return name;
158 }
159 
160 std::string symbol::get_TeX_name() const
161 {
162  if (TeX_name.empty()) {
163  return get_default_TeX_name(get_name());
164  }
165  return TeX_name;
166 }
167 
168 // protected
169 
170 void symbol::do_print(const print_context & c, unsigned level) const
171 {
172  c.s << get_name();
173 }
174 
175 void symbol::do_print_latex(const print_latex & c, unsigned level) const
176 {
177  if (!TeX_name.empty())
178  c.s << TeX_name;
179  else if (!name.empty())
181  else
182  c.s << "symbol" << serial;
183 }
184 
185 void symbol::do_print_tree(const print_tree & c, unsigned level) const
186 {
187  c.s << std::string(level, ' ') << name << " (" << class_name() << ")" << " @" << this
188  << ", serial=" << serial
189  << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
190  << ", domain=" << get_domain()
191  << std::endl;
192 }
193 
194 void symbol::do_print_python_repr(const print_python_repr & c, unsigned level) const
195 {
196  c.s << class_name() << "('";
197  if (!name.empty())
198  c.s << name;
199  else
200  c.s << "symbol" << serial;
201  if (!TeX_name.empty())
202  c.s << "','" << TeX_name;
203  c.s << "')";
204 }
205 
206 bool symbol::info(unsigned inf) const
207 {
208  switch (inf) {
209  case info_flags::symbol:
217  return true;
218  case info_flags::real:
222  return get_domain() == domain::positive;
224  return false;
225  }
226  return inherited::info(inf);
227 }
228 
230 {
231  return conjugate_function(*this).hold();
232 }
233 
235 {
236  return real_part_function(*this).hold();
237 }
238 
240 {
241  return imag_part_function(*this).hold();
242 }
243 
244 bool symbol::is_polynomial(const ex & var) const
245 {
246  return true;
247 }
248 
249 // protected
250 
255 ex symbol::derivative(const symbol & s) const
256 {
257  if (compare_same_type(s))
258  return _ex0;
259  else
260  return _ex1;
261 }
262 
263 int symbol::compare_same_type(const basic & other) const
264 {
265  GINAC_ASSERT(is_a<symbol>(other));
266  const symbol *o = static_cast<const symbol *>(&other);
267  if (serial==o->serial) return 0;
268  return serial < o->serial ? -1 : 1;
269 }
270 
271 bool symbol::is_equal_same_type(const basic & other) const
272 {
273  GINAC_ASSERT(is_a<symbol>(other));
274  const symbol *o = static_cast<const symbol *>(&other);
275  return serial==o->serial;
276 }
277 
278 unsigned symbol::calchash() const
279 {
280  unsigned seed = make_hash_seed(typeid(*this));
283  return hashvalue;
284 }
285 
287 // virtual functions which can be overridden by derived classes
289 
290 // none
291 
293 // non-virtual functions in this class
295 
297 static const std::string& get_default_TeX_name(const std::string& name)
298 {
299  static std::map<std::string, std::string> standard_names;
300  static bool names_initialized = false;
301  if (!names_initialized) {
302  standard_names["alpha"] = std::string("\\alpha");
303  standard_names["beta"] = std::string("\\beta");;
304  standard_names["gamma"] = std::string("\\gamma");;
305  standard_names["delta"] = std::string("\\delta");;
306  standard_names["epsilon"] = std::string("\\epsilon");
307  standard_names["varepsilon"] = std::string("\\varepsilon");
308  standard_names["zeta"] = std::string("\\zeta");
309  standard_names["eta" ] = std::string("\\eta" );
310  standard_names["theta"] = std::string("\\theta");
311  standard_names["vartheta"] = std::string("\\vartheta");
312  standard_names["iota"] = std::string("\\iota");
313  standard_names["kappa"] = std::string("\\kappa");
314  standard_names["lambda"] = std::string("\\lambda");
315  standard_names["mu"] = std::string("\\mu");
316  standard_names["nu"] = std::string("\\nu");
317  standard_names["xi"] = std::string("\\xi");
318  standard_names["omicron"] = std::string("\\omicron");
319  standard_names["pi"] = std::string("\\pi");
320  standard_names["varpi"] = std::string("\\varpi");
321  standard_names["rho"] = std::string("\\rho");
322  standard_names["varrho"] = std::string("\\varrho");
323  standard_names["sigma"] = std::string("\\sigma");
324  standard_names["varsigma"] = std::string("\\varsigma");
325  standard_names["tau"] = std::string("\\tau");
326  standard_names["upsilon"] = std::string("\\upsilon");
327  standard_names["phi"] = std::string("\\phi");
328  standard_names["varphi"] = std::string("\\varphi");
329  standard_names["chi"] = std::string("\\chi");
330  standard_names["psi"] = std::string("\\psi");
331  standard_names["omega"] = std::string("\\omega");
332  standard_names["Gamma"] = std::string("\\Gamma");
333  standard_names["Delta"] = std::string("\\Delta");
334  standard_names["Theta"] = std::string("\\Theta");
335  standard_names["Lambda"] = std::string("\\Lambda");
336  standard_names["Xi"] = std::string("\\Xi");
337  standard_names["Pi"] = std::string("\\Pi");
338  standard_names["Sigma"] = std::string("\\Sigma");
339  standard_names["Upsilon"] = std::string("\\Upsilon");
340  standard_names["Phi"] = std::string("\\Phi");
341  standard_names["Psi"] = std::string("\\Psi");
342  standard_names["Omega"] = std::string("\\Omega");
343  names_initialized = true;
344  }
345  std::map<std::string, std::string>::const_iterator it = standard_names.find(name);
346  if (it != standard_names.end())
347  return it->second;
348  else
349  return name;
350 }
351 
352 GINAC_BIND_UNARCHIVER(symbol);
353 GINAC_BIND_UNARCHIVER(realsymbol);
354 GINAC_BIND_UNARCHIVER(possymbol);
355 
357 // static member variables
359 
360 // private
361 
362 unsigned symbol::next_serial = 0;
363 
364 } // namespace GiNaC
std::string get_name() const
Definition: symbol.cpp:152
Interface to GiNaC&#39;s symbolic objects.
unsigned hashvalue
hash value
Definition: basic.h:303
bool is_equal_same_type(const basic &other) const override
Returns true if two objects of same type are equal.
Definition: symbol.cpp:271
void read_archive(const archive_node &n, lst &syms) override
Read (a.k.a.
Definition: symbol.cpp:100
void do_print(const print_context &c, unsigned level) const
Definition: symbol.cpp:170
const basic & setflag(unsigned f) const
Set some status_flags.
Definition: basic.h:288
Definition: add.cpp:38
unsigned calchash() const override
Compute the hash value of an object and if it makes sense to store it in the objects status_flags...
Definition: symbol.cpp:278
Archiving of GiNaC expressions.
This class is the ABC (abstract base class) of GiNaC&#39;s class hierarchy.
Definition: basic.h:104
const ex _ex0
Definition: utils.cpp:177
Context for python-parsable output.
Definition: print.h:138
ex derivative(const symbol &s) const override
Implementation of ex::diff() for single differentiation of a symbol.
Definition: symbol.cpp:255
virtual unsigned get_domain() const
Definition: symbol.h:71
bool info(unsigned inf) const override
Information about the object.
Definition: symbol.cpp:206
void do_print_latex(const print_latex &c, unsigned level) const
Definition: symbol.cpp:175
Interface to several small and furry utilities needed within GiNaC but not of any interest to the use...
const ex _ex1
Definition: utils.cpp:193
Context for latex-parsable output.
Definition: print.h:122
std::string name
printname of this symbol
Definition: symbol.h:89
Specialization of symbol to real domain.
Definition: symbol.h:98
print_func< print_context >(&varidx::do_print). print_func< print_latex >(&varidx
Definition: idx.cpp:45
unsigned serial
unique serial number for comparison
Definition: symbol.h:88
#define GINAC_ASSERT(X)
Assertion macro for checking invariances.
Definition: assertion.h:33
static unsigned make_hash_seed(const std::type_info &tinfo)
We need a hash function which gives different values for objects of different types.
Definition: hash_seed.h:36
ex conjugate() const override
Definition: symbol.cpp:229
GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(add, expairseq, print_func< print_context >(&add::do_print). print_func< print_latex >(&add::do_print_latex). print_func< print_csrc >(&add::do_print_csrc). print_func< print_tree >(&add::do_print_tree). print_func< print_python_repr >(&add::do_print_python_repr)) add
Definition: add.cpp:40
symbol(const std::string &initname)
Definition: symbol.cpp:69
void do_print_python_repr(const print_python_repr &c, unsigned level) const
Definition: symbol.cpp:194
std::string TeX_name
LaTeX name of this symbol.
Definition: symbol.h:90
void archive(archive_node &n) const override
Save (a.k.a.
Definition: symbol.cpp:133
unsigned golden_ratio_hash(uintptr_t n)
Truncated multiplication with golden ratio, for computing hash values.
Definition: utils.h:68
size_t n
Definition: factor.cpp:1463
Base class for print_contexts.
Definition: print.h:102
Definition of GiNaC&#39;s lst.
static unsigned next_serial
Definition: symbol.h:92
ex real_part() const override
Definition: symbol.cpp:234
This class stores all properties needed to record/retrieve the state of one object of class basic (or...
Definition: archive.h:48
Lightweight wrapper for GiNaC&#39;s symbolic objects.
Definition: ex.h:72
void do_print_tree(const print_tree &c, unsigned level) const
Definition: symbol.cpp:185
Interface to GiNaC&#39;s initially known functions.
.calchash() has already done its job
Definition: flags.h:205
Basic CAS symbol.
Definition: symbol.h:38
virtual int compare_same_type(const basic &other) const
Returns order relation between two objects of same type.
Definition: basic.cpp:719
std::string get_TeX_name() const
Definition: symbol.cpp:160
Wrapper template for making GiNaC classes out of STL containers.
Definition: container.h:73
.expand(0) has already done its job (other expand() options ignore this flag)
Definition: flags.h:204
ex imag_part() const override
Definition: symbol.cpp:239
heap-allocated (i.e. created by new if we want to be clever and bypass the stack, ...
Definition: flags.h:202
size_t c
Definition: factor.cpp:770
.eval() has already done its job
Definition: flags.h:203
Context for tree-like output for debugging.
Definition: print.h:146
unsigned flags
of type status_flags
Definition: basic.h:302
static const std::string & get_default_TeX_name(const std::string &name)
Return default TeX name for symbol.
Definition: symbol.cpp:297
GINAC_BIND_UNARCHIVER(add)
bool is_polynomial(const ex &var) const override
Check whether this is a polynomial in the given variables.
Definition: symbol.cpp:244
Type-specific hash seed.

This page is part of the GiNaC developer's reference. It was generated automatically by doxygen. For an introduction, see the tutorial.