100indexed::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)
107 seq.insert(
seq.end(), v.begin(), v.end());
113 seq.insert(
seq.end(), v.begin(), v.end());
135 inherited::read_archive(
n, sym_lst);
136 if (!
n.find_ex(
"symmetry",
symtree, sym_lst)) {
139 n.find_unsigned(
"symmetry",
symm);
158 inherited::archive(
n);
168 if (
seq.size() > 1) {
170 auto it =
seq.begin() + 1, itend =
seq.end();
172 if (is_a<print_latex>(
c)) {
176 bool covariant =
true;
178 while (it != itend) {
179 bool cur_covariant = (is_a<varidx>(*it) ? ex_to<varidx>(*it).is_covariant() :
true);
180 if (first || cur_covariant != covariant) {
184 covariant = cur_covariant;
200 while (it != itend) {
211 c.s << openbrace <<
'(';
217 c.s <<
')' << closebrace;
232 c.s << std::string(level,
' ') << class_name() <<
" @" <<
this
233 << std::hex <<
", hash=0x" <<
hashvalue <<
", flags=0x" <<
flags << std::dec
234 <<
", " <<
seq.size()-1 <<
" indices"
235 <<
", symmetry=" <<
symtree << std::endl;
244 return inherited::info(inf);
254 return find_if(
seq.begin() + 1,
seq.end(),
255 [inf](
const ex & e) { return !(ex_to<idx>(e).get_value().info(inf)); }) ==
seq.end();
261 return inherited::compare_same_type(other);
266 const ex &base =
seq[0];
273 if (is_exactly_a<mul>(base) && is_exactly_a<numeric>(base.
op(base.
nops() - 1))) {
275 ex f = ex_to<numeric>(base.
op(base.
nops() - 1));
280 if((
typeid(*
this) ==
typeid(
indexed)) &&
seq.size()==1)
284 if (
seq.size() > 2) {
288 if (sig != std::numeric_limits<int>::max()) {
297 return ex_to<basic>(base).eval_indexed(*
this);
304 return real_part_function(*this).hold();
311 return imag_part_function(*this).hold();
326 if(is_a<matrix>(
op(0)))
338 if (is_exactly_a<add>(newbase)) {
340 for (
size_t i=0; i<newbase.
nops(); i++) {
342 s[0] = newbase.
op(i);
353 return inherited::expand(
options);
372 auto it =
seq.begin() + 1, itend =
seq.end();
373 while (it != itend) {
375 throw(std::invalid_argument(
"indices of indexed object must be of type idx"));
380 if (!is_exactly_a<symmetry>(
symtree))
381 throw(std::invalid_argument(
"symmetry of indexed object must be of type symmetry"));
407 return lh.
is_equal(ex_to<idx>(rh).replace_dim(ex_to<idx>(lh).get_dim()));
418 if (v1.size() != v2.size())
432 exvector free_indices, dummy_indices;
434 return dummy_indices;
441 indices.insert(indices.end(), other_indices.begin(), other_indices.end());
444 return dummy_indices;
449 auto it =
seq.begin() + 1, itend =
seq.end();
450 while (it != itend) {
460 exvector free_indices, dummy_indices;
468 for (
size_t i=0; i<
nops(); i++) {
474 throw (std::runtime_error(
"add::get_free_indices: inconsistent indices in sum"));
484 for (
size_t i=0; i<
nops(); i++) {
486 un.insert(un.end(), free_indices_of_factor.begin(), free_indices_of_factor.end());
490 exvector free_indices, dummy_indices;
499 for (
size_t i=0; i<
nops(); i++) {
501 un.insert(un.end(), free_indices_of_factor.begin(), free_indices_of_factor.end());
505 exvector free_indices, dummy_indices;
520 throw (std::runtime_error(
"integral::get_free_indices: boundary values should not have free indices"));
528 if (is_exactly_a<T>(it))
543 size_t global_size = number_of_type<T>(global_dummy_indices),
544 local_size = number_of_type<T>(local_dummy_indices);
550 if (global_size < local_size) {
554 size_t old_global_size = global_size;
555 int remaining = local_size - global_size;
556 auto it = local_dummy_indices.
begin(), itend = local_dummy_indices.end();
557 while (it != itend && remaining > 0) {
558 if (is_exactly_a<T>(*it) &&
559 find_if(global_dummy_indices.begin(), global_dummy_indices.end(),
560 [it](
const ex &lh) { return idx_is_equal_ignore_dim()(lh, *it); }) == global_dummy_indices.end()) {
561 global_dummy_indices.push_back(*it);
569 if (old_global_size == 0)
576 local_syms.reserve(local_size);
577 global_syms.reserve(local_size);
578 for (
size_t i=0; local_syms.size()!=local_size; i++)
579 if(is_exactly_a<T>(local_dummy_indices[i]))
580 local_syms.push_back(local_dummy_indices[i].
op(0));
582 for (
size_t i=0; global_syms.size()!=local_size; i++)
583 if(is_exactly_a<T>(global_dummy_indices[i]))
584 global_syms.push_back(global_dummy_indices[i].
op(0));
589 set_difference(local_syms.begin(), local_syms.end(), global_syms.begin(), global_syms.end(), std::back_insert_iterator<exvector>(local_uniq),
ex_is_less());
590 set_difference(global_syms.begin(), global_syms.end(), local_syms.begin(), local_syms.end(), std::back_insert_iterator<exvector>(global_uniq),
ex_is_less());
593 if (local_uniq.empty())
596 while (global_uniq.size() > local_uniq.size())
597 global_uniq.pop_back();
605 exvector::const_iterator it1, itend;
606 for (it1 = v.begin(), itend = v.end(); it1 != itend; ++it1) {
607 if (is_exactly_a<varidx>(*it1))
608 variant_indices.push_back(*it1);
621 bool something_changed =
false;
625 local_var_dummies.reserve(e.
nops()/2);
626 for (
size_t i=1; i<e.
nops(); ++i) {
627 if (!is_a<varidx>(e.
op(i)))
629 for (
size_t j=i+1; j<e.
nops(); ++j) {
631 local_var_dummies.push_back(e.
op(i));
632 for (
auto k = variant_dummy_indices.begin();
k!=variant_dummy_indices.end(); ++
k) {
633 if (e.
op(i).
op(0) ==
k->
op(0)) {
634 variant_dummy_indices.erase(
k);
647 size_t numpossibs = 1 << local_var_dummies.size();
648 for (
size_t i=0; i<numpossibs; ++i) {
650 for (
size_t j=0; j<local_var_dummies.size(); ++j) {
653 ex curr_idx = local_var_dummies[j];
654 ex curr_toggle = ex_to<varidx>(curr_idx).toggle_variance();
655 m[curr_idx] = curr_toggle;
656 m[curr_toggle] = curr_idx;
662 something_changed =
true;
667 if (!is_a<indexed>(e))
670 exvector seq = ex_to<indexed>(e).seq;
674 for (
auto it2 = seq.begin()+1, it2end = seq.end(); it2 != it2end; ++it2) {
675 if (!is_exactly_a<varidx>(*it2))
678 exvector::iterator vit, vitend;
679 for (vit = variant_dummy_indices.begin(), vitend = variant_dummy_indices.end(); vit != vitend; ++vit) {
680 if (it2->op(0).is_equal(vit->op(0))) {
681 if (ex_to<varidx>(*it2).is_covariant()) {
694 *it2 = ex_to<varidx>(*it2).toggle_variance();
695 something_changed =
true;
697 moved_indices.push_back(*vit);
698 variant_dummy_indices.erase(vit);
703 for (vit = moved_indices.begin(), vitend = moved_indices.end(); vit != vitend; ++vit) {
704 if (it2->op(0).is_equal(vit->op(0))) {
705 if (ex_to<varidx>(*it2).is_contravariant()) {
706 *it2 = ex_to<varidx>(*it2).toggle_variance();
707 something_changed =
true;
716 if (something_changed)
717 e = ex_to<indexed>(e).thiscontainer(seq);
719 return something_changed;
726 return (is_a<indexed>(lh) ? lh.
op(0) : lh).compare(is_a<indexed>(rh) ? rh.
op(0) : rh) < 0;
736 non_commutative = is_exactly_a<ncmul>(e);
739 v.reserve(e.
nops() * 2);
741 if (is_exactly_a<power>(e)) {
744 v.push_back(e.
op(0));
745 v.push_back(e.
op(0));
747 for (
size_t i=0; i<e.
nops(); i++) {
750 v.push_back(f.
op(0));
751 v.push_back(f.
op(0));
752 }
else if (is_exactly_a<ncmul>(f)) {
754 non_commutative =
true;
755 for (
size_t j=0; j<f.
nops(); j++)
756 v.push_back(f.
op(j));
765 dummy_syms.reserve(
r.nops());
766 for (
auto & it : local_dummy_indices)
767 if(is_exactly_a<T>(it))
768 dummy_syms.push_back(it.op(0));
769 if(dummy_syms.size() < 2)
787 bool non_commutative;
791 bool something_changed =
false;
792 bool has_nonsymmetric =
false;
794 exvector::iterator it1, itend = v.end(), next_to_last = itend - 1;
795 for (it1 = v.begin(); it1 != next_to_last; it1++) {
798 if (!is_a<indexed>(*it1))
802 bool first_nonsymmetric = ex_to<symmetry>(ex_to<indexed>(*it1).get_symmetry()).has_nonsymmetric();
807 find_free_and_dummy(ex_to<indexed>(*it1).seq.begin() + 1, ex_to<indexed>(*it1).seq.end(), free1, dummy1);
809 exvector::iterator it2;
810 for (it2 = it1 + 1; it2 != itend; it2++) {
812 if (!is_a<indexed>(*it2))
820 find_free_and_dummy(ex_to<indexed>(*it2).seq.begin() + 1, ex_to<indexed>(*it2).seq.end(), un, dummy1);
821 un.insert(un.end(), free1.begin(), free1.end());
826 size_t num_dummies = dummy.size();
827 if (num_dummies == 0)
831 bool contracted =
false;
832 if (free.empty() && it1->nops()==2 && it2->nops()==2) {
835 ex_to<idx>(it1->op(1)).get_dim(),
836 ex_to<idx>(it2->op(1)).get_dim()
843 *it1 = sp.
evaluate(*it1, *it2, dim);
845 goto contraction_done;
850 contracted = ex_to<basic>(it1->op(0)).contract_with(it1, it2, v);
855 contracted = ex_to<basic>(it2->op(0)).contract_with(it2, it1, v);
859 if (first_noncommutative || second_noncommutative
860 || is_exactly_a<add>(*it1) || is_exactly_a<add>(*it2)
861 || is_exactly_a<mul>(*it1) || is_exactly_a<mul>(*it2)
862 || is_exactly_a<ncmul>(*it1) || is_exactly_a<ncmul>(*it2)) {
869 bool is_a_product = (is_exactly_a<mul>(*it1) || is_exactly_a<ncmul>(*it1)) &&
870 (is_exactly_a<mul>(*it2) || is_exactly_a<ncmul>(*it2));
871 ex r = (non_commutative ?
ex(
ncmul(std::move(v))) :
ex(
mul(std::move(v))));
884 something_changed =
true;
887 else if (!has_nonsymmetric &&
888 (first_nonsymmetric ||
889 ex_to<symmetry>(ex_to<indexed>(*it2).get_symmetry()).has_nonsymmetric())) {
890 has_nonsymmetric =
true;
897 exvector un, individual_dummy_indices;
898 for (it1 = v.begin(), itend = v.end(); it1 != itend; ++it1) {
900 if (is_a<indexed>(*it1)) {
902 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);
903 individual_dummy_indices.insert(individual_dummy_indices.end(), dummy_indices_of_factor.begin(), dummy_indices_of_factor.end());
905 free_indices_of_factor = it1->get_free_indices();
906 un.insert(un.end(), free_indices_of_factor.begin(), free_indices_of_factor.end());
910 local_dummy_indices.insert(local_dummy_indices.end(), individual_dummy_indices.begin(), individual_dummy_indices.end());
917 if (!variant_dummy_indices.empty()) {
921 if (!non_commutative)
927 for (it1 = v.begin(), itend = v.end(); it1 != itend; ++it1) {
928 if (!is_a<indexed>(*it1))
932 something_changed =
true;
937 if (something_changed)
938 r = non_commutative ?
ex(
ncmul(std::move(v))) :
ex(
mul(std::move(v)));
945 if (has_nonsymmetric) {
946 ex q = idx_symmetrization<idx>(
r, local_dummy_indices);
948 free_indices.clear();
951 q = idx_symmetrization<varidx>(q, local_dummy_indices);
953 free_indices.clear();
956 q = idx_symmetrization<spinidx>(q, local_dummy_indices);
958 free_indices.clear();
964 r = rename_dummy_indices<idx>(
r, dummy_indices, local_dummy_indices);
965 r = rename_dummy_indices<varidx>(
r, dummy_indices, local_dummy_indices);
966 r = rename_dummy_indices<spinidx>(
r, dummy_indices, local_dummy_indices);
969 if (is_exactly_a<mul>(
r) &&
r.nops() == 2
970 && is_exactly_a<numeric>(
r.op(1)) && is_a<indexed>(
r.op(0)))
971 return ex_to<basic>(
r.op(0).op(0)).scalar_mul_indexed(
r.op(0), ex_to<numeric>(
r.op(1)));
1002 if (is_exactly_a<mul>(symmterm_) && is_exactly_a<numeric>(symmterm_.
op(symmterm_.
nops()-1))) {
1035 if(is_a<idx>(
x) &&
x.
op(0)==sym)
1038 for(
size_t i=0; i<
x.
nops(); ++i)
1052 if (is_a<indexed>(e_expanded)) {
1055 const indexed &i = ex_to<indexed>(e_expanded);
1064 if (!variant_dummy_indices.empty()) {
1072 e_expanded = rename_dummy_indices<idx>(e_expanded, dummy_indices, local_dummy_indices);
1073 e_expanded = rename_dummy_indices<varidx>(e_expanded, dummy_indices, local_dummy_indices);
1074 e_expanded = rename_dummy_indices<spinidx>(e_expanded, dummy_indices, local_dummy_indices);
1080 if (is_exactly_a<add>(e_expanded)) {
1083 free_indices.clear();
1085 for (
size_t i=0; i<e_expanded.
nops(); i++) {
1090 free_indices = free_indices_of_term;
1095 std::ostringstream s;
1096 s <<
"simplify_indexed: inconsistent indices in sum: ";
1097 s <<
exprseq(free_indices) <<
" vs. " <<
exprseq(free_indices_of_term);
1098 throw (std::runtime_error(s.str()));
1100 if (is_a<indexed>(sum) && is_a<indexed>(term))
1101 sum = ex_to<basic>(sum.
op(0)).add_indexed(sum, term);
1110 free_indices.clear();
1115 size_t num_terms_orig = (is_exactly_a<add>(sum) ? sum.
nops() : 1);
1116 if (num_terms_orig < 2 || dummy_indices.size() < 2)
1121 std::vector<terminfo> terms;
1122 for (
size_t i=0; i<sum.
nops(); i++) {
1123 const ex & term = sum.
op(i);
1125 dummy_indices_of_term.reserve(dummy_indices.size());
1126 for (
auto & i : dummy_indices)
1128 dummy_indices_of_term.push_back(i);
1129 ex term_symm = idx_symmetrization<idx>(term, dummy_indices_of_term);
1130 term_symm = idx_symmetrization<varidx>(term_symm, dummy_indices_of_term);
1131 term_symm = idx_symmetrization<spinidx>(term_symm, dummy_indices_of_term);
1134 terms.push_back(
terminfo(term, term_symm));
1141 std::vector<terminfo> terms_pass2;
1142 for (std::vector<terminfo>::const_iterator i=terms.begin(); i!=terms.end(); ) {
1145 while (j != terms.end() && j->symm == i->symm) {
1149 terms_pass2.push_back(
terminfo(i->orig * num, i->symm * num));
1154 if (terms_pass2.size() == 1)
1155 return terms_pass2[0].orig;
1158 std::vector<symminfo> sy;
1159 for (
auto & i : terms_pass2) {
1160 if (is_exactly_a<add>(i.symm)) {
1161 size_t num = i.symm.nops();
1162 for (
size_t j=0; j<num; j++)
1163 sy.push_back(
symminfo(i.symm.op(j), i.orig, num));
1165 sy.push_back(
symminfo(i.symm, i.orig, 1));
1172 std::vector<symminfo> sy_pass2;
1174 for (
auto i=sy.begin(); i!=sy.end(); ) {
1178 if (j != sy.end() && j->symmterm == i->symmterm) {
1182 while (j != sy.end() && j->symmterm == i->symmterm) {
1189 result.push_back(
coeff * i->symmterm);
1194 sy_pass2.push_back(*i);
1201 if (sy_pass2.size() > 0) {
1206 for (std::vector<symminfo>::const_iterator i=sy_pass2.begin(); i!=sy_pass2.end(); ) {
1211 while (j != sy_pass2.end() && j->orig == i->orig) {
1216 if (num == i->num) {
1219 result.push_back(i->orig);
1224 std::vector<symminfo>::const_iterator
k;
1225 for (
k=i;
k!=j;
k++)
1226 result.push_back(
k->coeff *
k->symmterm);
1234 ex sum_symm = dynallocate<add>(result);
1236 free_indices.clear();
1241 if (is_exactly_a<mul>(e_expanded)
1242 || is_exactly_a<ncmul>(e_expanded)
1243 || (is_exactly_a<power>(e_expanded) && is_a<indexed>(e_expanded.
op(0)) && e_expanded.
op(1).
is_equal(
_ex2)))
1247 free_indices.clear();
1259 exvector free_indices, dummy_indices;
1274 exvector free_indices, dummy_indices;
1303 ex s1 = is_a<indexed>(v1_) ? v1_.
op(0) : v1_;
1304 ex s2 = is_a<indexed>(v2_) ? v2_.
op(0) : v2_;
1322 if (is_a<wildcard>(
dim) || is_a<wildcard>(other.
dim))
1338 if (is_a<wildcard>(
dim) || is_a<wildcard>(other.
dim))
1346 std::cerr <<
"(" <<
v1 <<
"," <<
v2 <<
"," <<
dim <<
")";
1362 for (
auto & it1 : l)
1363 for (
auto & it2 : l)
1364 add(it1, it2, it1 * it2);
1386 std::cerr <<
"map size=" <<
spm.size() << std::endl;
1387 for (
auto & it :
spm) {
1389 std::cerr <<
"item key=";
1391 std::cerr <<
", value=" << it.second << std::endl;
1397 if (is_a<indexed>(e))
1398 return ex_to<indexed>(e).get_dummy_indices();
1399 else if (is_a<power>(e) && e.
op(1)==2) {
1402 else if (is_a<mul>(e) || is_a<ncmul>(e)) {
1405 for (std::size_t i = 0; i < e.
nops(); ++i) {
1407 dummies.insert(dummies.end(), dummies_of_factor.begin(),
1408 dummies_of_factor.end());
1410 free_indices.insert(free_indices.begin(), free_of_factor.begin(),
1411 free_of_factor.end());
1416 dummies.insert(dummies.end(), dummy_out.begin(), dummy_out.end());
1419 else if(is_a<add>(e)) {
1421 for(std::size_t i = 0; i < e.
nops(); ++i) {
1423 sort(dummies_of_term.begin(), dummies_of_term.end());
1425 set_union(result.begin(), result.end(), dummies_of_term.begin(),
1426 dummies_of_term.end(), std::back_inserter<exvector>(new_vec),
1428 result.swap(new_vec);
1441 auto ip = p.begin(), ipend = p.end();
1443 while (ip != ipend) {
1444 if (is_a<indexed>(*ip)) {
1445 v1 = ex_to<indexed>(*ip).get_dummy_indices();
1446 v.insert(v.end(), v1.begin(), v1.end());
1448 while (ip1 != ipend) {
1449 if (is_a<indexed>(*ip1)) {
1450 v1 = ex_to<indexed>(*ip).get_dummy_indices(ex_to<indexed>(*ip1));
1451 v.insert(v.end(), v1.begin(), v1.end());
1464 set_intersection(va.begin(), va.end(), vb.begin(), vb.end(), std::back_insert_iterator<exvector>(common_indices),
ex_is_less());
1465 if (common_indices.empty()) {
1469 old_indices.
reserve(2*common_indices.size());
1470 new_indices.reserve(2*common_indices.size());
1471 exvector::const_iterator ip = common_indices.begin(), ipend = common_indices.end();
1472 while (ip != ipend) {
1473 ex newsym = dynallocate<symbol>();
1475 if(is_exactly_a<spinidx>(*ip))
1476 newidx = dynallocate<spinidx>(newsym, ex_to<spinidx>(*ip).get_dim(),
1477 ex_to<spinidx>(*ip).is_covariant(),
1478 ex_to<spinidx>(*ip).is_dotted());
1479 else if (is_exactly_a<varidx>(*ip))
1480 newidx = dynallocate<varidx>(newsym, ex_to<varidx>(*ip).get_dim(),
1481 ex_to<varidx>(*ip).is_covariant());
1483 newidx = dynallocate<idx>(newsym, ex_to<idx>(*ip).get_dim());
1484 old_indices.push_back(*ip);
1485 new_indices.push_back(newidx);
1486 if(is_a<varidx>(*ip)) {
1487 old_indices.push_back(ex_to<varidx>(*ip).toggle_variance());
1488 new_indices.push_back(ex_to<varidx>(newidx).toggle_variance());
1492 return lst{
lst(old_indices.begin(), old_indices.end()),
lst(new_indices.begin(), new_indices.end())};
1505 if (va.size() > 0) {
1507 if (vb.size() > 0) {
1511 if (indices_subs.
op(0).
nops() > 0)
1520 if (va.size() > 0) {
1522 if (vb.size() > 0) {
1525 if (indices_subs.
op(0).
nops() > 0) {
1527 for (
auto & i : ex_to<lst>(indices_subs.
op(1)))
1530 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());
1531 for (
auto & ip : uncommon_indices)
1546 if (is_a<add>(e_expanded) || is_a<lst>(e_expanded) || is_a<matrix>(e_expanded)) {
1547 return e_expanded.
map(fcn);
1548 }
else if (is_a<ncmul>(e_expanded) || is_a<mul>(e_expanded) || is_a<power>(e_expanded) || is_a<indexed>(e_expanded)) {
1550 if (is_a<indexed>(e_expanded))
1551 v = ex_to<indexed>(e_expanded).get_dummy_indices();
1554 ex result = e_expanded;
1555 for (
const auto & nu : v) {
1557 int idim = ex_to<numeric>(ex_to<idx>(nu).get_dim()).to_int();
1559 for (
int i=0; i < idim; i++) {
1560 if (subs_idx && is_a<varidx>(nu)) {
1561 ex other = ex_to<varidx>(nu).toggle_variance();
1564 other ==
idx(i, idim)
1567 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
bool find(const ex &pattern, exset &found) const
Find all occurrences of a pattern.
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.
void print(const print_context &c, unsigned level=0) const
Print expression to stream.
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 one index of an indexed object.
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
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.
Interface to GiNaC's non-commutative products of expressions.
Interface to GiNaC's overloaded operators.
Interface to GiNaC's symbolic exponentiation (basis^exponent).
#define GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(classname, supername, options)
Macro for inclusion in the implementation of each registered class.
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...