GiNaC 1.8.8
symbol.cpp
Go to the documentation of this file.
1
5/*
6 * GiNaC Copyright (C) 1999-2025 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
Lightweight wrapper for GiNaC's symbolic objects.
Definition ex.h:73
Specialization of symbol to real positive domain.
Definition symbol.h:123
Base class for print_contexts.
Definition print.h:102
Context for latex-parsable output.
Definition print.h:122
Context for python-parsable output.
Definition print.h:138
Context for tree-like output for debugging.
Definition print.h:146
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:36
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:44
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
#define GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(classname, supername, options)
Macro for inclusion in the implementation of each registered class.
Definition registrar.h:184
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.