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