Skip to content

Commit 79dc351

Browse files
author
Release Manager
committed
gh-35997: Improve getting matrix entries after permutation in _palp_PM_max()
<!-- ^^^^^ Please provide a concise, informative and self-explanatory title. Don't put issue numbers in there, do this in the PR body below. For example, instead of "Fixes #1234" use "Introduce new method to calculate 1+1" --> <!-- Describe your changes here in detail --> Modify the _palp_PM_max() to obtain the matrix entry after permutation without make copy of the matrix. @mkoeppe before ``` sage: %timeit -n 10 -r 3 o = lattice_polytope.cross_polytope(3); o._palp_PM_max(); 36.8 ms ± 5.19 ms per loop (mean ± std. dev. of 3 runs, 10 loops each) ``` after ``` sage: %timeit -n 10 -r 3 o = lattice_polytope.cross_polytope(3); o._palp_PM_max(); 4.88 ms ± 2.23 ms per loop (mean ± std. dev. of 3 runs, 10 loops each) ``` <!-- Why is this change required? What problem does it solve? --> <!-- If this PR resolves an open issue, please link to it here. For example "Fixes #12345". --> <!-- If your change requires a documentation PR, please link it appropriately. --> ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> <!-- If your change requires a documentation PR, please link it appropriately --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> <!-- Feel free to remove irrelevant items. --> - [x] The title is concise, informative, and self-explanatory. - [x] The description explains in detail what this PR is about. - [ ] I have linked a relevant issue or discussion. - [ ] I have created tests covering the changes. - [ ] I have updated the documentation accordingly. ### ⌛ Dependencies <!-- List all open PRs that this PR logically depends on - #12345: short description why this is a dependency - #34567: ... --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> URL: #35997 Reported by: xuluze Reviewer(s): Matthias Köppe
2 parents 845963c + 2df0d10 commit 79dc351

File tree

3 files changed

+43
-56
lines changed

3 files changed

+43
-56
lines changed

build/pkgs/configure/checksums.ini

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
tarball=configure-VERSION.tar.gz
2-
sha1=017780512407f8da87a091c485cf8c7162b5adaf
3-
md5=4e3e25464ee850c2593f16364bd6b206
4-
cksum=531215747
2+
sha1=d39abedb0ee7beb3d61b625d4627e10c347320f2
3+
md5=6a0dcd364b964e10b594339094d64a36
4+
cksum=2756767966
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
98520945e069c603400cf2ae902a843f7a1bda13
1+
259402d021bcc64831e1f24b26da34b76820b566

src/sage/geometry/lattice_polytope.py

