Skip to content

Commit 6b5806c

Browse files
committed
Make ImplicitIndex much more flexible.
1 parent 27b4e95 commit 6b5806c

File tree

9 files changed

+79
-53
lines changed

9 files changed

+79
-53
lines changed

core/Algorithm.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737

3838
#include <sstream>
3939

40-
#define DEBUG
40+
// #define DEBUG
4141

4242
using namespace cadabra;
4343

core/Compare.cc

Lines changed: 59 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,11 +1260,69 @@ int Ex_comparator::can_swap_ilist_ilist(Ex::iterator obj1, Ex::iterator obj2)
12601260
return sign;
12611261
}
12621262

1263+
bool Ex_comparator::can_swap_different_indexsets(Ex::iterator obj1, Ex::iterator obj2)
1264+
{
1265+
std::set<const Indices *> index_sets1;
1266+
// std::cerr << "Are " << obj1 << " and " << obj2 << " swappable?" << std::endl;
1267+
1268+
index_iterator it1=index_iterator::begin(properties, obj1);
1269+
while(it1!=index_iterator::end(properties, obj1)) {
1270+
auto ind = properties.get<Indices>(it1, true);
1271+
if(!ind) return false;
1272+
index_sets1.insert(ind);
1273+
++it1;
1274+
}
1275+
index_iterator it2=index_iterator::begin(properties, obj2);
1276+
while(it2!=index_iterator::end(properties, obj2)) {
1277+
auto ind = properties.get<Indices>(it2, true);
1278+
if(!ind) return false;
1279+
if(index_sets1.find(ind)!=index_sets1.end()) {
1280+
// std::cerr << "NO" << std::endl;
1281+
return false;
1282+
}
1283+
++it2;
1284+
}
1285+
// std::cerr << "YES" << std::endl;
1286+
return true;
1287+
}
1288+
12631289
int Ex_comparator::can_swap(Ex::iterator one, Ex::iterator two, match_t subtree_comparison,
1264-
bool ignore_implicit_indices)
1290+
bool ignore_implicit_indices)
12651291
{
12661292
// std::cerr << "can_swap " << *one->name << " " << *two->name << " " << ignore_implicit_indices << std::endl;
12671293

1294+
// Explicitly declared commutation behaviour goes first.
1295+
const CommutingBehaviour *com = properties.get_composite<CommutingBehaviour>(one, two, true);
1296+
if(com)
1297+
return com->sign();
1298+
1299+
1300+
// If both objects have implicit indices, we cannot swap the
1301+
// objects because that would re-order the index line. The sole
1302+
// exception is when these indices are explicitly stated to be in
1303+
// different sets.
1304+
1305+
const ImplicitIndex *ii1 = properties.get_composite<ImplicitIndex>(one);
1306+
const ImplicitIndex *ii2 = properties.get_composite<ImplicitIndex>(two);
1307+
if(!ignore_implicit_indices) {
1308+
if(ii1) {
1309+
if(ii1->explicit_form.size()==0) {
1310+
if(ii2) return 0; // nothing known about explicit form
1311+
}
1312+
else one=ii1->explicit_form.begin();
1313+
}
1314+
if(ii2) {
1315+
if(ii2->explicit_form.size()==0) {
1316+
if(ii1) return 0; // nothing known about explicit form
1317+
}
1318+
else two=ii2->explicit_form.begin();
1319+
}
1320+
// Check that indices in one and two are in mutually exclusive sets.
1321+
if(ii1 && ii2)
1322+
if(!can_swap_different_indexsets(one, two))
1323+
return false;
1324+
}
1325+
12681326
// Differential forms in a product cannot be moved through each
12691327
// other except when the degree of one of them is zero. In a wedge
12701328
// product, we can move them and potentially pick up a sign.
@@ -1287,43 +1345,6 @@ int Ex_comparator::can_swap(Ex::iterator one, Ex::iterator two, match_t subtree_
12871345
}
12881346
}
12891347
}
1290-
1291-
const ImplicitIndex *ii1 = properties.get_composite<ImplicitIndex>(one);
1292-
const ImplicitIndex *ii2 = properties.get_composite<ImplicitIndex>(two);
1293-
1294-
// When both objects carry an implicit index but the index lines are not connected,
1295-
// we should not be using explicit commutation rules, as this would mess up the
1296-
// index lines and make the expression meaningless.
1297-
// FIXME: this would ideally make use of index and conjugate index lines.
1298-
1299-
const DiracBar *db2 = properties.get_composite<DiracBar>(two);
1300-
if(! (ii1 && ii2 && db2) ) {
1301-
1302-
// First of all, check whether there is an explicit declaration for the commutativity
1303-
// of these two symbols.
1304-
// std::cout << *one->name << " explicit " << *two->name << std::endl;
1305-
const CommutingBehaviour *com = properties.get_composite<CommutingBehaviour>(one, two, true);
1306-
1307-
if(com) {
1308-
// std::cout << typeid(com).name() << std::endl;
1309-
// std::cout << "explicit " << com->sign() << std::endl;
1310-
return com->sign();
1311-
}
1312-
}
1313-
1314-
if(ignore_implicit_indices==false) {
1315-
// Two implicit-index objects cannot move through each other if they have the
1316-
// same type of implicit index.
1317-
// std::cout << "can_swap " << *one->name << " " << *two->name << std::endl;
1318-
1319-
if(ii1 && ii2) {
1320-
if(ii1->set_names.size()==0 && ii2->set_names.size()==0) return 0; // empty index name
1321-
for(size_t n1=0; n1<ii1->set_names.size(); ++n1)
1322-
for(size_t n2=0; n2<ii2->set_names.size(); ++n2)
1323-
if(ii1->set_names[n1]==ii2->set_names[n2])
1324-
return 0;
1325-
}
1326-
}
13271348

