Skip to content

Commit f0e4597

Browse files
committed
Add Determinant and Trace properties and related logic in complete.
1 parent 115220f commit f0e4597

File tree

14 files changed

+338
-28
lines changed

14 files changed

+338
-28
lines changed

core/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ set(PROPERTY_SRC_FILES
103103
properties/Depends.cc
104104
properties/DependsInherit.cc
105105
properties/Derivative.cc
106+
properties/Determinant.cc
106107
properties/Diagonal.cc
107108
properties/DifferentialForm.cc
108109
properties/DiracBar.cc
@@ -136,6 +137,7 @@ set(PROPERTY_SRC_FILES
136137
properties/Tableau.cc
137138
properties/TableauBase.cc
138139
properties/TableauSymmetry.cc
140+
properties/Trace.cc
139141
properties/Traceless.cc
140142
properties/Vielbein.cc
141143
properties/Weight.cc

core/PythonCdb.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "properties/Depends.hh"
3939
#include "properties/DependsInherit.hh"
4040
#include "properties/Derivative.hh"
41+
#include "properties/Determinant.hh"
4142
#include "properties/DifferentialForm.hh"
4243
#include "properties/DiracBar.hh"
4344
#include "properties/GammaMatrix.hh"
@@ -73,6 +74,7 @@
7374
#include "properties/Symmetric.hh"
7475
#include "properties/Tableau.hh"
7576
#include "properties/TableauSymmetry.hh"
77+
#include "properties/Trace.hh"
7678
#include "properties/Traceless.hh"
7779
#include "properties/Vielbein.hh"
7880
#include "properties/Weight.hh"
@@ -1569,6 +1571,7 @@ PYBIND11_MODULE(cadabra2, m)
15691571
def_prop<DAntiSymmetric>(m);
15701572
def_prop<Depends>(m);
15711573
def_prop<Derivative>(m);
1574+
def_prop<Determinant>(m);
15721575
def_prop<Diagonal>(m);
15731576
def_prop<DifferentialForm>(m);
15741577
def_prop<Distributable>(m);
@@ -1601,6 +1604,7 @@ PYBIND11_MODULE(cadabra2, m)
16011604
def_prop<Symmetric>(m);
16021605
def_prop<Tableau>(m);
16031606
def_prop<TableauSymmetry>(m);
1607+
def_prop<Trace>(m);
16041608
def_prop<Traceless>(m);
16051609
def_prop<Vielbein>(m);
16061610
def_prop<InverseVielbein>(m);

core/SympyCdb.cc

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
using namespace cadabra;
1414

15-
//#define DEBUG 1
15+
// #define DEBUG 1
1616

1717
Ex::iterator sympy::apply(const Kernel& kernel, Ex& ex, Ex::iterator& it, const std::vector<std::string>& wrap, std::vector<std::string> args,
1818
const std::string& method)
@@ -93,7 +93,7 @@ Ex::iterator sympy::apply(const Kernel& kernel, Ex& ex, Ex::iterator& it, const
9393
return it;
9494
}
9595

96-
Ex sympy::invert_matrix(const Kernel& kernel, Ex& ex, Ex& rules)
96+
Ex sympy::fill_matrix(const Kernel& kernel, Ex& ex, Ex& rules)
9797
{
9898
// check that object has two children only.
9999
if(ex.number_of_children(ex.begin())!=2) {
@@ -103,12 +103,6 @@ Ex sympy::invert_matrix(const Kernel& kernel, Ex& ex, Ex& rules)
103103
Ex::iterator ind1=ex.child(ex.begin(), 0);
104104
Ex::iterator ind2=ex.child(ex.begin(), 1);
105105

106-
str_node::parent_rel_t prel;
107-
if(ind1->fl.parent_rel==str_node::p_sub) prel=str_node::p_super;
108-
if(ind1->fl.parent_rel==str_node::p_super) prel=str_node::p_sub;
109-
110-
Ex ret;
111-
112106
// Get Indices property and from there Coordinates.
113107

114108
const Indices *prop1 = kernel.properties.get<Indices>(ind1);
@@ -130,10 +124,8 @@ Ex sympy::invert_matrix(const Kernel& kernel, Ex& ex, Ex& rules)
130124
Ex c(ex.begin());
131125
Ex::iterator cit1=c.child(c.begin(), 0);
132126
Ex::iterator cit2=c.child(c.begin(), 1);
133-
cit1=c.replace(cit1, prop1->values[c1].begin());
134-
cit2=c.replace(cit2, prop1->values[c2].begin());
135-
cit1->fl.parent_rel=prel;
136-
cit2->fl.parent_rel=prel;
127+
cit1=c.replace_index(cit1, prop1->values[c1].begin(), true);
128+
cit2=c.replace_index(cit2, prop1->values[c2].begin(), true);
137129

138130
Ex::iterator cit=c.begin();
139131
substitute subs(kernel, c, rules);
@@ -146,38 +138,80 @@ Ex sympy::invert_matrix(const Kernel& kernel, Ex& ex, Ex& rules)
146138
}
147139
}
148140
}
141+
142+
return matrix;
143+
}
144+
145+
void sympy::invert_matrix(const Kernel& kernel, Ex& ex, Ex& rules, const Ex& tocompute)
146+
{
147+
if(ex.number_of_children(ex.begin())!=2) {
148+
throw ConsistencyException("Object should have exactly two indices.");
149+
}
149150

151+
auto matrix = fill_matrix(kernel, ex, rules);
152+
150153
auto top=matrix.begin();
151154
std::vector<std::string> wrap;
152155
sympy::apply(kernel, matrix, top, wrap, std::vector<std::string>(), ".inv()");
153156
//matrix.print_recursive_treeform(std::cerr, top);
154157

158+
Ex::iterator ind1=ex.child(ex.begin(), 0);
159+
Ex::iterator ind2=ex.child(ex.begin(), 1);
160+
const Indices *prop1 = kernel.properties.get<Indices>(ind1);
161+
const Indices *prop2 = kernel.properties.get<Indices>(ind2);
162+
155163
Ex::iterator ruleslist=rules.begin();
156164

157165
// Now we need to iterate over the components again and construct sparse rules.
158-
cols=matrix.begin(matrix.begin()); // outer comma
166+
auto cols=matrix.begin(matrix.begin()); // outer comma
159167
auto row=matrix.begin(cols); // first inner comma
160168
for(unsigned c1=0; c1<prop1->values.size(); ++c1) {
161169
auto el =matrix.begin(row); // first element of first inner comma
162170
for(unsigned c2=0; c2<prop2->values.size(); ++c2) {
163171
if(el->is_zero()==false) {
164172
Ex rule("\\equals");
165-
auto rit = rule.append_child(rule.begin(), ex.begin());
173+
auto rit = rule.append_child(rule.begin(), tocompute.begin());
166174
auto cvit = rule.append_child(rule.begin(), Ex::iterator(el));
167175
auto i = rule.begin(rit);
168176
//std::cerr << c1 << ", " << c2 << std::endl;
169-
i = rule.replace(i, prop1->values[c1].begin());
170-
i->fl.parent_rel=ind1->fl.parent_rel;
177+
i = rule.replace_index(i, prop1->values[c1].begin(), true);
178+
// i->fl.parent_rel=ind1->fl.parent_rel;
171179
++i;
172-
i = rule.replace(i, prop1->values[c2].begin());
173-
i->fl.parent_rel=ind1->fl.parent_rel;
180+
i = rule.replace_index(i, prop1->values[c2].begin(), true);
181+
// i->fl.parent_rel=ind1->fl.parent_rel;
174182
rules.append_child(ruleslist, rule.begin());
175183
//rule.print_recursive_treeform(std::cerr, rule.begin());
176184
}
177185
++el;
178186
}
179187
++row;
180188
}
189+
}
190+
191+
void sympy::determinant(const Kernel& kernel, Ex& ex, Ex& rules, const Ex& tocompute)
192+
{
193+
auto matrix = fill_matrix(kernel, ex, rules);
194+
195+
auto top=matrix.begin();
196+
std::vector<std::string> wrap;
197+
sympy::apply(kernel, matrix, top, wrap, std::vector<std::string>(), ".det()");
198+
199+
Ex rule("\\equals");
200+
rule.append_child(rule.begin(), tocompute.begin());
201+
rule.append_child(rule.begin(), matrix.begin());
202+
rules.append_child(rules.begin(), rule.begin());
203+
}
204+
205+
void sympy::trace(const Kernel& kernel, Ex& ex, Ex& rules, const Ex& tocompute)
206+
{
207+
auto matrix = fill_matrix(kernel, ex, rules);
208+
209+
auto top=matrix.begin();
210+
std::vector<std::string> wrap;
211+
sympy::apply(kernel, matrix, top, wrap, std::vector<std::string>(), ".tr()");
181212

182-
return ret;
213+
Ex rule("\\equals");
214+
rule.append_child(rule.begin(), tocompute.begin());
215+
rule.append_child(rule.begin(), matrix.begin());
216+
rules.append_child(rules.begin(), rule.begin());
183217
}

