68 const ex & f4) : inherited{f1,f2,f3,f4}
73 const ex & f4,
const ex & f5) : inherited{f1,f2,f3,f4,f5}
78 const ex & f4,
const ex & f5,
const ex & f6) : inherited{f1,f2,f3,f4,f5,f6}
114 return inherited::info(inf);
123 const exvector &expanded_seq = v.empty() ? this->
seq : v;
127 uintvector positions_of_adds(expanded_seq.size());
128 uintvector number_of_add_operands(expanded_seq.size());
130 size_t number_of_adds = 0;
131 size_t number_of_expanded_terms = 1;
133 size_t current_position = 0;
134 for (
auto & it : expanded_seq) {
135 if (is_exactly_a<add>(it)) {
136 positions_of_adds[number_of_adds] = current_position;
137 size_t num_ops = it.nops();
138 number_of_add_operands[number_of_adds] = num_ops;
139 number_of_expanded_terms *= num_ops;
146 if (number_of_adds == 0) {
156 distrseq.reserve(number_of_expanded_terms);
165 for (
size_t i=0; i<expanded_seq.size(); i++) {
166 if (i == positions_of_adds[j]) {
167 expanded_seq_mod.push_back(
_ex1);
176 for (
size_t i=0; i<number_of_adds; i++) {
183 int l = number_of_adds-1;
184 while ((l>=0) && ((++
k[l]) >= number_of_add_operands[l])) {
203 deg_sum += i.degree(s);
215 deg_sum += i.degree(s);
225 coeffseq.reserve(
seq.size());
230 for (
auto & it :
seq)
231 coeffseq.push_back(it.coeff(s,
n));
232 return dynallocate<ncmul>(std::move(coeffseq));
235 bool coeff_found =
false;
236 for (
auto & i :
seq) {
239 coeffseq.push_back(i);
241 coeffseq.push_back(
c);
247 return dynallocate<ncmul>(std::move(coeffseq));
255 (is_exactly_a<ncmul>(e))) {
257 for (
size_t i=0; i<e.
nops(); i++)
268 (is_exactly_a<ncmul>(e))) {
269 for (
size_t i=0; i<e.
nops(); i++)
304 for (
auto & it :
seq)
310 for (
auto & it :
seq) {
316 if (assocseq.size()==1)
return *(
seq.begin());
319 if (assocseq.empty())
return _ex1;
324 size_t count_commutative=0;
325 size_t count_noncommutative=0;
326 size_t count_noncommutative_composite=0;
327 for (
auto & it : assocseq) {
328 rettypes[i] = it.return_type();
329 switch (rettypes[i]) {
334 count_noncommutative++;
337 count_noncommutative_composite++;
340 throw(std::logic_error(
"ncmul::eval(): invalid return type"));
344 GINAC_ASSERT(count_commutative+count_noncommutative+count_noncommutative_composite==assocseq.size());
348 if (count_commutative!=0) {
350 commutativeseq.reserve(count_commutative+1);
352 noncommutativeseq.reserve(assocseq.size()-count_commutative);
353 size_t num = assocseq.size();
354 for (
size_t i=0; i<num; ++i) {
356 commutativeseq.push_back(assocseq[i]);
358 noncommutativeseq.push_back(assocseq[i]);
360 commutativeseq.push_back(dynallocate<ncmul>(std::move(noncommutativeseq)));
361 return dynallocate<mul>(std::move(commutativeseq));
367 if (count_noncommutative_composite==0) {
372 size_t assoc_num = assocseq.size();
374 std::vector<return_type_t> rttinfos;
375 evv.reserve(assoc_num);
376 rttinfos.reserve(assoc_num);
378 for (
auto & it : assocseq) {
380 size_t rtt_num = rttinfos.size();
382 for (i=0; i<rtt_num; ++i) {
383 if(ti == rttinfos[i]) {
384 evv[i].push_back(it);
390 rttinfos.push_back(ti);
392 (evv.end()-1)->
reserve(assoc_num);
393 (evv.end()-1)->push_back(it);
397 size_t evv_num = evv.size();
398#ifdef DO_GINAC_ASSERT
402 for (i=0; i<evv_num; ++i)
409 return evv[0][0].eval_ncmul(evv[0]);
413 splitseq.reserve(evv_num);
414 for (i=0; i<evv_num; ++i)
415 splitseq.push_back(dynallocate<ncmul>(evv[i]));
417 return dynallocate<mul>(splitseq);
427 s.reserve(
seq.size());
428 for (
auto & it :
seq)
429 s.push_back(it.evalm());
432 auto it = s.
begin(), itend = s.end();
433 if (is_a<matrix>(*it)) {
434 matrix prod(ex_to<matrix>(*it));
436 while (it != itend) {
437 if (!is_a<matrix>(*it))
439 prod = prod.
mul(ex_to<matrix>(*it));
446 return dynallocate<ncmul>(std::move(s));
451 return dynallocate<ncmul>(v);
456 return dynallocate<ncmul>(std::move(v));
473 ev.push_back(i->conjugate());
475 return dynallocate<ncmul>(std::move(ev));
495 size_t num =
seq.size();
501 for (
size_t i=0; i<num; ++i) {
504 addseq.push_back(dynallocate<ncmul>(ncmulseq));
507 return dynallocate<add>(addseq);
512 return inherited::compare_same_type(other);
520 bool all_commutative =
true;
521 exvector::const_iterator noncommutative_element;
525 unsigned rt = i->return_type();
530 noncommutative_element = i;
531 all_commutative =
false;
535 if(noncommutative_element->return_type_tinfo() != i->return_type_tinfo())
548 return make_return_type_t<ncmul>();
553 return i.return_type_tinfo();
556 return make_return_type_t<ncmul>();
571 auto cit = this->
seq.begin(),
end = this->
seq.end();
578 s.reserve(this->
seq.size());
581 s.push_back(expanded_ex);
586 s.push_back(cit->expand(
options));
610 return dynallocate<ncmul>(v);
617 else if (v.size() == 1)
Interface to GiNaC's sums of expressions.
Archiving of GiNaC expressions.
#define GINAC_ASSERT(X)
Assertion macro for checking invariances.
This class is the ABC (abstract base class) of GiNaC's class hierarchy.
virtual ex imag_part() const
const basic & setflag(unsigned f) const
Set some status_flags.
unsigned flags
of type status_flags
bool is_equal(const basic &other) const
Test for syntactic equality.
virtual ex real_part() const
virtual int compare_same_type(const basic &other) const
Returns order relation between two objects of same type.
void do_print_tree(const print_tree &c, unsigned level) const
Tree output to stream.
Wrapper template for making GiNaC classes out of STL containers.
virtual void printseq(const print_context &c, char openbracket, char delim, char closebracket, unsigned this_precedence, unsigned upper_precedence=0) const
Print sequence of contained elements.
const_iterator end() const
ex conjugate() const override
const_iterator begin() const
size_t nops() const override
Number of operands/members.
ex op(size_t i) const override
Return operand/member at position i.
Lightweight wrapper for GiNaC's symbolic objects.
const_iterator begin() const noexcept
ex diff(const symbol &s, unsigned nth=1) const
Compute partial derivative of an expression.
ex expand(unsigned options=0) const
Expand an expression.
unsigned return_type() const
void swap(ex &other) noexcept
Efficiently swap the contents of two expressions.
ex coeff(const ex &s, int n=1) const
Class to handle the renaming of dummy indices.
ex handle_factor(const ex &x, const ex &coeff)
matrix mul(const matrix &other) const
Product of matrices.
Non-commutative product of expressions.
unsigned precedence() const override
Return relative operator precedence (for parenthezing output).
int ldegree(const ex &s) const override
Return degree of lowest power in object s.
int degree(const ex &s) const override
Return degree of highest power in object s.
void append_factors(exvector &v, const ex &e) const
ex coeff(const ex &s, int n=1) const override
Return coefficient of degree n in object s.
return_type_t return_type_tinfo() const override
void do_print(const print_context &c, unsigned level) const
ex expand(unsigned options=0) const override
Expand expression, i.e.
exvector expandchildren(unsigned options) const
ex imag_part() const override
ncmul(const ex &lh, const ex &rh)
ex real_part() const override
void do_print_csrc(const print_context &c, unsigned level) const
ex eval() const override
Perform automatic term rewriting rules in this class.
ex evalm() const override
Evaluate sums, products and integer powers of matrices.
ex derivative(const symbol &s) const override
Implementation of ex::diff() for a non-commutative product.
unsigned return_type() const override
bool info(unsigned inf) const override
Information about the object.
const exvector & get_factors() const
size_t count_factors(const ex &e) const
ex thiscontainer(const exvector &v) const override
ex conjugate() const override
Base class for print_contexts.
@ noncommutative_composite
@ expanded
.expand(0) has already done its job (other expand() options ignore this flag)
@ evaluated
.eval() has already done its job
Interface to GiNaC's clifford algebra (Dirac gamma) objects.
Interface to GiNaC's light-weight expression handles.
Interface to GiNaC's indexed expressions.
Interface to symbolic matrices.
Interface to GiNaC's products of expressions.
ex hold_ncmul(const exvector &v)
bool is_clifford_tinfo(const return_type_t &ti)
Check whether a given return_type_t object (as returned by return_type_tinfo() is that of a clifford ...
ex reeval_ncmul(const exvector &v)
bool are_ex_trivially_equal(const ex &e1, const ex &e2)
Compare two objects of class quickly without doing a deep tree traversal.
std::vector< exvector > exvectorvector
std::vector< std::size_t > uintvector
print_func< print_context >(&varidx::do_print). print_func< print_latex >(&varidx
ex factor(const ex &poly, unsigned options)
Interface function to the outside world.
std::vector< unsigned > unsignedvector
lst rename_dummy_indices_uniquely(const exvector &va, const exvector &vb)
Similar to above, where va and vb are the same and the return value is a list of two lists for substi...
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.
std::vector< ex > exvector
Interface to GiNaC's non-commutative products of expressions.
#define GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(classname, supername, options)
Macro for inclusion in the implementation of each registered class.
To distinguish between different kinds of non-commutative objects.
Interface to several small and furry utilities needed within GiNaC but not of any interest to the use...