| Peter Bruin on Tue, 24 Feb 2026 09:44:26 +0100 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
| Faster implementation of perm_sign |
Bonjour, Preparing a lecture about permutations made me realise that perm_sign (which I contributed in 2017) could be improved by successively composing with transpositions instead of computing the cycle decomposition. This does require keeping track of the inverse permutation. I am attaching a patch. Empirically, this seems to be at least 35% faster than the old implementation: Before: ? forperm(8,p,s=permsign(p)); *** last result computed in 15 ms. ? forperm(9,p,s=permsign(p)); *** last result computed in 130 ms. ? forperm(10,p,s=permsign(p)); *** last result computed in 1,221 ms. ? forperm(11,p,s=permsign(p)); *** last result computed in 14,319 ms. After: ? forperm(8,p,s=permsign(p)); *** last result computed in 9 ms. ? forperm(9,p,s=permsign(p)); *** last result computed in 83 ms. ? forperm(10,p,s=permsign(p)); *** last result computed in 786 ms. ? forperm(11,p,s=permsign(p)); *** last result computed in 8,776 ms. Best wishes, Peter
>From d7ee63ee461d45c5bdf39ed440e961a229fc94a2 Mon Sep 17 00:00:00 2001
From: Peter Bruin <P.J.Bruin@math.leidenuniv.nl>
Date: Tue, 24 Feb 2026 08:15:59 +0100
Subject: [PATCH] speed up perm_sign
---
src/basemath/perm.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/src/basemath/perm.c b/src/basemath/perm.c
index 7532e621c5..a81b91edae 100644
--- a/src/basemath/perm.c
+++ b/src/basemath/perm.c
@@ -531,10 +531,19 @@ long
perm_sign(GEN v)
{
pari_sp av = avma;
- GEN c = vecperm_orbits_i(mkvec(v), lg(v)-1);
- long i, l = lg(c), s = 1;
- for (i = 1; i < l; i++)
- if (odd(lg(gel(c, i)))) s = -s;
+ long i, j, l = lg(v), s = 1;
+ GEN w = perm_inv(v);
+ v = vecsmall_copy(v);
+ while (--l > 1)
+ {
+ if ((i = v[l]) != l)
+ {
+ j = w[l];
+ v[j] = i;
+ w[i] = j;
+ s = -s;
+ }
+ }
return gc_long(av,s);
}
--
2.51.0