core/SympyCdb.hh

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,17 @@ namespace sympy {
4242
/// sparse components. Will return a set of Cadabra rules for the
4343
/// inverse matrix.
4444

45-
cadabra::Ex invert_matrix(const cadabra::Kernel&, cadabra::Ex& ex, cadabra::Ex& rules);
45+
void invert_matrix(const cadabra::Kernel&, cadabra::Ex& ex, cadabra::Ex& rules, const cadabra::Ex& tocompute);
4646

47+
/// \ingroup scalar
48+
///
49+
/// Use Sympy to compute the determinant of a matrix, given a set of rules determining
50+
/// its sparse components. Will add the rules to the list.
51+
52+
void determinant(const cadabra::Kernel&, cadabra::Ex& ex, cadabra::Ex& rules, const cadabra::Ex& tocompute);
53+
void trace(const cadabra::Kernel&, cadabra::Ex& ex, cadabra::Ex& rules, const cadabra::Ex& tocompute);
54+
55+
cadabra::Ex fill_matrix(const cadabra::Kernel&, cadabra::Ex& ex, cadabra::Ex& rules);
4756
// extern Stopwatch sympy_stopwatch;
4857

4958
};

core/algorithms/complete.cc

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include "Functional.hh"
44
#include "properties/Metric.hh"
55
#include "properties/InverseMetric.hh"
6+
#include "properties/Determinant.hh"
7+
#include "properties/Trace.hh"
68
#include "SympyCdb.hh"
79

