Skip to content

Commit f5c535d

Browse files
committed
Merge branch 'fix/wedgewedge'
2 parents eabd6cb + cc1765d commit f5c535d

File tree

10 files changed

+125
-52
lines changed

10 files changed

+125
-52
lines changed

core/Cleanup.cc

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "Functional.hh"
44
#include "Algorithm.hh"
55
#include "algorithms/collect_terms.hh"
6+
#include "properties/SelfAntiCommuting.hh"
67
#include "properties/Diagonal.hh"
78
#include "properties/ExteriorDerivative.hh"
89
#include "properties/KroneckerDelta.hh"
@@ -30,7 +31,7 @@ void cleanup_dispatch(const Kernel& kernel, Ex& tr, Ex::iterator& it)
3031
break;
3132
}
3233
// std::cerr << "zero " << changed << std::endl;
33-
if(*it->name=="\\prod") res = cleanup_productlike(kernel, tr, it);
34+
if(*it->name=="\\prod" || *it->name=="\\wedge") res = cleanup_productlike(kernel, tr, it);
3435
changed = changed || res;
3536
// std::cerr << "product " << changed << std::endl;
3637
if(*it->name=="\\sum") res = cleanup_sumlike(kernel, tr, it);
@@ -98,12 +99,13 @@ bool cleanup_productlike(const Kernel& k, Ex&tr, Ex::iterator& it)
9899
{
99100
bool ret=false;
100101

101-
assert(*it->name=="\\prod");
102+
assert(*it->name=="\\prod" || *it->name=="\\wedge");
103+
std::string nm = *it->name;
102104

103105
// Flatten prod children inside this prod node.
104106
auto sib=tr.begin(it);
105107
while(sib!=tr.end(it)) {
106-
if(*sib->name=="\\prod") {
108+
if(*sib->name==nm) {
107109
multiply(it->multiplier, *sib->multiplier);
108110
tr.flatten(sib);
109111
sib=tr.erase(sib);
@@ -136,7 +138,44 @@ bool cleanup_productlike(const Kernel& k, Ex&tr, Ex::iterator& it)
136138
multiply(it->multiplier, mult);
137139
}
138140

139-
// Handle edge cases where the product should collapse to a single node,
141+
// Turn products with two adjacent identical anti-commuting siblings to zero.
142+
if(nm=="\\prod") {
143+
auto s1=tr.begin(it);
144+
auto s2=s1;
145+
++s2;
146+
while(s2!=tr.end(it)) {
147+
auto ac = k.properties.get<SelfAntiCommuting>(s1);
148+
if(ac) {
149+
if(subtree_compare(0, s1, s2)==0) {
150+
tr.erase_children(it);
151+
zero(it->multiplier);
152+
ret=true;
153+
break;
154+
}
155+
}
156+
++s2;
157+
++s1;
158+
}
159+
}
160+
161+
// Turn wedge products containing two identical siblings to zero.
162+
if(nm=="\\wedge") {
163+
auto s1=tr.begin(it);
164+
auto s2=s1;
165+
++s2;
166+
while(s2!=tr.end(it)) {
167+
if(subtree_compare(0, s1, s2)==0) {
168+
tr.erase_children(it);
169+
zero(it->multiplier);
170+
ret=true;
171+
break;
172+
}
173+
++s2;
174+
++s1;
175+
}
176+
}
177+
178+
// Handle edge cases where the product should collapse to a single node,
140179
// e.g. when we have just a single factor, or when the product vanishes.
141180

142181
if(tr.number_of_children(it)==1) { // i.e. from '3*4*7*a*9'

core/DisplayTeX.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ bool DisplayTeX::needs_brackets(Ex::iterator it)
5959
if(parent=="\\pow" && (child=="\\prod" || child=="\\sum" || der)) return true;
6060

6161

62-
if(*tree.parent(it)->name=="\\prod" || *tree.parent(it)->name=="\\frac" || *tree.parent(it)->name=="\\pow") {
62+
if(parent=="\\prod" || parent=="\\frac" || parent=="\\pow" || parent=="\\wedge") {
6363
if(*tree.parent(it)->name!="\\frac" && *it->name=="\\sum") return true;
6464
// if(*tree.parent(it)->name=="\\pow" && (*it->multiplier<0 || (*it->multiplier!=1 && *it->name!="1")) ) return true;
6565
}

core/PythonCdb.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,7 @@ void inject_defaults(Kernel *k)
808808
k->inject_property(new IndexInherit(), make_Ex_from_string("\\frac{#}",false), 0);
809809
k->inject_property(new DependsInherit(), make_Ex_from_string("\\frac{#}",false), 0);
810810

811-
// k->inject_property(new Distributable(), make_Ex_from_string("\\wedge{#}",false), 0);
811+
k->inject_property(new Distributable(), make_Ex_from_string("\\wedge{#}",false), 0);
812812
k->inject_property(new IndexInherit(), make_Ex_from_string("\\wedge{#}",false), 0);
813813
// k->inject_property(new CommutingAsProduct(), make_Ex_from_string("\\prod{#}",false), 0);
814814
k->inject_property(new DependsInherit(), make_Ex_from_string("\\wedge{#}",false), 0);

core/algorithms/distribute.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ Algorithm::result_t distribute::apply(iterator& prod)
100100
}
101101
if(rep.number_of_children(top)==1) { // nothing happened, no sum was present
102102
// prod->fl.mark=0; // handled
103+
// std::cerr << "only one for " << Ex(prod) << std::endl;
103104
return result_t::l_no_action;
104105
}
105106

core/algorithms/factor_out.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,11 @@ Algorithm::result_t factor_out::apply(iterator& it)
115115
// its product sorted), we first sort the collector product.
116116

117117
sort_product sp(kernel, collector);
118+
sp.dont_cleanup(); // otherwise single-factor products will get stripped of the \prod wrapper.
118119
auto coltop=collector.begin();
119-
if(sp.can_apply(coltop))
120+
if(sp.can_apply(coltop)) {
120121
sp.apply(coltop);
122+
}
121123
multiply(prod->multiplier, *coltop->multiplier);
122124
one(coltop->multiplier);
123125

core/algorithms/sort_product.cc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11

2+
#include "Cleanup.hh"
23
#include "algorithms/sort_product.hh"
34

45
using namespace cadabra;
56

67
sort_product::sort_product(const Kernel&k, Ex& tr)
7-
: Algorithm(k, tr), ignore_numbers_(false)
8+
: Algorithm(k, tr), ignore_numbers_(false), cleanup(true)
89
{
910
// if(has_argument("IgnoreNumbers")) {
1011
// txtout << "ignoring numbers" << std::endl;
1112
// ignore_numbers_=true;
1213
// }
1314
}
1415

16+
void sort_product::dont_cleanup()
17+
{
18+
cleanup=false;
19+
}
20+
1521
bool sort_product::can_apply(iterator st)
1622
{
1723
if(*st->name=="\\prod" || *st->name=="\\dot" || *st->name=="\\wedge") return true;
@@ -62,5 +68,8 @@ Algorithm::result_t sort_product::apply(iterator& st)
6268
}
6369
}
6470

71+
if(cleanup)
72+
cleanup_dispatch(kernel, tr, st);
73+
6574
return ret;
6675
}

core/algorithms/sort_product.hh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@ namespace cadabra {
1111

1212
virtual bool can_apply(iterator);
1313
virtual result_t apply(iterator&);
14+
15+
void dont_cleanup();
1416

1517
private:
1618
bool ignore_numbers_;
19+
bool cleanup;
1720
};
1821

1922
}

core/properties/AntiCommuting.cnb

Lines changed: 10 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
1-
21
{
32
"cells" :
43
[
5-
64
{
75
"cell_origin" : "client",
86
"cell_type" : "latex",
97
"cells" :
108
[
11-
129
{
1310
"cell_origin" : "client",
1411
"cell_type" : "latex_view",
@@ -18,25 +15,21 @@
1815
"hidden" : true,
1916
"source" : "\\property{AntiCommuting}{Make objects anti-commuting.}\n\nMakes components anti-commuting, for example"
2017
},
21-
2218
{
2319
"cell_origin" : "client",
2420
"cell_type" : "input",
2521
"cells" :
2622
[
27-
2823
{
2924
"cell_origin" : "server",
3025
"cell_type" : "latex_view",
31-
"source" : "\\begin{dmath*}{}\\text{Attached property AntiCommuting to~}(A, B).\\end{dmath*}"
26+
"source" : "\\begin{dmath*}{}\\text{Attached property AntiCommuting to~}\\left[A,~\\discretionary{}{}{} B\\right].\\end{dmath*}"
3227
},
33-
3428
{
3529
"cell_origin" : "server",
3630
"cell_type" : "latex_view",
3731
"source" : "\\begin{dmath*}{}B A\\end{dmath*}"
3832
},
39-
4033
{
4134
"cell_origin" : "server",
4235
"cell_type" : "latex_view",
@@ -45,13 +38,11 @@
4538
],
4639
"source" : "{A,B}::AntiCommuting;\nex:=B A;\nsort_product(_);"
4740
},
48-
4941
{
5042
"cell_origin" : "client",
5143
"cell_type" : "latex",
5244
"cells" :
5345
[
54-
5546
{
5647
"cell_origin" : "client",
5748
"cell_type" : "latex_view",
@@ -61,19 +52,16 @@
6152
"hidden" : true,
6253
"source" : "It also works for objects with indices:"
6354
},
64-
6555
{
6656
"cell_origin" : "client",
6757
"cell_type" : "input",
6858
"cells" :
6959
[
70-
7160
{
7261
"cell_origin" : "server",
7362
"cell_type" : "latex_view",
7463
"source" : "\\begin{dmath*}{}\\psi_{m} \\chi \\psi_{n}\\end{dmath*}"
7564
},
76-
7765
{
7866
"cell_origin" : "server",
7967
"cell_type" : "latex_view",
@@ -82,13 +70,11 @@
8270
],
8371
"source" : "{\\psi_{m}, \\chi}::AntiCommuting.\nex:= \\psi_{m} \\chi \\psi_{n};\nsort_product(_);"
8472
},
85-
8673
{
8774
"cell_origin" : "client",
8875
"cell_type" : "latex",
8976
"cells" :
9077
[
91-
9278
{
9379
"cell_origin" : "client",
9480
"cell_type" : "latex_view",
@@ -98,13 +84,11 @@
9884
"hidden" : true,
9985
"source" : "If you want a pattern like \\verb|\\psi_{m}| to anti-commute with\nitself, you should use the \\prop{SelfAntiCommuting} property instead."
10086
},
101-
10287
{
10388
"cell_origin" : "client",
10489
"cell_type" : "latex",
10590
"cells" :
10691
[
107-
10892
{
10993
"cell_origin" : "client",
11094
"cell_type" : "latex_view",
@@ -114,59 +98,50 @@
11498
"hidden" : true,
11599
"source" : "You can think about the difference\nbetween \\prop{SelfAntiCommuting} and \\prop{AntiCommuting} in\nthe following way. If \\verb|A_{m n}| is \\prop{SelfAntiCommuting}, it\nmeans that for each value of the indices the expression \\verb|A_{m n}|\nis an operator which anti-commutes with the operator for any other\nvalue of the indices. The matrix~$A$ is thus a matrix of\noperator-valued components which mutually anti-commute. On the other\nhand, if \\verb|A| and\n \\verb|B| are declared to\nbe \\prop{AntiCommuting}, then these can be viewed as two matrices of\ncommuting components, whose matrix product satisfies~$A B = - B A$."
116100
},
117-
118101
{
119102
"cell_origin" : "client",
120103
"cell_type" : "latex",
121104
"cells" :
122105
[
123-
124106
{
125107
"cell_origin" : "client",
126108
"cell_type" : "latex_view",
127-
"source" : "If you attach the \\prop|AntiCommuting| property to an object\nwith an \\prop{ImplicitIndex} property, the commutation property does\nnot refer to the object as a whole, but rather to its components. The\nlogic behind that becomes clear when considering e.g.~spinor bilinears,"
109+
"source" : "If you attach the \\prop{AntiCommuting} property to an object\nwith an \\prop{ImplicitIndex} property, the commutation property does\nnot refer to the object as a whole, but rather to its components. The\nlogic behind that becomes clear when considering e.g.~spinor bilinears,"
128110
}
129111
],
130112
"hidden" : true,
131-
"source" : "If you attach the \\prop|AntiCommuting| property to an object\nwith an \\prop{ImplicitIndex} property, the commutation property does\nnot refer to the object as a whole, but rather to its components. The\nlogic behind that becomes clear when considering e.g.~spinor bilinears,"
113+
"source" : "If you attach the \\prop{AntiCommuting} property to an object\nwith an \\prop{ImplicitIndex} property, the commutation property does\nnot refer to the object as a whole, but rather to its components. The\nlogic behind that becomes clear when considering e.g.~spinor bilinears,"
132114
},
133-
134115
{
135116
"cell_origin" : "client",
136117
"cell_type" : "input",
137118
"cells" :
138119
[
139-
140120
{
141121
"cell_origin" : "server",
142122
"cell_type" : "latex_view",
143-
"source" : "\\begin{dmath*}{}\\text{Attached property Spinor to~}(\\chi, \\psi).\\end{dmath*}"
123+
"source" : "\\begin{dmath*}{}\\text{Attached property Spinor to~}\\left[\\chi,~\\discretionary{}{}{} \\psi\\right].\\end{dmath*}"
144124
},
145-
146125
{
147126
"cell_origin" : "server",
148127
"cell_type" : "latex_view",
149-
"source" : "\\begin{dmath*}{}\\text{Attached property AntiCommuting to~}(\\chi, \\psi).\\end{dmath*}"
128+
"source" : "\\begin{dmath*}{}\\text{Attached property AntiCommuting to~}\\left[\\chi,~\\discretionary{}{}{} \\psi\\right].\\end{dmath*}"
150129
},
151-
152130
{
153131
"cell_origin" : "server",
154132
"cell_type" : "latex_view",
155133
"source" : "\\begin{dmath*}{}\\text{Attached property DiracBar to~}\\bar{\\#}.\\end{dmath*}"
156134
},
157-
158135
{
159136
"cell_origin" : "server",
160137
"cell_type" : "latex_view",
161-
"source" : "\\begin{dmath*}{}\\text{Attached property GammaMatrix to~}\\Gamma(\\#).\\end{dmath*}"
138+
"source" : "\\begin{dmath*}{}\\text{Attached property GammaMatrix to~}\\Gamma\\left(\\#\\right).\\end{dmath*}"
162139
},
163-
164140
{
165141
"cell_origin" : "server",
166142
"cell_type" : "latex_view",
167-
"source" : "\\begin{dmath*}{}\\text{Attached property SortOrder to~}(\\chi, \\psi).\\end{dmath*}"
143+
"source" : "\\begin{dmath*}{}\\text{Attached property SortOrder to~}\\left[\\chi,~\\discretionary{}{}{} \\psi\\right].\\end{dmath*}"
168144
},
169-
170145
{
171146
"cell_origin" : "server",
172147
"cell_type" : "latex_view",
@@ -175,13 +150,11 @@
175150
],
176151
"source" : "{\\chi, \\psi}::Spinor(dimension=10, type=MajoranaWeyl);\n{\\chi, \\psi}::AntiCommuting;\n\\bar{#}::DiracBar;\n\\Gamma{#}::GammaMatrix;\n{\\chi, \\psi}::SortOrder;\nex:=\\bar{\\psi} \\Gamma_{m n p} \\chi;"
177152
},
178-
179153
{
180154
"cell_origin" : "client",
181155
"cell_type" : "input",
182156
"cells" :
183157
[
184-
185158
{
186159
"cell_origin" : "server",
187160
"cell_type" : "latex_view",
@@ -190,28 +163,24 @@
190163
],
191164
"source" : "sort_product(_);"
192165
},
193-
194166
{
195167
"cell_origin" : "client",
196168
"cell_type" : "input",
197169
"cells" :
198170
[
199-
200171
{
201172
"cell_origin" : "server",
202-
"cell_type" : "error",
203-
"source" : "{\\color{red}{\\begin{verbatim}Traceback (most recent call last):\n File \"<string>\", line 1, in <module>\nNameError: name 'sort_spinors' is not defined\n\\end{verbatim}}}"
173+
"cell_type" : "latex_view",
174+
"source" : "\\begin{dmath*}{}\\bar{\\chi} \\Gamma_{m n p} \\psi\\end{dmath*}"
204175
}
205176
],
206177
"source" : "sort_spinors(_);"
207178
},
208-
209179
{
210180
"cell_origin" : "client",
211181
"cell_type" : "latex",
212182
"cells" :
213183
[
214-
215184
{
216185
"cell_origin" : "client",
217186
"cell_type" : "latex_view",
@@ -221,14 +190,12 @@
221190
"hidden" : true,
222191
"source" : "Here \\algo{sort_product} did not act because both the spinors and\nthe gamma matrices have the \\prop{ImplicitIndex} property and\nthere are thus no simple rules for their re-ordering. However,\nthe \\algo{sort_spinors} algorithm did act, and took into account\nthe fact that the components of the spinors are anti-commuting."
223192
},
224-
225193
{
226194
"cell_origin" : "client",
227195
"cell_type" : "input",
228196
"source" : ""
229197
}
230198
],
231199
"description" : "Cadabra JSON notebook format",
232-
"version" : 1.0
200+
"version" : 1
233201
}
234-

0 commit comments

Comments
 (0)