67 const ex & f4) : inherited{f1,f2,f3,f4}
72 const ex & f4,
const ex & f5) : inherited{f1,f2,f3,f4,f5}
77 const ex & f4,
const ex & f5,
const ex & f6) : inherited{f1,f2,f3,f4,f5,f6}
113 return inherited::info(inf);
122 const exvector &expanded_seq = v.empty() ? this->
seq : v;
126 uintvector positions_of_adds(expanded_seq.size());
127 uintvector number_of_add_operands(expanded_seq.size());
129 size_t number_of_adds = 0;
130 size_t number_of_expanded_terms = 1;
132 size_t current_position = 0;
133 for (
auto & it : expanded_seq) {
134 if (is_exactly_a<add>(it)) {
135 positions_of_adds[number_of_adds] = current_position;
136 size_t num_ops = it.nops();
137 number_of_add_operands[number_of_adds] = num_ops;
138 number_of_expanded_terms *= num_ops;
145 if (number_of_adds == 0) {
155 distrseq.reserve(number_of_expanded_terms);
164 for (
size_t i=0; i<expanded_seq.size(); i++) {
165 if (i == positions_of_adds[j]) {
166 expanded_seq_mod.push_back(
_ex1);
175 for (
size_t i=0; i<number_of_adds; i++) {
182 int l = number_of_adds-1;
183 while ((l>=0) && ((++
k[l]) >= number_of_add_operands[l])) {
202 deg_sum += i.degree(s);
214 deg_sum += i.degree(s);
224 coeffseq.reserve(
seq.size());
229 for (
auto & it :
seq)
230 coeffseq.push_back(it.coeff(s,
n));
231 return dynallocate<ncmul>(std::move(coeffseq));
234 bool coeff_found =
false;
235 for (
auto & i :
seq) {
238 coeffseq.push_back(i);
240 coeffseq.push_back(
c);
246 return dynallocate<ncmul>(std::move(coeffseq));
254 (is_exactly_a<ncmul>(e))) {
256 for (
size_t i=0; i<e.
nops(); i++)
267 (is_exactly_a<ncmul>(e))) {
268 for (
size_t i=0; i<e.
nops(); i++)
303 for (
auto & it :
seq)
309 for (
auto & it :
seq) {
315 if (assocseq.size()==1)
return *(
seq.begin());
318 if (assocseq.empty())
return _ex1;
323 size_t count_commutative=0;
324 size_t count_noncommutative=0;
325 size_t count_noncommutative_composite=0;
326 for (
auto & it : assocseq) {
327 rettypes[i] = it.return_type();
328 switch (rettypes[i]) {
333 count_noncommutative++;
336 count_noncommutative_composite++;
339 throw(std::logic_error(
"ncmul::eval(): invalid return type"));
343 GINAC_ASSERT(count_commutative+count_noncommutative+count_noncommutative_composite==assocseq.size());
347 if (count_commutative!=0) {
349 commutativeseq.reserve(count_commutative+1);
351 noncommutativeseq.reserve(assocseq.size()-count_commutative);
352 size_t num = assocseq.size();
353 for (
size_t i=0; i<num; ++i) {
355 commutativeseq.push_back(assocseq[i]);
357 noncommutativeseq.push_back(assocseq[i]);
359 commutativeseq.push_back(dynallocate<ncmul>(std::move(noncommutativeseq)));
360 return dynallocate<mul>(std::move(commutativeseq));
366 if (count_noncommutative_composite==0) {
371 size_t assoc_num = assocseq.size();
373 std::vector<return_type_t> rttinfos;
374 evv.reserve(assoc_num);
375 rttinfos.reserve(assoc_num);
377 for (
auto & it : assocseq) {
379 size_t rtt_num = rttinfos.size();
381 for (i=0; i<rtt_num; ++i) {
382 if(ti == rttinfos[i]) {
383 evv[i].push_back(it);
389 rttinfos.push_back(ti);
391 (evv.end()-1)->
reserve(assoc_num);
392 (evv.end()-1)->push_back(it);
396 size_t evv_num = evv.size();
397#ifdef DO_GINAC_ASSERT
401 for (i=0; i<evv_num; ++i)
408 return evv[0][0].eval_ncmul(evv[0]);
412 splitseq.reserve(evv_num);
413 for (i=0; i<evv_num; ++i)
414 splitseq.push_back(dynallocate<ncmul>(evv[i]));
416 return dynallocate<mul>(splitseq);
426 s.reserve(
seq.size());
427 for (
auto & it :
seq)
428 s.push_back(it.evalm());
431 auto it = s.
begin(), itend = s.end();
432 if (is_a<matrix>(*it)) {
433 matrix prod(ex_to<matrix>(*it));
435 while (it != itend) {
436 if (!is_a<matrix>(*it))
438 prod = prod.
mul(ex_to<matrix>(*it));
445 return dynallocate<ncmul>(std::move(s));
450 return dynallocate<ncmul>(v);
455 return dynallocate<ncmul>(std::move(v));
472 ev.push_back(i->conjugate());
474 return dynallocate<ncmul>(std::move(ev));
494 size_t num =
seq.size();
500 for (
size_t i=0; i<num; ++i) {
503 addseq.push_back(dynallocate<ncmul>(ncmulseq));
506 return dynallocate<add>(addseq);
511 return inherited::compare_same_type(other);
519 bool all_commutative =
true;
520 exvector::const_iterator noncommutative_element;
524 unsigned rt = i->return_type();
529 noncommutative_element = i;
530 all_commutative =
false;
534 if(noncommutative_element->return_type_tinfo() != i->return_type_tinfo())
547 return make_return_type_t<ncmul>();
552 return i.return_type_tinfo();
555 return make_return_type_t<ncmul>();
570 auto cit = this->
seq.begin(),
end = this->
seq.end();
577 s.reserve(this->
seq.size());
580 s.push_back(expanded_ex);
585 s.push_back(cit->expand(
options));
609 return dynallocate<ncmul>(v);
616 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...