GiNaC 1.8.10
symbol.cpp
Go to the documentation of this file.
1
5/*
6 * GiNaC Copyright (C) 1999-2026 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, see <https://www.gnu.org/licenses/>.
20 */
21
22#include "symbol.h"
23#include "lst.h"
24#include "archive.h"
25#include "utils.h"
26#include "hash_seed.h"
27#include "inifcns.h"
28
29#include <map>
30#include <stdexcept>
31#include <string>
32
33namespace GiNaC {
34
37 print_func<print_latex>(&symbol::do_print_latex).
38 print_func<print_tree>(&symbol::do_print_tree).
39 print_func<print_python_repr>(&symbol::do_print_python_repr))
40
41
42// default constructor
44
45// symbol
46
47symbol::symbol() : serial(next_serial++), name(""), TeX_name("")
48{
50}
51
52// realsymbol
53
54realsymbol::realsymbol() : symbol() { }
55
56// possymbol
57
59
61// other constructors
63
64// public
65
66// symbol
67
68symbol::symbol(const std::string & initname) : serial(next_serial++),
69 name(initname), TeX_name("")
70{
72}
73
74symbol::symbol(const std::string & initname, const std::string & texname) :
75 serial(next_serial++), name(initname), TeX_name(texname)
76{
78}
79
80// realsymbol
81
82realsymbol::realsymbol(const std::string & initname) : symbol(initname) { }
83
84realsymbol::realsymbol(const std::string & initname, const std::string & texname)
85 : symbol(initname, texname) { }
86
87// possymbol
88
89possymbol::possymbol(const std::string & initname) : realsymbol(initname) { }
90
91possymbol::possymbol(const std::string & initname, const std::string & texname)
92 : realsymbol(initname, texname) { }
93
95// archiving
97
99void symbol::read_archive(const archive_node &n, lst &sym_lst)
100{
101 inherited::read_archive(n, sym_lst);
103 std::string tmp_name;
104 n.find_string("name", tmp_name);
105
106 // If symbol is in sym_lst, return the existing symbol
107 for (auto & s : sym_lst) {
108 if (is_a<symbol>(s) && (ex_to<symbol>(s).name == tmp_name)) {
109 *this = ex_to<symbol>(s);
110 // XXX: This method is responsible for reading realsymbol
111 // and possymbol objects too. But
112 // basic::operator=(const basic& other)
113 // resets status_flags::evaluated if other and *this are
114 // of different types. Usually this is a good idea, but
115 // doing this for symbols is wrong (for one, nothing is
116 // going to set status_flags::evaluated, evaluation will
117 // loop forever). Therefore we need to restore flags.
119 return;
120 }
121 }
122 name = tmp_name;
123 if (!n.find_string("TeXname", TeX_name))
124 TeX_name = std::string("");
126
128 sym_lst.append(*this);
129}
130
133{
134 inherited::archive(n);
135 // XXX: we should not archive anonymous symbols.
136 if (!name.empty())
137 n.add_string("name", name);
138 if (!TeX_name.empty())
139 n.add_string("TeX_name", TeX_name);
140}
141
143// functions overriding virtual functions from base classes
145
147static const std::string& get_default_TeX_name(const std::string& name);
148
149// public
150
151std::string symbol::get_name() const
152{
153 if (name.empty()) {
154 name = "symbol" + std::to_string(serial);
155 }
156 return name;
157}
158
159std::string symbol::get_TeX_name() const
160{
161 if (TeX_name.empty()) {
163 }
164 return TeX_name;
165}
166
167// protected
168
169void symbol::do_print(const print_context & c, unsigned level) const
170{
171 c.s << get_name();
172}
173
174void symbol::do_print_latex(const print_latex & c, unsigned level) const
175{
176 if (!TeX_name.empty())
177 c.s << TeX_name;
178 else if (!name.empty())
180 else
181 c.s << "symbol" << serial;
182}
183
184void symbol::do_print_tree(const print_tree & c, unsigned level) const
185{
186 c.s << std::string(level, ' ') << name << " (" << class_name() << ")" << " @" << this
187 << ", serial=" << serial
188 << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
189 << ", domain=" << get_domain()
190 << std::endl;
191}
192
193void symbol::do_print_python_repr(const print_python_repr & c, unsigned level) const
194{
195 c.s << class_name() << "('";
196 if (!name.empty())
197 c.s << name;
198 else
199 c.s << "symbol" << serial;
200 if (!TeX_name.empty())
201 c.s << "','" << TeX_name;
202 c.s << "')";
203}
204
205bool symbol::info(unsigned inf) const
206{
207 switch (inf) {
216 return true;
217 case info_flags::real:
221 return get_domain() == domain::positive;
223 return false;
224 }
225 return inherited::info(inf);
226}
227
229{
230 return conjugate_function(*this).hold();
231}
232
234{
235 return real_part_function(*this).hold();
236}
237
239{
240 return imag_part_function(*this).hold();
241}
242
243bool symbol::is_polynomial(const ex & var) const
244{
245 return true;
246}
247
248// protected
249
255{
256 if (compare_same_type(s))
257 return _ex0;
258 else
259 return _ex1;
260}
261
262int symbol::compare_same_type(const basic & other) const
263{
264 GINAC_ASSERT(is_a<symbol>(other));
265 const symbol *o = static_cast<const symbol *>(&other);
266 if (serial==o->serial) return 0;
267 return serial < o->serial ? -1 : 1;
268}
269
270bool symbol::is_equal_same_type(const basic & other) const
271{
272 GINAC_ASSERT(is_a<symbol>(other));
273 const symbol *o = static_cast<const symbol *>(&other);
274 return serial==o->serial;
275}
276
277unsigned symbol::calchash() const
278{
279 unsigned seed = make_hash_seed(typeid(*this));
282 return hashvalue;
283}
284
286// virtual functions which can be overridden by derived classes
288
289// none
290
292// non-virtual functions in this class
294
296static const std::string& get_default_TeX_name(const std::string& name)
297{
298 static std::map<std::string, std::string> standard_names;
299 static bool names_initialized = false;
300 if (!names_initialized) {
301 standard_names["alpha"] = std::string("\\alpha");
302 standard_names["beta"] = std::string("\\beta");;
303 standard_names["gamma"] = std::string("\\gamma");;
304 standard_names["delta"] = std::string("\\delta");;
305 standard_names["epsilon"] = std::string("\\epsilon");
306 standard_names["varepsilon"] = std::string("\\varepsilon");
307 standard_names["zeta"] = std::string("\\zeta");
308 standard_names["eta" ] = std::string("\\eta" );
309 standard_names["theta"] = std::string("\\theta");
310 standard_names["vartheta"] = std::string("\\vartheta");
311 standard_names["iota"] = std::string("\\iota");
312 standard_names["kappa"] = std::string("\\kappa");
313 standard_names["lambda"] = std::string("\\lambda");
314 standard_names["mu"] = std::string("\\mu");
315 standard_names["nu"] = std::string("\\nu");
316 standard_names["xi"] = std::string("\\xi");
317 standard_names["omicron"] = std::string("\\omicron");
318 standard_names["pi"] = std::string("\\pi");
319 standard_names["varpi"] = std::string("\\varpi");
320 standard_names["rho"] = std::string("\\rho");
321 standard_names["varrho"] = std::string("\\varrho");
322 standard_names["sigma"] = std::string("\\sigma");
323 standard_names["varsigma"] = std::string("\\varsigma");
324 standard_names["tau"] = std::string("\\tau");
325 standard_names["upsilon"] = std::string("\\upsilon");
326 standard_names["phi"] = std::string("\\phi");
327 standard_names["varphi"] = std::string("\\varphi");
328 standard_names["chi"] = std::string("\\chi");
329 standard_names["psi"] = std::string("\\psi");
330 standard_names["omega"] = std::string("\\omega");
331 standard_names["Gamma"] = std::string("\\Gamma");
332 standard_names["Delta"] = std::string("\\Delta");
333 standard_names["Theta"] = std::string("\\Theta");
334 standard_names["Lambda"] = std::string("\\Lambda");
335 standard_names["Xi"] = std::string("\\Xi");
336 standard_names["Pi"] = std::string("\\Pi");
337 standard_names["Sigma"] = std::string("\\Sigma");
338 standard_names["Upsilon"] = std::string("\\Upsilon");
339 standard_names["Phi"] = std::string("\\Phi");
340 standard_names["Psi"] = std::string("\\Psi");
341 standard_names["Omega"] = std::string("\\Omega");
342 names_initialized = true;
343 }
344 std::map<std::string, std::string>::const_iterator it = standard_names.find(name);
345 if (it != standard_names.end())
346 return it->second;
347 else
348 return name;
349}
350
354
356// static member variables
358
359// private
360
361unsigned symbol::next_serial = 0;
362
363} // namespace GiNaC
Archiving of GiNaC expressions.
#define GINAC_ASSERT(X)
Assertion macro for checking invariances.
Definition assertion.h:32
This class stores all properties needed to record/retrieve the state of one object of class basic (or...
Definition archive.h:48
This class is the ABC (abstract base class) of GiNaC's class hierarchy.
Definition basic.h:104
const basic & setflag(unsigned f) const
Set some status_flags.
Definition basic.h:287
unsigned hashvalue
hash value
Definition basic.h:302
unsigned flags
of type status_flags
Definition basic.h:301
virtual int compare_same_type(const basic &other) const
Returns order relation between two objects of same type.
Definition basic.cpp:718
Wrapper template for making GiNaC classes out of STL containers.
Definition container.h:72
container & append(const ex &b)
Add element at back.
Definition container.h:390
Lightweight wrapper for GiNaC's symbolic objects.
Definition ex.h:72
Specialization of symbol to real positive domain.
Definition symbol.h:122
Base class for print_contexts.
Definition print.h:101
Context for latex-parsable output.
Definition print.h:121
Context for python-parsable output.
Definition print.h:137
Context for tree-like output for debugging.
Definition print.h:145
Specialization of symbol to real domain.
Definition symbol.h:98
@ expanded
.expand(0) has already done its job (other expand() options ignore this flag)
Definition flags.h:203
@ evaluated
.eval() has already done its job
Definition flags.h:202
@ dynallocated
heap-allocated (i.e. created by new if we want to be clever and bypass the stack,
Definition flags.h:201
@ hash_calculated
.calchash() has already done its job
Definition flags.h:204
Basic CAS symbol.
Definition symbol.h:38
unsigned serial
unique serial number for comparison
Definition symbol.h:87
std::string TeX_name
LaTeX name of this symbol.
Definition symbol.h:89
void read_archive(const archive_node &n, lst &syms) override
Read (a.k.a.
Definition symbol.cpp:99
static unsigned next_serial
Definition symbol.h:91
symbol(const std::string &initname)
Definition symbol.cpp:68
bool is_polynomial(const ex &var) const override
Check whether this is a polynomial in the given variables.
Definition symbol.cpp:243
virtual unsigned get_domain() const
Definition symbol.h:70
void do_print_python_repr(const print_python_repr &c, unsigned level) const
Definition symbol.cpp:193
bool is_equal_same_type(const basic &other) const override
Returns true if two objects of same type are equal.
Definition symbol.cpp:270
std::string get_TeX_name() const
Definition symbol.cpp:159
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:277
ex real_part() const override
Definition symbol.cpp:233
void do_print(const print_context &c, unsigned level) const
Definition symbol.cpp:169
void do_print_tree(const print_tree &c, unsigned level) const
Definition symbol.cpp:184
ex conjugate() const override
Definition symbol.cpp:228
void archive(archive_node &n) const override
Save (a.k.a.
Definition symbol.cpp:132
ex derivative(const symbol &s) const override
Implementation of ex::diff() for single differentiation of a symbol.
Definition symbol.cpp:254
void do_print_latex(const print_latex &c, unsigned level) const
Definition symbol.cpp:174
std::string name
printname of this symbol
Definition symbol.h:88
bool info(unsigned inf) const override
Information about the object.
Definition symbol.cpp:205
std::string get_name() const
Definition symbol.cpp:151
ex imag_part() const override
Definition symbol.cpp:238
size_t n
Definition factor.cpp:1431
size_t c
Definition factor.cpp:756
Type-specific hash seed.
Interface to GiNaC's initially known functions.
Definition of GiNaC's lst.
Definition add.cpp:35
unsigned golden_ratio_hash(uintptr_t n)
Truncated multiplication with golden ratio, for computing hash values.
Definition utils.h:67
static const std::string & get_default_TeX_name(const std::string &name)
Return default TeX name for symbol.
Definition symbol.cpp:296
const ex _ex1
Definition utils.cpp:384
print_func< print_context >(&varidx::do_print). print_func< print_latex >(&varidx
Definition idx.cpp:43
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:41
const ex _ex0
Definition utils.cpp:368
#define GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(classname, supername, options)
Macro for inclusion in the implementation of each registered class.
Definition registrar.h:183
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.