GiNaC 1.8.7
symbol.cpp
Go to the documentation of this file.
1
5/*
6 * GiNaC Copyright (C) 1999-2023 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
34namespace 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
43// default constructor
45
46// symbol
47
48symbol::symbol() : serial(next_serial++), name(""), TeX_name("")
49{
51}
52
53// realsymbol
54
55realsymbol::realsymbol() : symbol() { }
56
57// possymbol
58
60
62// other constructors
64
65// public
66
67// symbol
68
69symbol::symbol(const std::string & initname) : serial(next_serial++),
70 name(initname), TeX_name("")
71{
73}
74
75symbol::symbol(const std::string & initname, const std::string & texname) :
76 serial(next_serial++), name(initname), TeX_name(texname)
77{
79}
80
81// realsymbol
82
83realsymbol::realsymbol(const std::string & initname) : symbol(initname) { }
84
85realsymbol::realsymbol(const std::string & initname, const std::string & texname)
86 : symbol(initname, texname) { }
87
88// possymbol
89
90possymbol::possymbol(const std::string & initname) : realsymbol(initname) { }
91
92possymbol::possymbol(const std::string & initname, const std::string & texname)
93 : realsymbol(initname, texname) { }
94
96// archiving
98
101{
102 inherited::read_archive(n, sym_lst);
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
148static const std::string& get_default_TeX_name(const std::string& name);
149
150// public
151
152std::string symbol::get_name() const
153{
154 if (name.empty()) {
155 name = "symbol" + std::to_string(serial);
156 }
157 return name;
158}
159
160std::string symbol::get_TeX_name() const
161{
162 if (TeX_name.empty()) {
164 }
165 return TeX_name;
166}
167
168// protected
169
170void symbol::do_print(const print_context & c, unsigned level) const
171{
172 c.s << get_name();
173}
174
175void 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
185void 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
194void 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
206bool symbol::info(unsigned inf) const
207{
208 switch (inf) {
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
244bool symbol::is_polynomial(const ex & var) const
245{
246 return true;
247}
248
249// protected
250
256{
257 if (compare_same_type(s))
258 return _ex0;
259 else
260 return _ex1;
261}
262
263int 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
271bool 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
278unsigned 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
297static 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
355
357// static member variables
359
360// private
361
362unsigned symbol::next_serial = 0;
363
364} // namespace GiNaC
Archiving of GiNaC expressions.
#define GINAC_ASSERT(X)
Assertion macro for checking invariances.
Definition: assertion.h:33
This class stores all properties needed to record/retrieve the state of one object of class basic (or...
Definition: archive.h:49
This class is the ABC (abstract base class) of GiNaC's class hierarchy.
Definition: basic.h:105
const basic & setflag(unsigned f) const
Set some status_flags.
Definition: basic.h:288
unsigned hashvalue
hash value
Definition: basic.h:303
unsigned flags
of type status_flags
Definition: basic.h:302
virtual int compare_same_type(const basic &other) const
Returns order relation between two objects of same type.
Definition: basic.cpp:719
Wrapper template for making GiNaC classes out of STL containers.
Definition: container.h:73
container & append(const ex &b)
Add element at back.
Definition: container.h:391
@ positive
Definition: flags.h:71
Lightweight wrapper for GiNaC's symbolic objects.
Definition: ex.h:72
@ integer_polynomial
Definition: flags.h:256
@ cinteger_polynomial
Definition: flags.h:257
@ crational_polynomial
Definition: flags.h:259
@ rational_polynomial
Definition: flags.h:258
Specialization of symbol to real positive domain.
Definition: symbol.h:123
Base class for print_contexts.
Definition: print.h:103
Context for latex-parsable output.
Definition: print.h:123
Context for python-parsable output.
Definition: print.h:139
Context for tree-like output for debugging.
Definition: print.h:147
Specialization of symbol to real domain.
Definition: symbol.h:99
@ expanded
.expand(0) has already done its job (other expand() options ignore this flag)
Definition: flags.h:204
@ evaluated
.eval() has already done its job
Definition: flags.h:203
@ dynallocated
heap-allocated (i.e. created by new if we want to be clever and bypass the stack,
Definition: flags.h:202
@ hash_calculated
.calchash() has already done its job
Definition: flags.h:205
Basic CAS symbol.
Definition: symbol.h:39
unsigned serial
unique serial number for comparison
Definition: symbol.h:88
std::string TeX_name
LaTeX name of this symbol.
Definition: symbol.h:90
void read_archive(const archive_node &n, lst &syms) override
Read (a.k.a.
Definition: symbol.cpp:100
static unsigned next_serial
Definition: symbol.h:92
symbol(const std::string &initname)
Definition: symbol.cpp:69
bool is_polynomial(const ex &var) const override
Check whether this is a polynomial in the given variables.
Definition: symbol.cpp:244
virtual unsigned get_domain() const
Definition: symbol.h:71
void do_print_python_repr(const print_python_repr &c, unsigned level) const
Definition: symbol.cpp:194
bool is_equal_same_type(const basic &other) const override
Returns true if two objects of same type are equal.
Definition: symbol.cpp:271
std::string get_TeX_name() const
Definition: symbol.cpp:160
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
ex real_part() const override
Definition: symbol.cpp:234
void do_print(const print_context &c, unsigned level) const
Definition: symbol.cpp:170
void do_print_tree(const print_tree &c, unsigned level) const
Definition: symbol.cpp:185
ex conjugate() const override
Definition: symbol.cpp:229
void archive(archive_node &n) const override
Save (a.k.a.
Definition: symbol.cpp:133
ex derivative(const symbol &s) const override
Implementation of ex::diff() for single differentiation of a symbol.
Definition: symbol.cpp:255
void do_print_latex(const print_latex &c, unsigned level) const
Definition: symbol.cpp:175
std::string name
printname of this symbol
Definition: symbol.h:89
bool info(unsigned inf) const override
Information about the object.
Definition: symbol.cpp:206
std::string get_name() const
Definition: symbol.cpp:152
ex imag_part() const override
Definition: symbol.cpp:239
size_t n
Definition: factor.cpp:1432
size_t c
Definition: factor.cpp:757
Type-specific hash seed.
Interface to GiNaC's initially known functions.
Definition of GiNaC's lst.
Definition: add.cpp:38
unsigned golden_ratio_hash(uintptr_t n)
Truncated multiplication with golden ratio, for computing hash values.
Definition: utils.h:68
static const std::string & get_default_TeX_name(const std::string &name)
Return default TeX name for symbol.
Definition: symbol.cpp:297
const ex _ex1
Definition: utils.cpp:385
print_func< print_context >(&varidx::do_print). print_func< print_latex >(&varidx
Definition: idx.cpp:45
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
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
GINAC_IMPLEMENT_REGISTERED_CLASS_OPT_T(lst, basic, print_func< print_context >(&lst::do_print). print_func< print_tree >(&lst::do_print_tree)) template<> bool lst GINAC_BIND_UNARCHIVER(lst)
Specialization of container::info() for lst.
Definition: lst.cpp:42
const ex _ex0
Definition: utils.cpp:369
Interface to GiNaC's symbolic objects.
Interface to several small and furry utilities needed within GiNaC but not of any interest to the use...

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