13281349
// Do we need to use Self* properties?
13291350
const SelfCommutingBehaviour *sc1 =properties.get_composite<SelfCommutingBehaviour>(one, true);

core/Compare.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@ class Ex_comparator {
337337
int can_swap_prod_sum(Ex::iterator prod, Ex::iterator sum, bool) ;
338338
int can_swap_sum_sum(Ex::iterator sum1, Ex::iterator sum2, bool) ;
339339
int can_swap_ilist_ilist(Ex::iterator obj1, Ex::iterator obj2);
340+
bool can_swap_different_indexsets(Ex::iterator obj1, Ex::iterator obj2);
340341

341342
std::string tab() const;
342343
match_t report(match_t r) const;

core/properties/DifferentialForm.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
namespace cadabra {
1010

11-
class DifferentialForm : public ImplicitIndex, public IndexInherit, public DifferentialFormBase {
11+
class DifferentialForm : public IndexInherit, public DifferentialFormBase {
1212
public:
1313
virtual std::string name() const override;
1414
virtual bool parse(Kernel&, keyval_t&) override;

core/properties/ImplicitIndex.cc

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ bool ImplicitIndex::parse(Kernel&, keyval_t& keyvals)
1515
while(ki!=keyvals.end()) {
1616
// std::cout << "ImplicitIndex: " << ki->first << " = " << *ki->second->name << std::endl;
1717
if(ki->first=="name") {
18-
if(*ki->second->multiplier!=1) {
19-
throw std::logic_error("ImplicitIndex: use quotes to label names when they start with a number.");
20-
}
21-
set_names.push_back(*ki->second->name);
18+
throw std::logic_error("ImplicitIndex: argument 'name' no longer supported");
19+
}
20+
else if(ki->first=="explicit") {
21+
explicit_form=ki->second;
2222
}
2323
else throw ConsistencyException("Property 'ImplicitIndex' does not accept key '"+ki->first+"'.");
2424
++ki;
@@ -30,8 +30,8 @@ bool ImplicitIndex::parse(Kernel&, keyval_t& keyvals)
3030
void ImplicitIndex::latex(std::ostream& str) const
3131
{
3232
property::latex(str);
33-
for(size_t n=0; n<set_names.size(); ++n) {
34-
if(n>0) str << ", ";
35-
str << set_names[n];
36-
}
33+
// for(size_t n=0; n<set_names.size(); ++n) {
34+
// if(n>0) str << ", ";
35+
// str << set_names[n];
36+
// }
3737
}

core/properties/ImplicitIndex.hh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ namespace cadabra {
99
public:
1010
virtual bool parse(Kernel&, keyval_t&) override;
1111
virtual std::string name() const override;
12-
virtual std::string unnamed_argument() const override { return "name"; };
12+
virtual std::string unnamed_argument() const override { return "explicit"; };
1313
virtual void latex(std::ostream& str) const override;
14-
15-
std::vector<std::string> set_names;
14+
15+
Ex explicit_form;
1616
};
1717

1818
}

frontend/gtkmm/Cadabra.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ void Cadabra::on_open(const Gio::Application::type_vec_files& files, const Glib:
149149

150150
bool Cadabra::open_help(const std::string& nm, const std::string& title)
151151
{
152+
#ifdef DEBUG
153+
std::cerr << "Opening help file " << nm << std::endl;
154+
#endif
152155
std::ifstream fl(nm);
153156
if(fl) {
154157
auto nw = new cadabra::NotebookWindow(this, true);

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ set(RTESTS
7171
factor
7272
field_theory
7373
gamma_paper
74+
implicit
7475
fierz
7576
selecting
7677
kaluza_klein

tests/derivative.cdb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,8 +399,8 @@ test21()
399399

400400
def test22():
401401
__cdbkernel__=create_scope()
402-
{\alpha,\beta,\gamma}::Indices(spinor).
403-
{\theta,\lambda}::ImplicitIndex(spinor).
402+
{\alpha,\beta,\gamma}::Indices().
403+
{\theta,\lambda}::ImplicitIndex().
404404
{\alpha,\beta,\gamma,\theta,\lambda}::AntiCommuting.
405405
D{#}::Derivative.
406406
obj22:= D_{\alpha}{\theta \lambda};

0 commit comments

Comments
 (0)