beta-0.89.2
[luatex.git] / source / libs / gmp / gmp-src / mpn / generic / hgcd_jacobi.c
blob0a49e5b3a78848f677cf8df77b5474e4b937177a
1 /* hgcd_jacobi.c.
3 THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
4 SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
5 GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
7 Copyright 2003-2005, 2008, 2011, 2012 Free Software Foundation, Inc.
9 This file is part of the GNU MP Library.
11 The GNU MP Library is free software; you can redistribute it and/or modify
12 it under the terms of either:
14 * the GNU Lesser General Public License as published by the Free
15 Software Foundation; either version 3 of the License, or (at your
16 option) any later version.
20 * the GNU General Public License as published by the Free Software
21 Foundation; either version 2 of the License, or (at your option) any
22 later version.
24 or both in parallel, as here.
26 The GNU MP Library is distributed in the hope that it will be useful, but
27 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
28 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29 for more details.
31 You should have received copies of the GNU General Public License and the
32 GNU Lesser General Public License along with the GNU MP Library. If not,
33 see https://www.gnu.org/licenses/. */
35 #include "gmp.h"
36 #include "gmp-impl.h"
37 #include "longlong.h"
39 /* This file is almost a copy of hgcd.c, with some added calls to
40 mpn_jacobi_update */
42 struct hgcd_jacobi_ctx
44 struct hgcd_matrix *M;
45 unsigned *bitsp;
48 static void
49 hgcd_jacobi_hook (void *p, mp_srcptr gp, mp_size_t gn,
50 mp_srcptr qp, mp_size_t qn, int d)
52 ASSERT (!gp);
53 ASSERT (d >= 0);
55 MPN_NORMALIZE (qp, qn);
56 if (qn > 0)
58 struct hgcd_jacobi_ctx *ctx = (struct hgcd_jacobi_ctx *) p;
59 /* NOTES: This is a bit ugly. A tp area is passed to
60 gcd_subdiv_step, which stores q at the start of that area. We
61 now use the rest. */
62 mp_ptr tp = (mp_ptr) qp + qn;
64 mpn_hgcd_matrix_update_q (ctx->M, qp, qn, d, tp);
65 *ctx->bitsp = mpn_jacobi_update (*ctx->bitsp, d, qp[0] & 3);
69 /* Perform a few steps, using some of mpn_hgcd2, subtraction and
70 division. Reduces the size by almost one limb or more, but never
71 below the given size s. Return new size for a and b, or 0 if no
72 more steps are possible.
74 If hgcd2 succeeds, needs temporary space for hgcd_matrix_mul_1, M->n
75 limbs, and hgcd_mul_matrix1_inverse_vector, n limbs. If hgcd2
76 fails, needs space for the quotient, qn <= n - s + 1 limbs, for and
77 hgcd_matrix_update_q, qn + (size of the appropriate column of M) <=
78 resulting size of M.
80 If N is the input size to the calling hgcd, then s = floor(N/2) +
81 1, M->n < N, qn + matrix size <= n - s + 1 + n - s = 2 (n - s) + 1
82 < N, so N is sufficient.
85 static mp_size_t
86 hgcd_jacobi_step (mp_size_t n, mp_ptr ap, mp_ptr bp, mp_size_t s,
87 struct hgcd_matrix *M, unsigned *bitsp, mp_ptr tp)
89 struct hgcd_matrix1 M1;
90 mp_limb_t mask;
91 mp_limb_t ah, al, bh, bl;
93 ASSERT (n > s);
95 mask = ap[n-1] | bp[n-1];
96 ASSERT (mask > 0);
98 if (n == s + 1)
100 if (mask < 4)
101 goto subtract;
103 ah = ap[n-1]; al = ap[n-2];
104 bh = bp[n-1]; bl = bp[n-2];
106 else if (mask & GMP_NUMB_HIGHBIT)
108 ah = ap[n-1]; al = ap[n-2];
109 bh = bp[n-1]; bl = bp[n-2];
111 else
113 int shift;
115 count_leading_zeros (shift, mask);
116 ah = MPN_EXTRACT_NUMB (shift, ap[n-1], ap[n-2]);
117 al = MPN_EXTRACT_NUMB (shift, ap[n-2], ap[n-3]);
118 bh = MPN_EXTRACT_NUMB (shift, bp[n-1], bp[n-2]);
119 bl = MPN_EXTRACT_NUMB (shift, bp[n-2], bp[n-3]);
122 /* Try an mpn_hgcd2 step */
123 if (mpn_hgcd2_jacobi (ah, al, bh, bl, &M1, bitsp))
125 /* Multiply M <- M * M1 */
126 mpn_hgcd_matrix_mul_1 (M, &M1, tp);
128 /* Can't swap inputs, so we need to copy. */
129 MPN_COPY (tp, ap, n);
130 /* Multiply M1^{-1} (a;b) */
131 return mpn_matrix22_mul1_inverse_vector (&M1, ap, tp, bp, n);
134 subtract:
136 struct hgcd_jacobi_ctx ctx;
137 ctx.M = M;
138 ctx.bitsp = bitsp;
140 return mpn_gcd_subdiv_step (ap, bp, n, s, hgcd_jacobi_hook, &ctx, tp);
144 /* Reduces a,b until |a-b| fits in n/2 + 1 limbs. Constructs matrix M
145 with elements of size at most (n+1)/2 - 1. Returns new size of a,
146 b, or zero if no reduction is possible. */
148 /* Same scratch requirements as for mpn_hgcd. */
149 mp_size_t
150 mpn_hgcd_jacobi (mp_ptr ap, mp_ptr bp, mp_size_t n,
151 struct hgcd_matrix *M, unsigned *bitsp, mp_ptr tp)
153 mp_size_t s = n/2 + 1;
155 mp_size_t nn;
156 int success = 0;
158 if (n <= s)
159 /* Happens when n <= 2, a fairly uninteresting case but exercised
160 by the random inputs of the testsuite. */
161 return 0;
163 ASSERT ((ap[n-1] | bp[n-1]) > 0);
165 ASSERT ((n+1)/2 - 1 < M->alloc);
167 if (ABOVE_THRESHOLD (n, HGCD_THRESHOLD))
169 mp_size_t n2 = (3*n)/4 + 1;
170 mp_size_t p = n/2;
172 nn = mpn_hgcd_jacobi (ap + p, bp + p, n - p, M, bitsp, tp);
173 if (nn > 0)
175 /* Needs 2*(p + M->n) <= 2*(floor(n/2) + ceil(n/2) - 1)
176 = 2 (n - 1) */
177 n = mpn_hgcd_matrix_adjust (M, p + nn, ap, bp, p, tp);
178 success = 1;
180 while (n > n2)
182 /* Needs n + 1 storage */
183 nn = hgcd_jacobi_step (n, ap, bp, s, M, bitsp, tp);
184 if (!nn)
185 return success ? n : 0;
186 n = nn;
187 success = 1;
190 if (n > s + 2)
192 struct hgcd_matrix M1;
193 mp_size_t scratch;
195 p = 2*s - n + 1;
196 scratch = MPN_HGCD_MATRIX_INIT_ITCH (n-p);
198 mpn_hgcd_matrix_init(&M1, n - p, tp);
199 nn = mpn_hgcd_jacobi (ap + p, bp + p, n - p, &M1, bitsp, tp + scratch);
200 if (nn > 0)
202 /* We always have max(M) > 2^{-(GMP_NUMB_BITS + 1)} max(M1) */
203 ASSERT (M->n + 2 >= M1.n);
205 /* Furthermore, assume M ends with a quotient (1, q; 0, 1),
206 then either q or q + 1 is a correct quotient, and M1 will
207 start with either (1, 0; 1, 1) or (2, 1; 1, 1). This
208 rules out the case that the size of M * M1 is much
209 smaller than the expected M->n + M1->n. */
211 ASSERT (M->n + M1.n < M->alloc);
213 /* Needs 2 (p + M->n) <= 2 (2*s - n2 + 1 + n2 - s - 1)
214 = 2*s <= 2*(floor(n/2) + 1) <= n + 2. */
215 n = mpn_hgcd_matrix_adjust (&M1, p + nn, ap, bp, p, tp + scratch);
217 /* We need a bound for of M->n + M1.n. Let n be the original
218 input size. Then
220 ceil(n/2) - 1 >= size of product >= M.n + M1.n - 2
222 and it follows that
224 M.n + M1.n <= ceil(n/2) + 1
226 Then 3*(M.n + M1.n) + 5 <= 3 * ceil(n/2) + 8 is the
227 amount of needed scratch space. */
228 mpn_hgcd_matrix_mul (M, &M1, tp + scratch);
229 success = 1;
234 for (;;)
236 /* Needs s+3 < n */
237 nn = hgcd_jacobi_step (n, ap, bp, s, M, bitsp, tp);
238 if (!nn)
239 return success ? n : 0;
241 n = nn;
242 success = 1;