810
using namespace cadabra;
@@ -26,7 +28,24 @@ Algorithm::result_t complete::apply(iterator& it)
2628
const InverseMetric *invmetric = kernel.properties.get<InverseMetric>(bg);
2729
if(invmetric) {
2830
Ex metric(bg);
29-
sympy::invert_matrix(kernel, metric, tr);
31+
Ex::iterator ind1=metric.child(metric.begin(), 0);
32+
Ex::iterator ind2=metric.child(metric.begin(), 1);
33+
ind1->flip_parent_rel();
34+
ind2->flip_parent_rel();
35+
36+
sympy::invert_matrix(kernel, metric, tr, bg);
37+
res = result_t::l_applied;
38+
}
39+
const Determinant *det = kernel.properties.get<Determinant>(bg);
40+
if(det) {
41+
Ex metric(det->obj);
42+
sympy::determinant(kernel, metric, tr, bg);
43+
res = result_t::l_applied;
44+
}
45+
const Trace *trace = kernel.properties.get<Trace>(bg);
46+
if(trace) {
47+
Ex metric(trace->obj);
48+
sympy::trace(kernel, metric, tr, bg);
3049
res = result_t::l_applied;
3150
}
3251

core/properties/Determinant.cc

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
2+
#include "Exceptions.hh"
3+
#include "properties/Determinant.hh"
4+
5+
using namespace cadabra;
6+
7+
Determinant::Determinant()
8+
{
9+
}
10+
11+
std::string Determinant::name() const
12+
{
13+
return "Determinant";
14+
}
15+
16+
std::string Determinant::unnamed_argument() const
17+
{
18+
return "object";
19+
}
20+
21+
bool Determinant::parse(Kernel&, keyval_t& keyvals)
22+
{
23+
keyval_t::const_iterator kv=keyvals.find("object");
24+
if(kv!=keyvals.end())
25+
obj = kv->second;
26+
return true;
27+
}
28+
29+
void Determinant::validate(const Kernel&, const Ex& tr) const
30+
{
31+
}
32+
33+
void Determinant::latex(std::ostream& str) const
34+
{
35+
str << name();
36+
}

