69 const ex & f4) : inherited{f1,f2,f3,f4}
74 const ex & f4,
const ex & f5) : inherited{f1,f2,f3,f4,f5}
79 const ex & f4,
const ex & f5,
const ex & f6) : inherited{f1,f2,f3,f4,f5,f6}
115 return inherited::info(inf);
124 const exvector &expanded_seq = v.empty() ? this->
seq : v;
128 uintvector positions_of_adds(expanded_seq.size());
129 uintvector number_of_add_operands(expanded_seq.size());
131 size_t number_of_adds = 0;
132 size_t number_of_expanded_terms = 1;
134 size_t current_position = 0;
135 for (
auto & it : expanded_seq) {
136 if (is_exactly_a<add>(it)) {
137 positions_of_adds[number_of_adds] = current_position;
138 size_t num_ops = it.nops();
139 number_of_add_operands[number_of_adds] = num_ops;
140 number_of_expanded_terms *= num_ops;
147 if (number_of_adds == 0) {
157 distrseq.reserve(number_of_expanded_terms);
166 for (
size_t i=0; i<expanded_seq.size(); i++) {
167 if (i == positions_of_adds[j]) {
168 expanded_seq_mod.push_back(
_ex1);
177 for (
size_t i=0; i<number_of_adds; i++) {
184 int l = number_of_adds-1;
185 while ((l>=0) && ((++
k[l]) >= number_of_add_operands[l])) {
204 deg_sum += i.degree(s);
216 deg_sum += i.degree(s);
226 coeffseq.reserve(
seq.size());
231 for (
auto & it :
seq)
232 coeffseq.push_back(it.coeff(s,
n));
233 return dynallocate<ncmul>(std::move(coeffseq));
236 bool coeff_found =
false;
237 for (
auto & i :
seq) {
240 coeffseq.push_back(i);
242 coeffseq.push_back(
c);
248 return dynallocate<ncmul>(std::move(coeffseq));
256 (is_exactly_a<ncmul>(e))) {
258 for (
size_t i=0; i<e.
nops(); i++)
269 (is_exactly_a<ncmul>(e))) {
270 for (
size_t i=0; i<e.
nops(); i++)
305 for (
auto & it :
seq)
311 for (
auto & it :
seq) {
317 if (assocseq.size()==1)
return *(
seq.begin());
320 if (assocseq.empty())
return _ex1;
325 size_t count_commutative=0;
326 size_t count_noncommutative=0;
327 size_t count_noncommutative_composite=0;
328 for (
auto & it : assocseq) {
329 rettypes[i] = it.return_type();
330 switch (rettypes[i]) {
335 count_noncommutative++;
338 count_noncommutative_composite++;
341 throw(std::logic_error(
"ncmul::eval(): invalid return type"));
345 GINAC_ASSERT(count_commutative+count_noncommutative+count_noncommutative_composite==assocseq.size());
349 if (count_commutative!=0) {
351 commutativeseq.reserve(count_commutative+1);
353 noncommutativeseq.reserve(assocseq.size()-count_commutative);
354 size_t num = assocseq.size();
355 for (
size_t i=0; i<num; ++i) {
357 commutativeseq.push_back(assocseq[i]);
359 noncommutativeseq.push_back(assocseq[i]);
361 commutativeseq.push_back(dynallocate<ncmul>(std::move(noncommutativeseq)));
362 return dynallocate<mul>(std::move(commutativeseq));
368 if (count_noncommutative_composite==0) {
373 size_t assoc_num = assocseq.size();
375 std::vector<return_type_t> rttinfos;
376 evv.reserve(assoc_num);
377 rttinfos.reserve(assoc_num);
379 for (
auto & it : assocseq) {
381 size_t rtt_num = rttinfos.size();
383 for (i=0; i<rtt_num; ++i) {
384 if(ti == rttinfos[i]) {
385 evv[i].push_back(it);
391 rttinfos.push_back(ti);
393 (evv.end()-1)->
reserve(assoc_num);
394 (evv.end()-1)->push_back(it);
398 size_t evv_num = evv.size();
399#ifdef DO_GINAC_ASSERT
403 for (i=0; i<evv_num; ++i)
410 return evv[0][0].eval_ncmul(evv[0]);
414 splitseq.reserve(evv_num);
415 for (i=0; i<evv_num; ++i)
416 splitseq.push_back(dynallocate<ncmul>(evv[i]));
418 return dynallocate<mul>(splitseq);
428 s.reserve(
seq.size());
429 for (
auto & it :
seq)
430 s.push_back(it.evalm());
433 auto it = s.
begin(), itend = s.end();
434 if (is_a<matrix>(*it)) {
435 matrix prod(ex_to<matrix>(*it));
437 while (it != itend) {
438 if (!is_a<matrix>(*it))
440 prod = prod.
mul(ex_to<matrix>(*it));
447 return dynallocate<ncmul>(std::move(s));
452 return dynallocate<ncmul>(v);
457 return dynallocate<ncmul>(std::move(v));
474 ev.push_back(i->conjugate());
476 return dynallocate<ncmul>(std::move(ev));
496 size_t num =
seq.size();
502 for (
size_t i=0; i<num; ++i) {
503 ex e =
seq[i].diff(s);
505 addseq.push_back(dynallocate<ncmul>(ncmulseq));
508 return dynallocate<add>(addseq);
513 return inherited::compare_same_type(other);
521 bool all_commutative =
true;
522 exvector::const_iterator noncommutative_element;
526 unsigned rt = i->return_type();
531 noncommutative_element = i;
532 all_commutative =
false;
536 if(noncommutative_element->return_type_tinfo() != i->return_type_tinfo())
549 return make_return_type_t<ncmul>();
554 return i.return_type_tinfo();
557 return make_return_type_t<ncmul>();
572 auto cit = this->
seq.begin(),
end = this->
seq.end();
579 s.reserve(this->
seq.size());
582 s.push_back(expanded_ex);
587 s.push_back(cit->expand(
options));
611 return dynallocate<ncmul>(v);
618 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.
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.
void do_print_tree(const print_tree &c, unsigned level) const
Lightweight wrapper for GiNaC's symbolic objects.
const_iterator begin() const noexcept
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.
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
GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(add, expairseq, print_func< print_context >(&add::do_print). print_func< print_latex >(&add::do_print_latex). print_func< print_csrc >(&add::do_print_csrc). print_func< print_tree >(&add::do_print_tree). print_func< print_python_repr >(&add::do_print_python_repr)) add
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.
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...