GiNaC 1.8.10
operators.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 "operators.h"
23#include "numeric.h"
24#include "add.h"
25#include "mul.h"
26#include "power.h"
27#include "ncmul.h"
28#include "relational.h"
29#include "print.h"
30#include "utils.h"
31
32namespace GiNaC {
33
35static inline const ex exadd(const ex & lh, const ex & rh)
36{
37 return dynallocate<add>(lh, rh);
38}
39
41static inline const ex exmul(const ex & lh, const ex & rh)
42{
43 // Check if we are constructing a mul object or a ncmul object. Due to
44 // ncmul::eval()'s rule to pull out commutative elements we need to check
45 // only one of the elements.
48 return dynallocate<mul>(lh, rh);
49 } else {
50 return dynallocate<ncmul>(lh, rh);
51 }
52}
53
55static inline const ex exminus(const ex & lh)
56{
57 return dynallocate<mul>(lh, _ex_1);
58}
59
60// binary arithmetic operators ex with ex
61
62const ex operator+(const ex & lh, const ex & rh)
63{
64 return exadd(lh, rh);
65}
66
67const ex operator-(const ex & lh, const ex & rh)
68{
69 return exadd(lh, exminus(rh));
70}
71
72const ex operator*(const ex & lh, const ex & rh)
73{
74 return exmul(lh, rh);
75}
76
77const ex operator/(const ex & lh, const ex & rh)
78{
79 return exmul(lh, power(rh,_ex_1));
80}
81
82
83// binary arithmetic operators numeric with numeric
84
85const numeric operator+(const numeric & lh, const numeric & rh)
86{
87 return lh.add(rh);
88}
89
90const numeric operator-(const numeric & lh, const numeric & rh)
91{
92 return lh.sub(rh);
93}
94
95const numeric operator*(const numeric & lh, const numeric & rh)
96{
97 return lh.mul(rh);
98}
99
100const numeric operator/(const numeric & lh, const numeric & rh)
101{
102 return lh.div(rh);
103}
104
105
106// binary arithmetic assignment operators with ex
107
108ex & operator+=(ex & lh, const ex & rh)
109{
110 return lh = exadd(lh, rh);
111}
112
113ex & operator-=(ex & lh, const ex & rh)
114{
115 return lh = exadd(lh, exminus(rh));
116}
117
118ex & operator*=(ex & lh, const ex & rh)
119{
120 return lh = exmul(lh, rh);
121}
122
123ex & operator/=(ex & lh, const ex & rh)
124{
125 return lh = exmul(lh, power(rh,_ex_1));
126}
127
128
129// binary arithmetic assignment operators with numeric
130
132{
133 lh = lh.add(rh);
134 return lh;
135}
136
138{
139 lh = lh.sub(rh);
140 return lh;
141}
142
144{
145 lh = lh.mul(rh);
146 return lh;
147}
148
150{
151 lh = lh.div(rh);
152 return lh;
153}
154
155
156// unary operators
157
158const ex operator+(const ex & lh)
159{
160 return lh;
161}
162
163const ex operator-(const ex & lh)
164{
165 return exminus(lh);
166}
167
168const numeric operator+(const numeric & lh)
169{
170 return lh;
171}
172
173const numeric operator-(const numeric & lh)
174{
175 return _num_1_p->mul(lh);
176}
177
178
179// increment / decrement operators
180
183{
184 return rh = exadd(rh, _ex1);
185}
186
189{
190 return rh = exadd(rh, _ex_1);
191}
192
195const ex operator++(ex & lh, int)
196{
197 ex tmp(lh);
198 lh = exadd(lh, _ex1);
199 return tmp;
200}
201
204const ex operator--(ex & lh, int)
205{
206 ex tmp(lh);
207 lh = exadd(lh, _ex_1);
208 return tmp;
209}
210
213{
214 rh = rh.add(*_num1_p);
215 return rh;
216}
217
220{
221 rh = rh.add(*_num_1_p);
222 return rh;
223}
224
227const numeric operator++(numeric & lh, int)
228{
229 numeric tmp(lh);
230 lh = lh.add(*_num1_p);
231 return tmp;
232}
233
236const numeric operator--(numeric & lh, int)
237{
238 numeric tmp(lh);
239 lh = lh.add(*_num_1_p);
240 return tmp;
241}
242
243// binary relational operators ex with ex
244
245const relational operator==(const ex & lh, const ex & rh)
246{
247 return relational(lh, rh, relational::equal);
248}
249
250const relational operator!=(const ex & lh, const ex & rh)
251{
252 return relational(lh, rh, relational::not_equal);
253}
254
255const relational operator<(const ex & lh, const ex & rh)
256{
257 return relational(lh, rh, relational::less);
258}
259
260const relational operator<=(const ex & lh, const ex & rh)
261{
263}
264
265const relational operator>(const ex & lh, const ex & rh)
266{
267 return relational(lh, rh, relational::greater);
268}
269
270const relational operator>=(const ex & lh, const ex & rh)
271{
273}
274
275// input/output stream operators and manipulators
276
277static int my_ios_index()
278{
279 static int i = std::ios_base::xalloc();
280 return i;
281}
282
283// Stream format gets copied or destroyed
284static void my_ios_callback(std::ios_base::event ev, std::ios_base & s, int i)
285{
286 print_context *p = static_cast<print_context *>(s.pword(i));
287 if (ev == std::ios_base::erase_event) {
288 delete p;
289 s.pword(i) = nullptr;
290 } else if (ev == std::ios_base::copyfmt_event && p != nullptr)
291 s.pword(i) = p->duplicate();
292}
293
294enum {
297
298// Get print_context associated with stream, may return 0 if no context has
299// been associated yet
300static inline print_context *get_print_context(std::ios_base & s)
301{
302 return static_cast<print_context *>(s.pword(my_ios_index()));
303}
304
305// Set print_context associated with stream, retain options
306static void set_print_context(std::ios_base & s, const print_context & c)
307{
308 int i = my_ios_index();
309 long flags = s.iword(i);
310 if (!(flags & callback_registered)) {
311 s.register_callback(my_ios_callback, i);
312 s.iword(i) = flags | callback_registered;
313 }
314 print_context *p = static_cast<print_context *>(s.pword(i));
315 unsigned options = p ? p->options : c.options;
316 delete p;
317 p = c.duplicate();
318 p->options = options;
319 s.pword(i) = p;
320}
321
322// Get options for print_context associated with stream
323static inline unsigned get_print_options(std::ios_base & s)
324{
326 return p ? p->options : 0;
327}
328
329// Set options for print_context associated with stream
330static void set_print_options(std::ostream & s, unsigned options)
331{
333 if (p == nullptr)
335 else
336 p->options = options;
337}
338
339std::ostream & operator<<(std::ostream & os, const ex & e)
340{
342 if (p == nullptr)
343 e.print(print_dflt(os));
344 else
345 e.print(*p);
346 return os;
347}
348
349std::ostream & operator<<(std::ostream & os, const exvector & e)
350{
352 auto i = e.begin();
353 auto vend = e.end();
354
355 if (i==vend) {
356 os << "[]";
357 return os;
358 }
359
360 os << "[";
361 while (true) {
362 if (p == nullptr)
363 i -> print(print_dflt(os));
364 else
365 i -> print(*p);
366 ++i;
367 if (i==vend)
368 break;
369 os << ",";
370 }
371 os << "]";
372
373 return os;
374}
375
376std::ostream & operator<<(std::ostream & os, const exset & e)
377{
379 auto i = e.begin();
380 auto send = e.end();
381
382 if (i==send) {
383 os << "<>";
384 return os;
385 }
386
387 os << "<";
388 while (true) {
389 if (p == nullptr)
390 i->print(print_dflt(os));
391 else
392 i->print(*p);
393 ++i;
394 if (i == send)
395 break;
396 os << ",";
397 }
398 os << ">";
399
400 return os;
401}
402
403std::ostream & operator<<(std::ostream & os, const exmap & e)
404{
406 auto i = e.begin();
407 auto mend = e.end();
408
409 if (i==mend) {
410 os << "{}";
411 return os;
412 }
413
414 os << "{";
415 while (true) {
416 if (p == nullptr)
417 i->first.print(print_dflt(os));
418 else
419 i->first.print(*p);
420 os << "==";
421 if (p == nullptr)
422 i->second.print(print_dflt(os));
423 else
424 i->second.print(*p);
425 ++i;
426 if( i==mend )
427 break;
428 os << ",";
429 }
430 os << "}";
431
432 return os;
433}
434
435std::istream & operator>>(std::istream & is, ex & e)
436{
437 throw (std::logic_error("expression input from streams not implemented"));
438}
439
440std::ostream & dflt(std::ostream & os)
441{
443 set_print_options(os, 0);
444 return os;
445}
446
447std::ostream & latex(std::ostream & os)
448{
450 return os;
451}
452
453std::ostream & python(std::ostream & os)
454{
456 return os;
457}
458
459std::ostream & python_repr(std::ostream & os)
460{
462 return os;
463}
464
465std::ostream & tree(std::ostream & os)
466{
468 return os;
469}
470
471std::ostream & csrc(std::ostream & os)
472{
474 return os;
475}
476
477std::ostream & csrc_float(std::ostream & os)
478{
480 return os;
481}
482
483std::ostream & csrc_double(std::ostream & os)
484{
486 return os;
487}
488
489std::ostream & csrc_cl_N(std::ostream & os)
490{
492 return os;
493}
494
495std::ostream & index_dimensions(std::ostream & os)
496{
498 return os;
499}
500
501std::ostream & no_index_dimensions(std::ostream & os)
502{
504 return os;
505}
506
507} // namespace GiNaC
Interface to GiNaC's sums of expressions.
Lightweight wrapper for GiNaC's symbolic objects.
Definition ex.h:72
unsigned return_type() const
Definition ex.h:230
void print(const print_context &c, unsigned level=0) const
Print expression to stream.
Definition ex.cpp:54
This class is a wrapper around CLN-numbers within the GiNaC class hierarchy.
Definition numeric.h:81
const numeric sub(const numeric &other) const
Numerical subtraction method.
Definition numeric.cpp:871
const numeric mul(const numeric &other) const
Numerical multiplication method.
Definition numeric.cpp:879
const numeric add(const numeric &other) const
Numerical addition method.
Definition numeric.cpp:863
const numeric div(const numeric &other) const
Numerical division method.
Definition numeric.cpp:889
This class holds a two-component object, a basis and and exponent representing exponentiation.
Definition power.h:38
Base class for print_contexts.
Definition print.h:101
unsigned options
option flags
Definition print.h:108
Context for C source output using CLN numbers.
Definition print.h:180
Context for C source output using double precision.
Definition print.h:172
Context for C source output using float precision.
Definition print.h:164
Context for default (ginsh-parsable) output.
Definition print.h:113
Context for latex-parsable output.
Definition print.h:121
@ print_index_dimensions
print the dimensions of indices
Definition print.h:55
Context for python-parsable output.
Definition print.h:137
Context for python pretty-print output.
Definition print.h:129
Context for tree-like output for debugging.
Definition print.h:145
This class holds a relation consisting of two expressions and a logical relation between them.
Definition relational.h:34
unsigned options
Definition factor.cpp:2473
size_t c
Definition factor.cpp:756
Interface to GiNaC's products of expressions.
Definition add.cpp:35
const numeric * _num_1_p
Definition utils.cpp:350
std::ostream & operator<<(std::ostream &os, const archive_node &n)
Write archive_node to binary data stream.
Definition archive.cpp:198
std::ostream & python_repr(std::ostream &os)
static const ex exmul(const ex &lh, const ex &rh)
Used internally by operator*() to multiply two ex objects.
Definition operators.cpp:41
static const ex exadd(const ex &lh, const ex &rh)
Used internally by operator+() to add two ex objects.
Definition operators.cpp:35
@ callback_registered
std::map< ex, ex, ex_is_less > exmap
Definition basic.h:49
std::set< ex, ex_is_less > exset
Definition basic.h:48
const ex operator/(const ex &lh, const ex &rh)
Definition operators.cpp:77
std::ostream & dflt(std::ostream &os)
std::ostream & csrc_double(std::ostream &os)
const ex _ex1
Definition utils.cpp:384
static unsigned get_print_options(std::ios_base &s)
ex & operator*=(ex &lh, const ex &rh)
std::ostream & latex(std::ostream &os)
ex & operator++(ex &rh)
Expression prefix increment.
const relational operator==(const ex &lh, const ex &rh)
static const ex exminus(const ex &lh)
Used internally by operator-() and friends to change the sign of an argument.
Definition operators.cpp:55
ex & operator--(ex &rh)
Expression prefix decrement.
std::ostream & python(std::ostream &os)
const relational operator>(const ex &lh, const ex &rh)
std::ostream & index_dimensions(std::ostream &os)
const ex operator+(const ex &lh, const ex &rh)
Definition operators.cpp:62
const ex operator*(const ex &lh, const ex &rh)
Definition operators.cpp:72
std::ostream & csrc_cl_N(std::ostream &os)
const ex _ex_1
Definition utils.cpp:351
static void set_print_options(std::ostream &s, unsigned options)
const relational operator!=(const ex &lh, const ex &rh)
std::ostream & tree(std::ostream &os)
static int my_ios_index()
static void my_ios_callback(std::ios_base::event ev, std::ios_base &s, int i)
static void set_print_context(std::ios_base &s, const print_context &c)
ex & operator+=(ex &lh, const ex &rh)
static print_context * get_print_context(std::ios_base &s)
const numeric * _num1_p
Definition utils.cpp:383
const relational operator<=(const ex &lh, const ex &rh)
std::istream & operator>>(std::istream &is, archive_node &n)
Read archive_node from binary data stream.
Definition archive.cpp:243
std::ostream & csrc(std::ostream &os)
std::ostream & no_index_dimensions(std::ostream &os)
const relational operator<(const ex &lh, const ex &rh)
const relational operator>=(const ex &lh, const ex &rh)
ex & operator/=(ex &lh, const ex &rh)
std::ostream & csrc_float(std::ostream &os)
std::vector< ex > exvector
Definition basic.h:47
const ex operator-(const ex &lh, const ex &rh)
Definition operators.cpp:67
ex & operator-=(ex &lh, const ex &rh)
Interface to GiNaC's non-commutative products of expressions.
Makes the interface to the underlying bignum package available.
Interface to GiNaC's overloaded operators.
Interface to GiNaC's symbolic exponentiation (basis^exponent).
Definition of helper classes for expression output.
Interface to relations between expressions.
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.