core/properties/Determinant.cnb

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
{
2+
"cells" :
3+
[
4+
{
5+
"cell_origin" : "client",
6+
"cell_type" : "latex",
7+
"cells" :
8+
[
9+
{
10+
"cell_origin" : "client",
11+
"cell_type" : "latex_view",
12+
"source" : "\\property{Determinant}{Declares an object to be the determinant of a matrix or metric.}\n\nIn order to declare the name associated to the determinant of a matrix or metric, give it the\n\\prop{Determinant} property, indicating the matrix or metric as an argument. This is mainly used\nto compute determinants in components, but the property can also be used by algorithms which\nonly deal with purely abstract properties, e.g.~covariant derivatives.\n\nThe following example shows how to declare a metric and its components, and then compute\nthe determinant from there."
13+
}
14+
],
15+
"hidden" : true,
16+
"source" : "\\property{Determinant}{Declares an object to be the determinant of a matrix or metric.}\n\nIn order to declare the name associated to the determinant of a matrix or metric, give it the\n\\prop{Determinant} property, indicating the matrix or metric as an argument. This is mainly used\nto compute determinants in components, but the property can also be used by algorithms which\nonly deal with purely abstract properties, e.g.~covariant derivatives.\n\nThe following example shows how to declare a metric and its components, and then compute\nthe determinant from there."
17+
},
18+
{
19+
"cell_origin" : "client",
20+
"cell_type" : "input",
21+
"cells" :
22+
[
23+
{
24+
"cell_origin" : "server",
25+
"cell_type" : "latex_view",
26+
"source" : "\\begin{dmath*}{}\\text{Attached property Coordinate to~}\\left[t,~\\discretionary{}{}{} r,~\\discretionary{}{}{} \\phi\\right].\\end{dmath*}"
27+
},
28+
{
29+
"cell_origin" : "server",
30+
"cell_type" : "latex_view",
31+
"source" : "\\begin{dmath*}{}\\text{Attached property Indices(position=fixed) to~}\\left[m,~\\discretionary{}{}{} n,~\\discretionary{}{}{} p,~\\discretionary{}{}{} q\\right].\\end{dmath*}"
32+
},
33+
{
34+
"cell_origin" : "server",
35+
"cell_type" : "latex_view",
36+
"source" : "\\begin{dmath*}{}\\text{Attached property Metric to~}g_{m n}.\\end{dmath*}"
37+
},
38+
{
39+
"cell_origin" : "server",
40+
"cell_type" : "latex_view",
41+
"cells" :
42+
[
43+
{
44+
"cell_origin" : "server",
45+
"cell_type" : "input_form",
46+
"source" : "{g_{t t} = -1, g_{r r} = 1, g_{\\phi \\phi} = (r)**2}"
47+
}
48+
],
49+
"source" : "\\begin{dmath*}{}\\left[g_{t t} = -1,~\\discretionary{}{}{} g_{r r} = 1,~\\discretionary{}{}{} g_{\\phi \\phi} = {r}^{2}\\right]\\end{dmath*}"
50+
}
51+
],
52+
"source" : "{t,r,\\phi}::Coordinate;\n{m,n,p,q}::Indices(position=fixed, values={t,r,\\phi});\ng_{m n}::Metric;\nrl:= g_{t t} = -1, g_{r r} = 1, g_{\\phi \\phi} = r**2;"
53+
},
54+
{
55+
"cell_origin" : "client",
56+
"cell_type" : "latex",
57+
"cells" :
58+
[
59+
{
60+
"cell_origin" : "client",
61+
"cell_type" : "latex_view",
62+
"source" : "Now we declare that $g$ denotes the determinant of the metric $g_{m n}$, and use \\algo{complete} to compute it\ngiven the metric components."
63+
}
64+
],
65+
"hidden" : true,
66+
"source" : "Now we declare that $g$ denotes the determinant of the metric $g_{m n}$, and use \\algo{complete} to compute it\ngiven the metric components."
67+
},
68+
{
69+
"cell_origin" : "client",
70+
"cell_type" : "input",
71+
"cells" :
72+
[
73+
{
74+
"cell_origin" : "server",
75+
"cell_type" : "latex_view",
76+
"source" : "\\begin{dmath*}{}\\text{Attached property Determinant to~}g.\\end{dmath*}"
77+
}
78+
],
79+
"source" : "g::Determinant(g_{m n});"
80+
},
81+
{
82+
"cell_origin" : "client",
83+
"cell_type" : "input",
84+
"cells" :
85+
[
86+
{
87+
"cell_origin" : "server",
88+
"cell_type" : "latex_view",
89+
"cells" :
90+
[
91+
{
92+
"cell_origin" : "server",
93+
"cell_type" : "input_form",
94+
"source" : "{g_{t t} = -1, g_{r r} = 1, g_{\\phi \\phi} = (r)**2, g = -(r)**2}"
95+
}
96+
],
97+
"source" : "\\begin{dmath*}{}\\left[g_{t t} = -1,~\\discretionary{}{}{} g_{r r} = 1,~\\discretionary{}{}{} g_{\\phi \\phi} = {r}^{2},~\\discretionary{}{}{} g = -{r}^{2}\\right]\\end{dmath*}"
98+
}
99+
],
100+
"source" : "complete(rl, $g$);"
101+
},
102+
{
103+
"cell_origin" : "client",
104+
"cell_type" : "input",
105+
"source" : ""
106+
}
107+
],
108+
"description" : "Cadabra JSON notebook format",
109+
"version" : 1
110+
}

0 commit comments

Comments
 (0)