Skip to content

Commit 0760fe5

Browse files
author
Dominic Price
committed
fixed issue where some zeroes were not being removed causing matching errors
1 parent b02af61 commit 0760fe5

File tree

3 files changed

+58
-37
lines changed

3 files changed

+58
-37
lines changed

core/algorithms/young_reduce.cc

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -159,21 +159,21 @@ namespace cadabra {
159159
return factor;
160160
}
161161

162-
void ProjectedForm::combine(const ProjectedForm& other, mpq_class factor)
162+
void ProjectedForm::combine(const ProjectedForm& other)
163163
{
164-
if (factor == 1) {
165-
for (const auto& kv : other.data) {
166-
data[kv.first] += kv.second;
167-
if (data[kv.first] == 0)
168-
data.erase(kv.first);
169-
}
164+
for (const auto& kv : other.data) {
165+
data[kv.first] += kv.second;
166+
if (data[kv.first] == 0)
167+
data.erase(kv.first);
170168
}
171-
else {
172-
for (const auto& kv : other.data) {
173-
data[kv.first] += kv.second * factor;
174-
if (data[kv.first] == 0)
175-
data.erase(kv.first);
176-
}
169+
}
170+
171+
void ProjectedForm::combine(const ProjectedForm& other, mpq_class factor)
172+
{
173+
for (const auto& kv : other.data) {
174+
data[kv.first] += kv.second * factor;
175+
if (data[kv.first] == 0)
176+
data.erase(kv.first);
177177
}
178178
}
179179

@@ -190,7 +190,8 @@ namespace cadabra {
190190

191191
void ProjectedForm::insert(adjform_t adjform, mpq_class value)
192192
{
193-
data[adjform] = value;
193+
if (value != 0)
194+
data[adjform] = value;
194195
}
195196

196197
void ProjectedForm::apply_young_symmetry(const adjform_t& indices, bool antisymmetric)
@@ -221,6 +222,8 @@ namespace cadabra {
221222
}
222223
cdebug << "\tMade term " << adjform_to_string(ret) << " * " << (parity * kv.second) << '\n';
223224
data[ret] += parity * kv.second;
225+
if (data[ret] == 0)
226+
data.erase(ret);
224227
} while (swaps = next_perm(perm));
225228
}
226229
}
@@ -258,8 +261,6 @@ namespace cadabra {
258261
Ex::iterator l1 = lhs.begin(), l2 = lhs.end();
259262
Ex::iterator r1 = rhs.begin(), r2 = rhs.end();
260263

261-
std::vector<Ex::iterator> l_indices, r_indices;
262-
263264
// Loop over all tree nodes using a depth first iterator. If the
264265
// entry is an index ensure that it has the same parent_rel, if it
265266
// is any other type of node check that the names match.
@@ -270,8 +271,6 @@ namespace cadabra {
270271
if (l1->fl.parent_rel != r1->fl.parent_rel) {
271272
return false;
272273
}
273-
l_indices.push_back(l1);
274-
r_indices.push_back(r1);
275274
}
276275
else {
277276
if (l1->name != r1->name || l1->multiplier != r1->multiplier) {
@@ -284,6 +283,18 @@ namespace cadabra {
284283
return l1 == l2 && r1 == r2;
285284
}
286285

286+
bool has_TableauBase(Ex::iterator it, const cadabra::Kernel& kernel)
287+
{
288+
if (*it->name == "\\prod" || *it->name == "\\sum") {
289+
for (Ex::sibling_iterator beg = it.begin(), end = it.end(); beg != end; ++beg)
290+
if (has_TableauBase(beg, kernel))
291+
return true;
292+
}
293+
else {
294+
return (kernel.properties.get_composite<cadabra::TableauBase>(it) != nullptr);
295+
}
296+
}
297+
287298
std::vector<Ex::iterator> split_ex(Ex::iterator it, const std::string& delim)
288299
{
289300
if (*it->name == delim) {
@@ -368,7 +379,12 @@ young_reduce::~young_reduce()
368379

369380
bool young_reduce::can_apply(iterator it)
370381
{
371-
return true;
382+
if (pat == Ex::iterator()) {
383+
// check for TableauBase
384+
return has_TableauBase(it, kernel);
385+
}
386+
else
387+
return true;
372388
}
373389

374390
young_reduce::result_t young_reduce::apply(iterator& it)
@@ -513,17 +529,13 @@ bool young_reduce::set_pattern(Ex::iterator new_pat)
513529
throw std::runtime_error("pat is empty");
514530

515531
cdebug << "Checking for TableauBase property...";
516-
bool has_tableau_symmetry = false;
517-
for (const auto& term: collect) {
518-
if (kernel.properties.get_composite<TableauBase>(term) != nullptr) {
519-
has_tableau_symmetry = true;
520-
break;
521-
}
522-
}
523-
cdebug << (has_tableau_symmetry ? "true!" : "false - exiting...") << '\n';
524-
525-
if (!has_tableau_symmetry)
532+
if (!has_TableauBase(new_pat, kernel)) {
533+
cdebug << "false, returning...\n";
526534
return false;
535+
}
536+
else {
537+
cdebug << "true!\n";
538+
}
527539

528540
pat = new_pat;
529541
pat_sym = symmetrize(new_pat);

core/algorithms/young_reduce.hh

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ namespace cadabra {
2222
mpq_class compare(const ProjectedForm& other) const;
2323

2424
// Add all contributions from 'other' into 'this'
25-
void combine(const ProjectedForm& other, mpq_class factor = 1);
25+
void combine(const ProjectedForm& other);
26+
void combine(const ProjectedForm& other, mpq_class factor);
2627

2728
// Multiply all terms by a constant factor
2829
void multiply(mpq_class k);
@@ -47,17 +48,17 @@ namespace cadabra {
4748
// Checks if 'lhs' and 'rhs' are identical up to index names
4849
bool check_structure(Ex::iterator lhs, Ex::iterator rhs);
4950

51+
// Check for a TableauBase property (potentially deep)
52+
bool has_TableauBase(Ex::iterator it, const Kernel& kernel);
53+
5054
// Returns a list of iterators of the children of 'it' if it->name
5155
// is delim, otherwise returns a list containing 'it' as its only
5256
// entry. If 'pat' is specified, any terms not matching 'pat' are
5357
// ignored
5458
std::vector<Ex::iterator> split_ex(Ex::iterator it, const std::string& delim);
5559
std::vector<Ex::iterator> split_ex(Ex::iterator it, const std::string& delim, Ex::iterator pat);
5660

57-
// Rewrite adjform type indices as dummy indices
5861
adjform_t collapse_dummy_indices(adjform_t adjform);
59-
60-
// Rewrite dummy indices as adjform type indices
6162
adjform_t expand_dummy_indices(adjform_t adjform);
6263
}
6364

tests/youngreduce.cdb

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ def test01():
66
S_{a b c}::Symmetric;
77
ex:= S_{a b c}S_{b a c} + S_{b a c}S_{c a b}:
88
young_reduce(ex, $S_{a b c}S_{a b c}$)
9-
display(ex)
109
assert(ex == $2S_{a b c}S_{a b c}$)
1110
print("Test 01 passed")
1211

@@ -138,7 +137,8 @@ def test13():
138137
R_{a b c d}::RiemannTensor.
139138
A^{a b c}::AntiSymmetric.
140139
ex:= R_{a b c d} A^{a b c}:
141-
young_reduce(ex, $R_{a b c d} A^{a b c}$)
140+
young_reduce(ex)
141+
#young_reduce(ex, $R_{a b c d} A^{a b c}$)
142142
assert ex==0
143143
print("Test 13 passed")
144144

@@ -147,8 +147,7 @@ test13()
147147
def test14():
148148
__cdbkernel__ = create_scope()
149149
A_{a b c d e}::AntiSymmetric.
150-
ex = young_reduce($9A_{b a c e d} - 3A_{e d c b a}$, $A_{b a c e d}$)
151-
display(ex)
150+
ex = young_reduce($9A_{b a c e d} - 3A_{e d c b a}$, $7A_{b a c e d}$)
152151
assert ex == $6A_{b a c e d}$
153152
print("Test 14 passed")
154153

@@ -164,3 +163,12 @@ def test15():
164163
print("Test 15 passed")
165164

166165
test15()
166+
167+
def test16():
168+
__cdbkernel__ = create_scope()
169+
S_{a b c}::Symmetric.
170+
assert young_reduce($a + b + c$) == $a + b + c$
171+
assert young_reduce($0$) == $0$
172+
print("Test 16 passed")
173+
174+
test16()

0 commit comments

Comments
 (0)