Skip to content

Commit 2a6ea2d

Browse files
committed
Various fixes/improvements for Young tableaux. Add ExNode::ex().
1 parent b045bd4 commit 2a6ea2d

File tree

11 files changed

+104
-13
lines changed

11 files changed

+104
-13
lines changed

cmake/version.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
set(CADABRA_VERSION_MAJOR 2)
22
set(CADABRA_VERSION_MINOR 3)
3-
set(CADABRA_VERSION_PATCH 1)
4-
set(CADABRA_VERSION_TWEAK 16)
3+
set(CADABRA_VERSION_PATCH 2)
4+
set(CADABRA_VERSION_TWEAK 0)
55
set(COPYRIGHT_YEARS "2001-2020")
66
math(EXPR SYSTEM_BITS "${CMAKE_SIZEOF_VOID_P} * 8")
77
find_program(GIT git PATHS ${GIT_DIR})

core/ExNode.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,11 @@ void ExNode::set_name(std::string nm)
278278
it->name = name_set.insert(nm).first;
279279
}
280280

281+
cadabra::Ex ExNode::get_ex() const
282+
{
283+
return Ex(it);
284+
}
285+
281286
str_node::parent_rel_t ExNode::get_parent_rel() const
282287
{
283288
if(!ex->is_valid(it))

core/ExNode.hh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
/// Iterators are much safer than in C++, because they carry the
2222
/// tree modification interface themselves, and can thus compute
2323
/// their next value for any destructive operation.
24+
///
25+
/// Note that ExNode does not really behave like a Python iterator
26+
/// in the strict sense: it does not return copies of nodes in the
27+
/// tree, but rather objects which know how to modify the tree.
2428

2529
class ExNode : public cadabra::IndexClassifier {
2630
public:
@@ -40,6 +44,9 @@ class ExNode : public cadabra::IndexClassifier {
4044
std::string get_name() const;
4145
void set_name(std::string);
4246

47+
/// Create a copy of the Ex pointed to by this iterator.
48+
cadabra::Ex get_ex() const;
49+
4350
cadabra::str_node::parent_rel_t get_parent_rel() const;
4451
void set_parent_rel(cadabra::str_node::parent_rel_t);
4552

core/Storage.cc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,21 @@ namespace cadabra {
132132
return *(begin()->multiplier);
133133
}
134134

135+
bool Ex::is_integer() const
136+
{
137+
if(begin()!=end())
138+
if(begin()->is_integer())
139+
return true;
140+
return false;
141+
}
142+
143+
long Ex::to_integer() const
144+
{
145+
if(!is_integer())
146+
throw InternalError("Called to_integer() on non-integer Ex");
147+
return to_long(*(begin()->multiplier));
148+
}
149+
135150
std::ostream& Ex::print_python(std::ostream& str, Ex::iterator it)
136151
{
137152
std::string name(*(*it).name);

core/Storage.hh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ namespace cadabra {
171171
/// FIXME: add tests for integers as well.
172172
bool is_rational() const;
173173
multiplier_t to_rational() const;
174+
bool is_integer() const;
175+
long to_integer() const;
174176

175177
/// Display expression in Python/Cadabra input form. This is
176178
/// fairly straightforward so not handled with a separate

core/algorithms/lr_tensor.cc

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ bool lr_tensor::can_apply(iterator it)
1919
tab2=tr.end(it);
2020
while(sib!=tr.end(it)) {
2121
if(kernel.properties.get<Tableau>(sib)) {
22+
// FIXME: test that tab2 has the same dimension!
2223
if(tab1==tr.end(it))
2324
tab1=sib;
2425
else {
@@ -51,15 +52,18 @@ bool lr_tensor::can_apply(iterator it)
5152

5253
Algorithm::result_t lr_tensor::apply(iterator& it)
5354
{
54-
if(kernel.properties.get<Tableau>(tab1)) do_tableau(it);
55-
else do_filledtableau(it);
55+
const Tableau *t1=kernel.properties.get<Tableau>(tab1);
56+
const FilledTableau *f1=kernel.properties.get<FilledTableau>(tab1);
57+
58+
if(t1) do_tableau(it, t1->dimension);
59+
else do_filledtableau(it, f1->dimension);
5660

5761
return result_t::l_applied;
5862
}
5963

6064
// The format is \ftab{a,b,c}{d,e}{f}.
6165
//
62-
void lr_tensor::do_filledtableau(iterator& it)
66+
void lr_tensor::do_filledtableau(iterator& it, int dimension)
6367
{
6468
bool even_only=false;
6569
bool singlet_rules=false;
@@ -80,7 +84,7 @@ void lr_tensor::do_filledtableau(iterator& it)
8084
tree_to_numerical_tab(tab1, one);
8185
tree_to_numerical_tab(tab2, two);
8286

83-
yngtab::LR_tensor(one,two,999,prod.get_back_insert_iterator());
87+
yngtab::LR_tensor(one,two,dimension,prod.get_back_insert_iterator());
8488

8589
Ex rep;
8690
iterator top=rep.set_head(str_node("\\sum"));
@@ -99,7 +103,7 @@ void lr_tensor::do_filledtableau(iterator& it)
99103
cleanup_dispatch(kernel, tr, it);
100104
}
101105

102-
void lr_tensor::do_tableau(iterator& it)
106+
void lr_tensor::do_tableau(iterator& it, int dimension)
103107
{
104108
bool even_only=false;
105109
// FIXME: put arguments back in
@@ -119,7 +123,7 @@ void lr_tensor::do_tableau(iterator& it)
119123
two.add_row(to_long(*sib->multiplier));
120124
++sib;
121125
}
122-
yngtab::LR_tensor(one,two,999,prod.get_back_insert_iterator());
126+
yngtab::LR_tensor(one,two,dimension,prod.get_back_insert_iterator());
123127

124128
Ex rep;
125129
iterator top=rep.set_head(str_node("\\sum"));

core/algorithms/lr_tensor.hh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ namespace cadabra {
1515
sibling_iterator tab1, tab2;
1616

1717
private:
18-
void do_tableau(iterator&);
19-
void do_filledtableau(iterator&);
18+
void do_tableau(iterator&, int dimension);
19+
void do_filledtableau(iterator&, int dimension);
2020
};
2121

2222
}

core/algorithms/tab_dimension.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ Algorithm::result_t tabdimension::apply(iterator& it)
5151
++sib;
5252
++currow;
5353
}
54+
auto tmp=it->multiplier;
5455
node_one(it);
56+
it->multiplier=tmp;
5557
multiply(it->multiplier, one.dimension(dimension));
5658
}
5759
else {
@@ -61,7 +63,9 @@ Algorithm::result_t tabdimension::apply(iterator& it)
6163
one.add_row(to_long(*sib->multiplier));
6264
++sib;
6365
}
66+
auto tmp=it->multiplier;
6467
node_one(it);
68+
it->multiplier=tmp;
6569
multiply(it->multiplier, one.dimension(dimension));
6670
}
6771
cleanup_dispatch(kernel, tr, it);

core/pythoncdb/py_ex.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,11 @@ namespace cadabra {
401401
return ex->number_of_children(it);
402402
}
403403

404+
long Ex_int_cast(Ex_ptr ex)
405+
{
406+
return ex->to_integer(); // this will throw an exception if the object is not integer
407+
}
408+
404409
std::string Ex_head(Ex_ptr ex)
405410
{
406411
if (ex->begin() == ex->end())
@@ -555,6 +560,7 @@ namespace cadabra {
555560
.def("__setitem__", &Ex_setitem)
556561
.def("__setitem__", &Ex_setitem_iterator)
557562
.def("__len__", &Ex_len)
563+
.def("__int__", &Ex_int_cast)
558564
.def("head", &Ex_head)
559565
.def("mult", &Ex_get_mult)
560566
.def("__iter__", &Ex_iter)
@@ -595,6 +601,7 @@ namespace cadabra {
595601
.def("append_child", &ExNode::append_child)
596602
.def("append_child", &ExNode::append_child_it)
597603
.def("erase", &ExNode::erase)
604+
.def("ex", &ExNode::get_ex)
598605
.def_property("name", &ExNode::get_name, &ExNode::set_name)
599606
.def_property("parent_rel", &ExNode::get_parent_rel, &ExNode::set_parent_rel)
600607
.def_property("multiplier", &ExNode::get_multiplier, &ExNode::set_multiplier)

tests/young.cdb

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,42 @@ def test29():
116116
assert(tst==0)
117117
print('Test 29 passed')
118118

119-
test27b()
119+
test29()
120+
121+
# The 8x8 tensor product in Young tableaux.
122+
#
123+
def test30():
124+
\tableau{#}::Tableau(dimension=3);
125+
\ftableau{#}::FilledTableau(dimension=3);
126+
ex:=\tableau{2}{1}\tableau{2}{1};
127+
lr_tensor(_)
128+
q=[int(tab_dimension(t.ex())) for t in ex.top().terms()]
129+
assert(q==[27,10,10,16,1])
130+
print("Test 30a passed")
131+
ex:=\ftableau{c,c}{c}\ftableau{a,a}{b};
132+
lr_tensor(_)
133+
q=[int(tab_dimension(t.ex())) for t in ex.top().terms()]
134+
assert(q==[27,10,10,8,8,1])
135+
print("Test 30b passed")
136+
137+
test30()
138+
139+
# def test30():
140+
# \tableau{#}::Tableau(dimension=10);
141+
# ex:=\tableau{2}{2}\tableau{2}{2} \tableau{2};
142+
# converge(ex):
143+
# lr_tensor(ex)
144+
# distribute(ex)
145+
#
146+
# q=[]
147+
# p=[]
148+
# for t in ex.top().terms():
149+
# p.append(t.ex())
150+
# q.append(int(tab_dimension(t.ex())))
151+
#
152+
#
153+
# assert(q==[
154+
155+
156+
157+

0 commit comments

Comments
 (0)