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