99indexed::indexed(
const ex & b,
const symmetry &
symm,
const ex & i1,
const ex & i2,
const ex & i3,
const ex & i4) : inherited{b, i1, i2, i3, i4}, symtree(
symm)
106 seq.insert(
seq.end(), v.begin(), v.end());
112 seq.insert(
seq.end(), v.begin(), v.end());
134 inherited::read_archive(
n, sym_lst);
135 if (!
n.find_ex(
"symmetry",
symtree, sym_lst)) {
138 n.find_unsigned(
"symmetry",
symm);
157 inherited::archive(
n);
167 if (
seq.size() > 1) {
169 auto it =
seq.begin() + 1, itend =
seq.end();
171 if (is_a<print_latex>(
c)) {
175 bool covariant =
true;
177 while (it != itend) {
178 bool cur_covariant = (is_a<varidx>(*it) ? ex_to<varidx>(*it).is_covariant() :
true);
179 if (first || cur_covariant != covariant) {
183 covariant = cur_covariant;
199 while (it != itend) {
210 c.s << openbrace <<
'(';
216 c.s <<
')' << closebrace;
231 c.s << std::string(level,
' ') << class_name() <<
" @" <<
this
232 << std::hex <<
", hash=0x" <<
hashvalue <<
", flags=0x" <<
flags << std::dec
233 <<
", " <<
seq.size()-1 <<
" indices"
234 <<
", symmetry=" <<
symtree << std::endl;
235 seq[0].print(
c, level +
c.delta_indent);
243 return inherited::info(inf);
253 return find_if(
seq.begin() + 1,
seq.end(),
254 [inf](
const ex & e) { return !(ex_to<idx>(e).get_value().info(inf)); }) ==
seq.end();
260 return inherited::compare_same_type(other);
265 const ex &base =
seq[0];
272 if (is_exactly_a<mul>(base) && is_exactly_a<numeric>(base.
op(base.
nops() - 1))) {
274 ex f = ex_to<numeric>(base.
op(base.
nops() - 1));
279 if((
typeid(*
this) ==
typeid(
indexed)) &&
seq.size()==1)
283 if (
seq.size() > 2) {
287 if (sig != std::numeric_limits<int>::max()) {
296 return ex_to<basic>(base).eval_indexed(*
this);
303 return real_part_function(*this).hold();
310 return imag_part_function(*this).hold();
325 if(is_a<matrix>(
op(0)))
337 if (is_exactly_a<add>(newbase)) {
339 for (
size_t i=0; i<newbase.
nops(); i++) {
341 s[0] = newbase.
op(i);
371 auto it =
seq.begin() + 1, itend =
seq.end();
372 while (it != itend) {
374 throw(std::invalid_argument(
"indices of indexed object must be of type idx"));
379 if (!is_exactly_a<symmetry>(
symtree))
380 throw(std::invalid_argument(
"symmetry of indexed object must be of type symmetry"));
406 return lh.
is_equal(ex_to<idx>(rh).replace_dim(ex_to<idx>(lh).get_dim()));
417 if (v1.size() != v2.size())
431 exvector free_indices, dummy_indices;
433 return dummy_indices;
440 indices.insert(indices.end(), other_indices.begin(), other_indices.end());
443 return dummy_indices;
448 auto it =
seq.begin() + 1, itend =
seq.end();
449 while (it != itend) {
459 exvector free_indices, dummy_indices;
467 for (
size_t i=0; i<
nops(); i++) {
473 throw (std::runtime_error(
"add::get_free_indices: inconsistent indices in sum"));
483 for (
size_t i=0; i<
nops(); i++) {
485 un.insert(un.end(), free_indices_of_factor.begin(), free_indices_of_factor.end());
489 exvector free_indices, dummy_indices;
498 for (
size_t i=0; i<
nops(); i++) {
500 un.insert(un.end(), free_indices_of_factor.begin(), free_indices_of_factor.end());
504 exvector free_indices, dummy_indices;
519 throw (std::runtime_error(
"integral::get_free_indices: boundary values should not have free indices"));
527 if (is_exactly_a<T>(it))
542 size_t global_size = number_of_type<T>(global_dummy_indices),
543 local_size = number_of_type<T>(local_dummy_indices);
549 if (global_size < local_size) {
553 size_t old_global_size = global_size;
554 int remaining = local_size - global_size;
555 auto it = local_dummy_indices.
begin(), itend = local_dummy_indices.end();
556 while (it != itend && remaining > 0) {
557 if (is_exactly_a<T>(*it) &&
558 find_if(global_dummy_indices.begin(), global_dummy_indices.end(),
559 [it](
const ex &lh) { return idx_is_equal_ignore_dim()(lh, *it); }) == global_dummy_indices.end()) {
560 global_dummy_indices.push_back(*it);
568 if (old_global_size == 0)
575 local_syms.reserve(local_size);
576 global_syms.reserve(local_size);
577 for (
size_t i=0; local_syms.size()!=local_size; i++)
578 if(is_exactly_a<T>(local_dummy_indices[i]))
579 local_syms.push_back(local_dummy_indices[i].
op(0));
581 for (
size_t i=0; global_syms.size()!=local_size; i++)
582 if(is_exactly_a<T>(global_dummy_indices[i]))
583 global_syms.push_back(global_dummy_indices[i].
op(0));
588 set_difference(local_syms.begin(), local_syms.end(), global_syms.begin(), global_syms.end(), std::back_insert_iterator<exvector>(local_uniq),
ex_is_less());
589 set_difference(global_syms.begin(), global_syms.end(), local_syms.begin(), local_syms.end(), std::back_insert_iterator<exvector>(global_uniq),
ex_is_less());
592 if (local_uniq.empty())
595 while (global_uniq.size() > local_uniq.size())
596 global_uniq.pop_back();
604 exvector::const_iterator it1, itend;
605 for (it1 = v.begin(), itend = v.end(); it1 != itend; ++it1) {
606 if (is_exactly_a<varidx>(*it1))
607 variant_indices.push_back(*it1);
620 bool something_changed =
false;
624 local_var_dummies.reserve(e.
nops()/2);
625 for (
size_t i=1; i<e.
nops(); ++i) {
626 if (!is_a<varidx>(e.
op(i)))
628 for (
size_t j=i+1; j<e.
nops(); ++j) {
630 local_var_dummies.push_back(e.
op(i));
631 for (
auto k = variant_dummy_indices.begin();
k!=variant_dummy_indices.end(); ++
k) {
632 if (e.
op(i).
op(0) ==
k->op(0)) {
633 variant_dummy_indices.erase(
k);
646 size_t numpossibs = 1 << local_var_dummies.size();
647 for (
size_t i=0; i<numpossibs; ++i) {
649 for (
size_t j=0; j<local_var_dummies.size(); ++j) {
652 ex curr_idx = local_var_dummies[j];
653 ex curr_toggle = ex_to<varidx>(curr_idx).toggle_variance();
654 m[curr_idx] = curr_toggle;
655 m[curr_toggle] = curr_idx;
661 something_changed =
true;
666 if (!is_a<indexed>(e))
669 exvector seq = ex_to<indexed>(e).seq;
673 for (
auto it2 = seq.begin()+1, it2end = seq.end(); it2 != it2end; ++it2) {
674 if (!is_exactly_a<varidx>(*it2))
677 exvector::iterator vit, vitend;
678 for (vit = variant_dummy_indices.begin(), vitend = variant_dummy_indices.end(); vit != vitend; ++vit) {
679 if (it2->op(0).is_equal(vit->op(0))) {
680 if (ex_to<varidx>(*it2).is_covariant()) {
693 *it2 = ex_to<varidx>(*it2).toggle_variance();
694 something_changed =
true;
696 moved_indices.push_back(*vit);
697 variant_dummy_indices.erase(vit);
702 for (vit = moved_indices.begin(), vitend = moved_indices.end(); vit != vitend; ++vit) {
703 if (it2->op(0).is_equal(vit->op(0))) {
704 if (ex_to<varidx>(*it2).is_contravariant()) {
705 *it2 = ex_to<varidx>(*it2).toggle_variance();
706 something_changed =
true;
715 if (something_changed)
716 e = ex_to<indexed>(e).thiscontainer(seq);
718 return something_changed;
725 return (is_a<indexed>(lh) ? lh.
op(0) : lh).compare(is_a<indexed>(rh) ? rh.
op(0) : rh) < 0;
735 non_commutative = is_exactly_a<ncmul>(e);
738 v.reserve(e.
nops() * 2);
740 if (is_exactly_a<power>(e)) {
743 v.push_back(e.
op(0));
744 v.push_back(e.
op(0));
746 for (
size_t i=0; i<e.
nops(); i++) {
749 v.push_back(f.
op(0));
750 v.push_back(f.
op(0));
751 }
else if (is_exactly_a<ncmul>(f)) {
753 non_commutative =
true;
754 for (
size_t j=0; j<f.
nops(); j++)
755 v.push_back(f.
op(j));
764 dummy_syms.reserve(
r.nops());
765 for (
auto & it : local_dummy_indices)
766 if(is_exactly_a<T>(it))
767 dummy_syms.push_back(it.op(0));
768 if(dummy_syms.size() < 2)
786 bool non_commutative;
790 bool something_changed =
false;
791 bool has_nonsymmetric =
false;
793 exvector::iterator it1, itend = v.end(), next_to_last = itend - 1;
794 for (it1 = v.begin(); it1 != next_to_last; it1++) {
797 if (!is_a<indexed>(*it1))
801 bool first_nonsymmetric = ex_to<symmetry>(ex_to<indexed>(*it1).get_symmetry()).has_nonsymmetric();
806 find_free_and_dummy(ex_to<indexed>(*it1).seq.begin() + 1, ex_to<indexed>(*it1).seq.end(), free1, dummy1);
808 exvector::iterator it2;
809 for (it2 = it1 + 1; it2 != itend; it2++) {
811 if (!is_a<indexed>(*it2))
819 find_free_and_dummy(ex_to<indexed>(*it2).seq.begin() + 1, ex_to<indexed>(*it2).seq.end(), un, dummy1);
820 un.insert(un.end(), free1.begin(), free1.end());
825 size_t num_dummies = dummy.size();
826 if (num_dummies == 0)
830 bool contracted =
false;
831 if (free.empty() && it1->nops()==2 && it2->nops()==2) {
834 ex_to<idx>(it1->op(1)).get_dim(),
835 ex_to<idx>(it2->op(1)).get_dim()
842 *it1 = sp.
evaluate(*it1, *it2, dim);
844 goto contraction_done;
849 contracted = ex_to<basic>(it1->op(0)).contract_with(it1, it2, v);
854 contracted = ex_to<basic>(it2->op(0)).contract_with(it2, it1, v);
858 if (first_noncommutative || second_noncommutative
859 || is_exactly_a<add>(*it1) || is_exactly_a<add>(*it2)
860 || is_exactly_a<mul>(*it1) || is_exactly_a<mul>(*it2)
861 || is_exactly_a<ncmul>(*it1) || is_exactly_a<ncmul>(*it2)) {
868 bool is_a_product = (is_exactly_a<mul>(*it1) || is_exactly_a<ncmul>(*it1)) &&
869 (is_exactly_a<mul>(*it2) || is_exactly_a<ncmul>(*it2));
870 ex r = (non_commutative ?
ex(
ncmul(std::move(v))) :
ex(
mul(std::move(v))));
883 something_changed =
true;
886 else if (!has_nonsymmetric &&
887 (first_nonsymmetric ||
888 ex_to<symmetry>(ex_to<indexed>(*it2).get_symmetry()).has_nonsymmetric())) {
889 has_nonsymmetric =
true;
896 exvector un, individual_dummy_indices;
897 for (it1 = v.begin(), itend = v.end(); it1 != itend; ++it1) {
899 if (is_a<indexed>(*it1)) {
901 find_free_and_dummy(ex_to<indexed>(*it1).seq.begin() + 1, ex_to<indexed>(*it1).seq.end(), free_indices_of_factor, dummy_indices_of_factor);
902 individual_dummy_indices.insert(individual_dummy_indices.end(), dummy_indices_of_factor.begin(), dummy_indices_of_factor.end());
904 free_indices_of_factor = it1->get_free_indices();
905 un.insert(un.end(), free_indices_of_factor.begin(), free_indices_of_factor.end());
909 local_dummy_indices.insert(local_dummy_indices.end(), individual_dummy_indices.begin(), individual_dummy_indices.end());
916 if (!variant_dummy_indices.empty()) {
920 if (!non_commutative)
926 for (it1 = v.begin(), itend = v.end(); it1 != itend; ++it1) {
927 if (!is_a<indexed>(*it1))
931 something_changed =
true;
936 if (something_changed)
937 r = non_commutative ?
ex(
ncmul(std::move(v))) :
ex(
mul(std::move(v)));
944 if (has_nonsymmetric) {
945 ex q = idx_symmetrization<idx>(
r, local_dummy_indices);
947 free_indices.clear();
950 q = idx_symmetrization<varidx>(q, local_dummy_indices);
952 free_indices.clear();
955 q = idx_symmetrization<spinidx>(q, local_dummy_indices);
957 free_indices.clear();
963 r = rename_dummy_indices<idx>(
r, dummy_indices, local_dummy_indices);
964 r = rename_dummy_indices<varidx>(
r, dummy_indices, local_dummy_indices);
965 r = rename_dummy_indices<spinidx>(
r, dummy_indices, local_dummy_indices);
968 if (is_exactly_a<mul>(
r) &&
r.nops() == 2
969 && is_exactly_a<numeric>(
r.op(1)) && is_a<indexed>(
r.op(0)))
970 return ex_to<basic>(
r.op(0).op(0)).scalar_mul_indexed(
r.op(0), ex_to<numeric>(
r.op(1)));
1001 if (is_exactly_a<mul>(symmterm_) && is_exactly_a<numeric>(symmterm_.
op(symmterm_.
nops()-1))) {
1034 if(is_a<idx>(
x) &&
x.
op(0)==sym)
1037 for(
size_t i=0; i<
x.
nops(); ++i)
1051 if (is_a<indexed>(e_expanded)) {
1054 const indexed &i = ex_to<indexed>(e_expanded);
1063 if (!variant_dummy_indices.empty()) {
1071 e_expanded = rename_dummy_indices<idx>(e_expanded, dummy_indices, local_dummy_indices);
1072 e_expanded = rename_dummy_indices<varidx>(e_expanded, dummy_indices, local_dummy_indices);
1073 e_expanded = rename_dummy_indices<spinidx>(e_expanded, dummy_indices, local_dummy_indices);
1079 if (is_exactly_a<add>(e_expanded)) {
1082 free_indices.clear();
1084 for (
size_t i=0; i<e_expanded.
nops(); i++) {
1089 free_indices = free_indices_of_term;
1094 std::ostringstream s;
1095 s <<
"simplify_indexed: inconsistent indices in sum: ";
1096 s <<
exprseq(free_indices) <<
" vs. " <<
exprseq(free_indices_of_term);
1097 throw (std::runtime_error(s.str()));
1099 if (is_a<indexed>(sum) && is_a<indexed>(term))
1100 sum = ex_to<basic>(sum.
op(0)).add_indexed(sum, term);
1109 free_indices.clear();
1114 size_t num_terms_orig = (is_exactly_a<add>(sum) ? sum.
nops() : 1);
1115 if (num_terms_orig < 2 || dummy_indices.size() < 2)
1120 std::vector<terminfo> terms;
1121 for (
size_t i=0; i<sum.
nops(); i++) {
1122 const ex & term = sum.
op(i);
1124 dummy_indices_of_term.reserve(dummy_indices.size());
1125 for (
auto & i : dummy_indices)
1127 dummy_indices_of_term.push_back(i);
1128 ex term_symm = idx_symmetrization<idx>(term, dummy_indices_of_term);
1129 term_symm = idx_symmetrization<varidx>(term_symm, dummy_indices_of_term);
1130 term_symm = idx_symmetrization<spinidx>(term_symm, dummy_indices_of_term);
1133 terms.push_back(
terminfo(term, term_symm));
1140 std::vector<terminfo> terms_pass2;
1141 for (std::vector<terminfo>::const_iterator i=terms.begin(); i!=terms.end(); ) {
1144 while (j != terms.end() && j->symm == i->symm) {
1148 terms_pass2.push_back(
terminfo(i->orig * num, i->symm * num));
1153 if (terms_pass2.size() == 1)
1154 return terms_pass2[0].orig;
1157 std::vector<symminfo> sy;
1158 for (
auto & i : terms_pass2) {
1159 if (is_exactly_a<add>(i.symm)) {
1160 size_t num = i.symm.nops();
1161 for (
size_t j=0; j<num; j++)
1162 sy.push_back(
symminfo(i.symm.op(j), i.orig, num));
1164 sy.push_back(
symminfo(i.symm, i.orig, 1));
1171 std::vector<symminfo> sy_pass2;
1173 for (
auto i=sy.begin(); i!=sy.end(); ) {
1177 if (j != sy.end() && j->symmterm == i->symmterm) {
1181 while (j != sy.end() && j->symmterm == i->symmterm) {
1188 result.push_back(
coeff * i->symmterm);
1193 sy_pass2.push_back(*i);
1200 if (sy_pass2.size() > 0) {
1205 for (std::vector<symminfo>::const_iterator i=sy_pass2.begin(); i!=sy_pass2.end(); ) {
1210 while (j != sy_pass2.end() && j->orig == i->orig) {
1215 if (num == i->num) {
1218 result.push_back(i->orig);
1223 std::vector<symminfo>::const_iterator
k;
1224 for (
k=i;
k!=j;
k++)
1225 result.push_back(
k->coeff *
k->symmterm);
1233 ex sum_symm = dynallocate<add>(result);
1235 free_indices.clear();
1240 if (is_exactly_a<mul>(e_expanded)
1241 || is_exactly_a<ncmul>(e_expanded)
1242 || (is_exactly_a<power>(e_expanded) && is_a<indexed>(e_expanded.
op(0)) && e_expanded.
op(1).
is_equal(
_ex2)))
1246 free_indices.clear();
1258 exvector free_indices, dummy_indices;
1273 exvector free_indices, dummy_indices;
1302 ex s1 = is_a<indexed>(v1_) ? v1_.
op(0) : v1_;
1303 ex s2 = is_a<indexed>(v2_) ? v2_.
op(0) : v2_;
1321 if (is_a<wildcard>(
dim) || is_a<wildcard>(other.
dim))
1337 if (is_a<wildcard>(
dim) || is_a<wildcard>(other.
dim))
1345 std::cerr <<
"(" <<
v1 <<
"," <<
v2 <<
"," <<
dim <<
")";
1361 for (
auto & it1 : l)
1362 for (
auto & it2 : l)
1363 add(it1, it2, it1 * it2);
1385 std::cerr <<
"map size=" <<
spm.size() << std::endl;
1386 for (
auto & it :
spm) {
1388 std::cerr <<
"item key=";
1390 std::cerr <<
", value=" << it.second << std::endl;
1396 if (is_a<indexed>(e))
1397 return ex_to<indexed>(e).get_dummy_indices();
1398 else if (is_a<power>(e) && e.
op(1)==2) {
1401 else if (is_a<mul>(e) || is_a<ncmul>(e)) {
1404 for (std::size_t i = 0; i < e.
nops(); ++i) {
1406 dummies.insert(dummies.end(), dummies_of_factor.begin(),
1407 dummies_of_factor.end());
1409 free_indices.insert(free_indices.begin(), free_of_factor.begin(),
1410 free_of_factor.end());
1415 dummies.insert(dummies.end(), dummy_out.begin(), dummy_out.end());
1418 else if(is_a<add>(e)) {
1420 for(std::size_t i = 0; i < e.
nops(); ++i) {
1422 sort(dummies_of_term.begin(), dummies_of_term.end());
1424 set_union(result.begin(), result.end(), dummies_of_term.begin(),
1425 dummies_of_term.end(), std::back_inserter<exvector>(new_vec),
1427 result.swap(new_vec);
1440 auto ip = p.begin(), ipend = p.end();
1442 while (ip != ipend) {
1443 if (is_a<indexed>(*ip)) {
1444 v1 = ex_to<indexed>(*ip).get_dummy_indices();
1445 v.insert(v.end(), v1.begin(), v1.end());
1447 while (ip1 != ipend) {
1448 if (is_a<indexed>(*ip1)) {
1449 v1 = ex_to<indexed>(*ip).get_dummy_indices(ex_to<indexed>(*ip1));
1450 v.insert(v.end(), v1.begin(), v1.end());
1463 set_intersection(va.begin(), va.end(), vb.begin(), vb.end(), std::back_insert_iterator<exvector>(common_indices),
ex_is_less());
1464 if (common_indices.empty()) {
1468 old_indices.
reserve(2*common_indices.size());
1469 new_indices.reserve(2*common_indices.size());
1470 exvector::const_iterator ip = common_indices.begin(), ipend = common_indices.end();
1471 while (ip != ipend) {
1472 ex newsym = dynallocate<symbol>();
1474 if(is_exactly_a<spinidx>(*ip))
1475 newidx = dynallocate<spinidx>(newsym, ex_to<spinidx>(*ip).get_dim(),
1476 ex_to<spinidx>(*ip).is_covariant(),
1477 ex_to<spinidx>(*ip).is_dotted());
1478 else if (is_exactly_a<varidx>(*ip))
1479 newidx = dynallocate<varidx>(newsym, ex_to<varidx>(*ip).get_dim(),
1480 ex_to<varidx>(*ip).is_covariant());
1482 newidx = dynallocate<idx>(newsym, ex_to<idx>(*ip).get_dim());
1483 old_indices.push_back(*ip);
1484 new_indices.push_back(newidx);
1485 if(is_a<varidx>(*ip)) {
1486 old_indices.push_back(ex_to<varidx>(*ip).toggle_variance());
1487 new_indices.push_back(ex_to<varidx>(newidx).toggle_variance());
1491 return lst{
lst(old_indices.begin(), old_indices.end()),
lst(new_indices.begin(), new_indices.end())};
1504 if (va.size() > 0) {
1506 if (vb.size() > 0) {
1510 if (indices_subs.
op(0).
nops() > 0)
1519 if (va.size() > 0) {
1521 if (vb.size() > 0) {
1524 if (indices_subs.
op(0).
nops() > 0) {
1526 for (
auto & i : ex_to<lst>(indices_subs.
op(1)))
1529 set_difference(vb.begin(), vb.end(), indices_subs.
op(0).
begin(), indices_subs.
op(0).
end(), std::back_insert_iterator<exvector>(uncommon_indices),
ex_is_less());
1530 for (
auto & ip : uncommon_indices)
1545 if (is_a<add>(e_expanded) || is_a<lst>(e_expanded) || is_a<matrix>(e_expanded)) {
1546 return e_expanded.
map(fcn);
1547 }
else if (is_a<ncmul>(e_expanded) || is_a<mul>(e_expanded) || is_a<power>(e_expanded) || is_a<indexed>(e_expanded)) {
1549 if (is_a<indexed>(e_expanded))
1550 v = ex_to<indexed>(e_expanded).get_dummy_indices();
1553 ex result = e_expanded;
1554 for (
const auto & nu : v) {
1556 int idim = ex_to<numeric>(ex_to<idx>(nu).get_dim()).to_int();
1558 for (
int i=0; i < idim; i++) {
1559 if (subs_idx && is_a<varidx>(nu)) {
1560 ex other = ex_to<varidx>(nu).toggle_variance();
1563 other ==
idx(i, idim)
1566 en += result.
subs( nu.op(0) == i );
Interface to GiNaC's sums of expressions.
Archiving of GiNaC expressions.
#define GINAC_ASSERT(X)
Assertion macro for checking invariances.
exvector get_free_indices() const override
Return a vector containing the free indices of an expression.
This class stores all properties needed to record/retrieve the state of one object of class basic (or...
This class is the ABC (abstract base class) of GiNaC's class hierarchy.
unsigned hashvalue
hash value
unsigned flags
of type status_flags
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.
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.
ex map(map_function &f) const
const_iterator begin() const noexcept
exvector get_free_indices() const
ex expand(unsigned options=0) const
Expand an expression.
bool is_equal(const ex &other) const
ex simplify_indexed(unsigned options=0) const
Simplify/canonicalize expression containing indexed objects.
ex symmetrize_cyclic() const
Symmetrize expression by cyclic permutation over its free indices.
unsigned return_type() const
const_iterator end() const noexcept
ex subs(const exmap &m, unsigned options=0) const
int compare(const ex &other) const
ex symmetrize() const
Symmetrize expression over its free indices.
ex coeff(const ex &s, int n=1) const
ex antisymmetrize() const
Antisymmetrize expression over its free indices.
size_t nops() const override
Number of operands/members.
ex op(size_t i) const override
Return operand/member at position i.
@ expand_indexed
expands (a+b).i to a.i+b.i
This class holds an indexed expression.
bool all_index_values_are(unsigned inf) const
Check whether all index values have a certain property.
ex thiscontainer(const exvector &v) const override
unsigned precedence() const override
Return relative operator precedence (for parenthezing output).
void printindices(const print_context &c, unsigned level) const
exvector get_free_indices() const override
Return a vector containing the free indices of an expression.
void archive(archive_node &n) const override
Save (a.k.a.
void do_print(const print_context &c, unsigned level) const
ex expand(unsigned options=0) const override
Expand expression, i.e.
void do_print_latex(const print_latex &c, unsigned level) const
void read_archive(const archive_node &n, lst &syms) override
Read (a.k.a.
void do_print_tree(const print_tree &c, unsigned level) const
ex derivative(const symbol &s) const override
Implementation of ex::diff() for an indexed object always returns 0.
bool info(unsigned inf) const override
Information about the object.
ex eval() const override
Perform automatic non-interruptive term rewriting rules.
indexed(const ex &b)
Construct indexed object with no index.
ex real_part() const override
void validate() const
Check whether all indices are of class idx and validate the symmetry tree.
ex symtree
Index symmetry (tree of symmetry objects)
exvector get_indices() const
Return a vector containing the object's indices.
exvector get_dummy_indices() const
Return a vector containing the dummy indices of the object, if any.
void print_indexed(const print_context &c, const char *openbrace, const char *closebrace, unsigned level) const
bool has_dummy_index_for(const ex &i) const
Check whether the object has an index that forms a dummy index pair with a given index.
unsigned return_type() const override
ex imag_part() const override
exvector get_free_indices() const override
Return a vector containing the free indices of an expression.
exvector get_free_indices() const override
Return a vector containing the free indices of an expression.
Non-commutative product of expressions.
exvector get_free_indices() const override
Return a vector containing the free indices of an expression.
Base class for print_contexts.
Context for latex-parsable output.
Context for tree-like output for debugging.
Helper class for storing information about known scalar products which are to be automatically replac...
bool is_defined(const ex &v1, const ex &v2, const ex &dim) const
Check whether scalar product pair is defined.
ex evaluate(const ex &v1, const ex &v2, const ex &dim) const
Return value of defined scalar product pair.
void add(const ex &v1, const ex &v2, const ex &sp)
Register scalar product pair and its value.
void clear()
Clear all registered scalar products.
void add_vectors(const lst &l, const ex &dim=wild())
Register list of vectors.
bool operator<(const spmapkey &other) const
bool operator==(const spmapkey &other) const
@ no_pattern
disable pattern matching
This class describes the symmetry of a group of indices.
bool operator()(const symminfo &si1, const symminfo &si2) const
bool operator()(const symminfo &si1, const symminfo &si2) const
This structure stores the individual symmetrized terms obtained during the simplification of sums.
ex coeff
coefficient of symmetrized term
ex symmterm
symmetrized term
size_t num
how many symmetrized terms resulted from the original term
symminfo(const ex &symmterm_, const ex &orig_, size_t num_)
bool operator()(const terminfo &ti1, const terminfo &ti2) const
This structure stores the original and symmetrized versions of terms obtained during the simplificati...
terminfo(const ex &orig_, const ex &symm_)
Interface to GiNaC's indices.
Interface to GiNaC's indexed expressions.
Interface to GiNaC's initially known functions.
Interface to GiNaC's symbolic integral.
Definition of GiNaC's lst.
Interface to symbolic matrices.
Interface to GiNaC's products of expressions.
static bool indices_consistent(const exvector &v1, const exvector &v2)
Check whether two sorted index vectors are consistent (i.e.
ex idx_symmetrization(const ex &r, const exvector &local_dummy_indices)
ex minimal_dim(const ex &dim1, const ex &dim2)
Return the minimum of two index dimensions.
const symmetry & not_symmetric()
container< std::list > lst
std::map< ex, ex, ex_is_less > exmap
ex symmetrize(const ex &thisex)
static void find_variant_indices(const exvector &v, exvector &variant_indices)
Given a set of indices, extract those of class varidx.
bool are_ex_trivially_equal(const ex &e1, const ex &e2)
Compare two objects of class quickly without doing a deep tree traversal.
bool reposition_dummy_indices(ex &e, exvector &variant_dummy_indices, exvector &moved_indices)
Raise/lower dummy indices in a single indexed objects to canonicalize their variance.
static ex rename_dummy_indices(const ex &e, exvector &global_dummy_indices, exvector &local_dummy_indices)
Rename dummy indices in an expression.
ex simplify_indexed(const ex &thisex, unsigned options=0)
bool is_dummy_pair(const idx &i1, const idx &i2)
Check whether two indices form a dummy pair.
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 simplify_indexed_product(const ex &e, exvector &free_indices, exvector &dummy_indices, const scalar_products &sp)
Simplify product of indexed expressions (commutative, noncommutative and simple squares),...
ex antisymmetrize(const ex &thisex)
ex op(const ex &thisex, size_t i)
void shaker_sort(It first, It last, Cmp comp, Swap swapit)
ex coeff(const ex &thisex, const ex &s, int n=1)
static ex symm(const ex &e, exvector::const_iterator first, exvector::const_iterator last, bool asymmetric)
int canonicalize(exvector::iterator v, const symmetry &symm)
Canonicalize the order of elements of an expression vector, according to the symmetry properties defi...
static void product_to_exvector(const ex &e, exvector &v, bool &non_commutative)
size_t number_of_type(const exvector &v)
void find_dummy_indices(const exvector &v, exvector &out_dummy)
Given a vector of indices, find the dummy indices.
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...
ex symmetrize_cyclic(const ex &thisex)
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.
void find_free_and_dummy(exvector::const_iterator it, exvector::const_iterator itend, exvector &out_free, exvector &out_dummy)
Given a vector of indices, split them into two vectors, one containing the free indices,...
ex expand_dummy_sum(const ex &e, bool subs_idx)
This function returns the given expression with expanded sums for all dummy index summations,...
std::vector< ex > exvector
bool hasindex(const ex &x, const ex &sym)
exvector get_all_dummy_indices(const ex &e)
Returns all dummy indices from the exvector.
container< std::vector > exprseq
exvector get_all_dummy_indices_safely(const ex &e)
More reliable version of the form.
ex expand(const ex &thisex, unsigned options=0)
Interface to GiNaC's non-commutative products of expressions.
Interface to GiNaC's overloaded operators.
Interface to GiNaC's symbolic exponentiation (basis^exponent).
Interface to relations between expressions.
bool operator()(const ex &lh, const ex &rh) const
bool operator()(const ex &lh, const ex &rh) const
bool operator()(const ex &e)
Interface to GiNaC's symbolic objects.
Interface to GiNaC's symmetry definitions.
Interface to several small and furry utilities needed within GiNaC but not of any interest to the use...