[Gmp-commit] /var/hg/gmp: 2 new changesets
mercurial at gmplib.org
mercurial at gmplib.org
Sat Oct 27 10:50:44 CEST 2012
details: /var/hg/gmp/rev/a04b1abcb99d
changeset: 15088:a04b1abcb99d
user: Torbjorn Granlund <tege at gmplib.org>
date: Sat Oct 27 10:27:52 2012 +0200
description:
Get remainder allocation right.
details: /var/hg/gmp/rev/755243e9118f
changeset: 15089:755243e9118f
user: Torbjorn Granlund <tege at gmplib.org>
date: Sat Oct 27 10:50:42 2012 +0200
description:
Trivial merge.
diffstat:
ChangeLog | 4 ++++
mpn/generic/perfpow.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
mpn/generic/remove.c | 2 +-
3 files changed, 50 insertions(+), 1 deletions(-)
diffs (99 lines):
diff -r 7e1cea21638c -r 755243e9118f ChangeLog
--- a/ChangeLog Thu Oct 25 21:49:32 2012 +0200
+++ b/ChangeLog Sat Oct 27 10:50:42 2012 +0200
@@ -1,3 +1,7 @@
+2012-10-27 Torbjorn Granlund <tege at gmplib.org>
+
+ * mpn/generic/remove.c: Get remainder allocation right.
+
2012-10-25 Torbjorn Granlund <tege at gmplib.org>
* longlong.h: De-support old POWER asm syntax.
diff -r 7e1cea21638c -r 755243e9118f mpn/generic/perfpow.c
--- a/mpn/generic/perfpow.c Thu Oct 25 21:49:32 2012 +0200
+++ b/mpn/generic/perfpow.c Sat Oct 27 10:50:42 2012 +0200
@@ -32,6 +32,12 @@
For s = 1, 2, 4, ..., s_max, compute the s least significant
limbs of {xp,xn}^k. Stop if they don't match the s least
significant limbs of {np,nn}.
+
+ FIXME: Low xn limbs can be expected to always match, if computed as
+ a mod B^{xn} root. So instead of using mpn_powlo, compute an
+ approximation of the most significant (normalized) limb of {xp,xn}
+ ^ k (and an error bound), and compare to {np, nn}. Or use an even
+ cruder approximation based on fix-point base 2 logarithm.
*/
static int
pow_equals (mp_srcptr np, mp_size_t nn,
@@ -105,6 +111,28 @@
Algorithm:
Apply Hensel lifting repeatedly, each time
doubling (approx.) the number of known bits in rp.
+
+ Uses the iteration
+
+ r' <-- k^{-1} ((k+1) r - r^{k+1} y) (mod 2^b)
+
+ FIXME: I think we get *exactly* doubled precision in each
+ iteration. Could be simplified to do precision book-keeping in
+ limbs rather than bits.
+
+ FIXME: Rewrite iteration as
+
+ r' <-- r - k^{-1} r (r^k y - 1)
+
+ and take advantage of the zero low part of r^k y - 1.
+
+ If we prefer to get y^{1/k} rather than y^{-1/k}, we could also
+ switch to the iteration
+
+ r' <-- r - k^{-1} r (r^k y^{k-1} - 1)
+
+ which converges to y^{1/n - 1}, and we then get y^{1/n} by a single
+ mullo.
*/
static void
binv_root (mp_ptr rp, mp_srcptr yp,
@@ -146,6 +174,16 @@
/*
Computes rp such that rp^2 * yp = 1 (mod 2^{b+1}).
Returns non-zero if such an integer rp exists.
+
+ Uses the iteration
+
+ r' <-- (3r - r^3 y) / 2
+
+ FIXME: Rewrite as
+
+ r' <-- r - r (r^2 y - 1) / 2
+
+ and take advantage of zero low part of r^2 y - 1.
*/
static int
binv_sqroot (mp_ptr rp, mp_srcptr yp,
@@ -274,6 +312,13 @@
tp = TMP_ALLOC_LIMBS (5 * nn); /* FIXME */
MPN_ZERO (rp1, nn);
+ /* FIXME: It seems the inverse in yp is needed only to get
+ non-inverted roots. I.e., is_kth_power computes n^{1/2} as
+ (n^{-1})^{-1/2} and similarly for nth roots. It should be more
+ efficient to compute n^{1/2} as n * n^{-1/2}, with a mullo
+ instead of a binvert. And we can do something similar for kth
+ roots if we switch to an iteration converging to n^{1/k - 1}, and
+ we can then eliminate this binvert call. */
mpn_binvert (yp, np, 1 + (b - 1) / GMP_LIMB_BITS, tp);
if (b % GMP_LIMB_BITS)
yp[(b - 1) / GMP_LIMB_BITS] &= (((mp_limb_t) 1) << (b % GMP_LIMB_BITS)) - 1;
diff -r 7e1cea21638c -r 755243e9118f mpn/generic/remove.c
--- a/mpn/generic/remove.c Thu Oct 25 21:49:32 2012 +0200
+++ b/mpn/generic/remove.c Sat Oct 27 10:50:42 2012 +0200
@@ -86,7 +86,7 @@
TMP_MARK;
- tp = TMP_ALLOC_LIMBS ((un + vn) / 2); /* remainder */
+ tp = TMP_ALLOC_LIMBS ((un + 1 + vn) / 2); /* remainder */
qp = TMP_ALLOC_LIMBS (un + 1); /* quotient, alternating */
qp2 = TMP_ALLOC_LIMBS (un + 1); /* quotient, alternating */
np = TMP_ALLOC_LIMBS (un + LOG); /* powers of V */
More information about the gmp-commit
mailing list