Lines changed: 39 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3188,11 +3188,6 @@ def _palp_PM_max(self, check=False):
31883188
sage: all(results) # long time
31893189
True
31903190
"""
3191-
def PGE(S, u, v):
3192-
if u == v:
3193-
return S.one()
3194-
return S((u, v), check=False)
3195-
31963191
PM = self.vertex_facet_pairing_matrix()
31973192
n_v = PM.ncols()
31983193
n_f = PM.nrows()
@@ -3202,53 +3197,45 @@ def PGE(S, u, v):
32023197
# and find all the ways of making the first row of PM_max
32033198
def index_of_max(iterable):
32043199
# returns the index of max of any iterable
3205-
m, x = 0, iterable[0]
3206-
for k, l in enumerate(iterable):
3207-
if l > x:
3208-
m, x = k, l
3209-
return m
3200+
return max(enumerate(iterable), key=lambda x: x[1])[0]
32103201

32113202
n_s = 1
3212-
permutations = {0 : [S_f.one(), S_v.one()]}
3203+
permutations = {0: [S_f.one(), S_v.one()]}
32133204
for j in range(n_v):
3214-
m = index_of_max(
3215-
[(PM.with_permuted_columns(permutations[0][1]))[0][i]
3216-
for i in range(j, n_v)])
3205+
m = index_of_max(PM[0, i] for i in range(j, n_v))
32173206
if m > 0:
3218-
permutations[0][1] = PGE(S_v, j + 1, m + j + 1) * permutations[0][1]
3207+
permutations[0][1] = S_v((j + 1, m + j + 1), check=False) * permutations[0][1]
32193208
first_row = list(PM[0])
32203209

32213210
# Arrange other rows one by one and compare with first row
32223211
for k in range(1, n_f):
32233212
# Error for k == 1 already!
32243213
permutations[n_s] = [S_f.one(), S_v.one()]
3225-
m = index_of_max(PM.with_permuted_columns(permutations[n_s][1])[k])
3214+
m = index_of_max(PM[k, permutations[n_s][1](j+1) - 1] for j in range(n_v))
32263215
if m > 0:
3227-
permutations[n_s][1] = PGE(S_v, 1, m+1) * permutations[n_s][1]
3228-
d = ((PM.with_permuted_columns(permutations[n_s][1]))[k][0]
3216+
permutations[n_s][1] = S_v((1, m + 1), check=False) * permutations[n_s][1]
3217+
d = (PM[k, permutations[n_s][1](1) - 1]
32293218
- permutations[0][1](first_row)[0])
32303219
if d < 0:
32313220
# The largest elt of this row is smaller than largest elt
32323221
# in 1st row, so nothing to do
32333222
continue
32343223
# otherwise:
32353224
for i in range(1, n_v):
3236-
m = index_of_max(
3237-
[PM.with_permuted_columns(permutations[n_s][1])[k][j]
3238-
for j in range(i, n_v)])
3225+
m = index_of_max(PM[k, permutations[n_s][1](j+1) - 1] for j in range(i,n_v))
32393226
if m > 0:
3240-
permutations[n_s][1] = PGE(S_v, i + 1, m + i + 1) \
3227+
permutations[n_s][1] = S_v((i + 1, m + i + 1), check=False) \
32413228
* permutations[n_s][1]
32423229
if d == 0:
3243-
d = (PM.with_permuted_columns(permutations[n_s][1])[k][i]
3230+
d = (PM[k, permutations[n_s][1](i+1) - 1]
32443231
-permutations[0][1](first_row)[i])
32453232
if d < 0:
32463233
break
32473234
if d < 0:
32483235
# This row is smaller than 1st row, so nothing to do
32493236
del permutations[n_s]
32503237
continue
3251-
permutations[n_s][0] = PGE(S_f, 1, k + 1) * permutations[n_s][0]
3238+
permutations[n_s][0] = S_f((1, k + 1), check=False) * permutations[n_s][0]
32523239
if d == 0:
32533240
# This row is the same, so we have a symmetry!
32543241
n_s += 1
@@ -3258,9 +3245,9 @@ def index_of_max(iterable):
32583245
first_row = list(PM[k])
32593246
permutations = {0: permutations[n_s]}
32603247
n_s = 1
3261-
permutations = {k:permutations[k] for k in permutations if k < n_s}
3248+
permutations = {k: permutations[k] for k in permutations if k < n_s}
32623249

3263-
b = PM.with_permuted_rows_and_columns(*permutations[0])[0]
3250+
b = tuple(PM[permutations[0][0](1) - 1, permutations[0][1](j+1) - 1] for j in range(n_v))
32643251
# Work out the restrictions the current permutations
32653252
# place on other permutations as a automorphisms
32663253
# of the first row
@@ -3294,34 +3281,35 @@ def index_of_max(iterable):
32943281
# between 0 and S(0)
32953282
for s in range(l, n_f):
32963283
for j in range(1, S[0]):
3297-
v = PM.with_permuted_rows_and_columns(
3298-
*permutations_bar[n_p])[s]
3299-
if v[0] < v[j]:
3300-
permutations_bar[n_p][1] = PGE(S_v, 1, j + 1) * permutations_bar[n_p][1]
3284+
v0 = PM[permutations_bar[n_p][0](s+1) - 1, permutations_bar[n_p][1](1) - 1]
3285+
vj = PM[permutations_bar[n_p][0](s+1) - 1, permutations_bar[n_p][1](j+1) - 1]
3286+
if v0 < vj:
3287+
permutations_bar[n_p][1] = S_v((1, j + 1), check=False) * permutations_bar[n_p][1]
33013288
if ccf == 0:
3302-
l_r[0] = PM.with_permuted_rows_and_columns(
3303-
*permutations_bar[n_p])[s][0]
3304-
permutations_bar[n_p][0] = PGE(S_f, l + 1, s + 1) * permutations_bar[n_p][0]
3289+
l_r[0] = PM[permutations_bar[n_p][0](s+1) - 1, permutations_bar[n_p][1](1) - 1]
3290+
if s != l:
3291+
permutations_bar[n_p][0] = S_f((l + 1, s + 1), check=False) * permutations_bar[n_p][0]
33053292
n_p += 1
33063293
ccf = 1
33073294
permutations_bar[n_p] = copy(permutations[k])
33083295
else:
3309-
d1 = PM.with_permuted_rows_and_columns(
3310-
*permutations_bar[n_p])[s][0]
3296+
d1 = PM[permutations_bar[n_p][0](s+1) - 1, permutations_bar[n_p][1](1) - 1]
33113297
d = d1 - l_r[0]
33123298
if d < 0:
33133299
# We move to the next line
33143300
continue
33153301
elif d==0:
33163302
# Maximal values agree, so possible symmetry
3317-
permutations_bar[n_p][0] = PGE(S_f, l + 1, s + 1) * permutations_bar[n_p][0]
3303+
if s != l:
3304+
permutations_bar[n_p][0] = S_f((l + 1, s + 1), check=False) * permutations_bar[n_p][0]
33183305
n_p += 1
33193306
permutations_bar[n_p] = copy(permutations[k])
33203307
else:
33213308
# We found a greater maximal value for first entry.
33223309
# It becomes our new reference:
33233310
l_r[0] = d1
3324-
permutations_bar[n_p][0] = PGE(S_f, l + 1, s + 1) * permutations_bar[n_p][0]
3311+
if s != l:
3312+
permutations_bar[n_p][0] = S_f((l + 1, s + 1), check=False) * permutations_bar[n_p][0]
33253313
# Forget previous work done
33263314
cf = 0
33273315
permutations_bar = {0:copy(permutations_bar[n_p])}
@@ -3343,18 +3331,16 @@ def index_of_max(iterable):
33433331
s -= 1
33443332
# Find the largest value in this symmetry block
33453333
for j in range(c + 1, h):
3346-
v = PM.with_permuted_rows_and_columns(
3347-
*permutations_bar[s])[l]
3348-
if (v[c] < v[j]):
3349-
permutations_bar[s][1] = PGE(S_v, c + 1, j + 1) * permutations_bar[s][1]
3334+
vc = PM[(permutations_bar[s][0])(l+1) - 1, (permutations_bar[s][1])(c+1) - 1]
3335+
vj = PM[(permutations_bar[s][0])(l+1) - 1, (permutations_bar[s][1])(j+1) - 1]
3336+
if (vc < vj):
3337+
permutations_bar[s][1] = S_v((c + 1, j + 1), check=False) * permutations_bar[s][1]
33503338
if ccf == 0:
33513339
# Set reference and carry on to next permutation
3352-
l_r[c] = PM.with_permuted_rows_and_columns(
3353-
*permutations_bar[s])[l][c]
3340+
l_r[c] = PM[(permutations_bar[s][0])(l+1) - 1, (permutations_bar[s][1])(c+1) - 1]
33543341
ccf = 1
33553342
else:
3356-
d1 = PM.with_permuted_rows_and_columns(
3357-
*permutations_bar[s])[l][c]
3343+
d1 = PM[(permutations_bar[s][0])(l+1) - 1, (permutations_bar[s][1])(c+1) - 1]
33583344
d = d1 - l_r[c]
33593345
if d < 0:
33603346
n_p -= 1
@@ -3383,7 +3369,7 @@ def index_of_max(iterable):
33833369
# the restrictions the last worked out
33843370
# row imposes.
33853371
c = 0
3386-
M = (PM.with_permuted_rows_and_columns(*permutations[0]))[l]
3372+
M = tuple(PM[permutations[0][0](l+1) - 1, permutations[0][1](j+1) - 1] for j in range(n_v))
33873373
while c < n_v:
33883374
s = S[c] + 1
33893375
S[c] = c + 1
@@ -5196,11 +5182,10 @@ def _palp_canonical_order(V, PM_max, permutations):
51965182
in 2-d lattice M, (1,3,2,4))
51975183
"""
51985184
n_v = PM_max.ncols()
5199-
n_f = PM_max.nrows()
52005185
S_v = SymmetricGroup(n_v)
52015186
p_c = S_v.one()
5202-
M_max = [max([PM_max[i][j] for i in range(n_f)]) for j in range(n_v)]
5203-
S_max = [sum([PM_max[i][j] for i in range(n_f)]) for j in range(n_v)]
5187+
M_max = [max(row[j] for row in PM_max.rows()) for j in range(n_v)]
5188+
S_max = sum(PM_max)
52045189
for i in range(n_v):
52055190
k = i
52065191
for j in range(i + 1, n_v):
@@ -5213,13 +5198,15 @@ def _palp_canonical_order(V, PM_max, permutations):
52135198
p_c = S_v((1 + i, 1 + k), check=False) * p_c
52145199
# Create array of possible NFs.
52155200
permutations = [p_c * l[1] for l in permutations.values()]
5216-
Vs = [(V.column_matrix().with_permuted_columns(sig).hermite_form(), sig)
5201+
Vmatrix = V.column_matrix()
5202+
Vs = [(Vmatrix.with_permuted_columns(sig).hermite_form(), sig)
52175203
for sig in permutations]
52185204
Vmin = min(Vs, key=lambda x:x[0])
5219-
vertices = [V.module()(_) for _ in Vmin[0].columns()]
5205+
Vmodule = V.module()
5206+
vertices = [Vmodule(_) for _ in Vmin[0].columns()]
52205207
for v in vertices:
52215208
v.set_immutable()
5222-
return (PointCollection(vertices, V.module()), Vmin[1])
5209+
return (PointCollection(vertices, Vmodule), Vmin[1])
52235210

52245211

52255212
def _palp_convert_permutation(permutation):

0 commit comments

Comments
 (0)