malachite_nz/integer/arithmetic/kronecker_symbol.rs
1// Copyright © 2025 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MP Library.
4//
5// Copyright © 2000-2002, 2005, 2010-2012 Free Software Foundation, Inc.
6//
7// This file is part of Malachite.
8//
9// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
10// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
11// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
12
13use crate::integer::Integer;
14use crate::natural::InnerNatural::{Large, Small};
15use crate::natural::Natural;
16use crate::natural::arithmetic::div_mod::limbs_div_mod_to_out;
17use crate::natural::arithmetic::eq_mod::limbs_mod_exact_odd_limb;
18use crate::natural::arithmetic::kronecker_symbol::{
19 limbs_jacobi_symbol_init, limbs_jacobi_symbol_same_length,
20};
21use crate::natural::arithmetic::mod_op::limbs_mod_limb_alt_2;
22use crate::natural::arithmetic::shr::limbs_shr_to_out;
23use crate::platform::{BMOD_1_TO_MOD_1_THRESHOLD, DoubleLimb, Limb};
24use core::mem::swap;
25use malachite_base::num::arithmetic::traits::{
26 JacobiSymbol, KroneckerSymbol, LegendreSymbol, Parity,
27};
28use malachite_base::num::basic::integers::PrimitiveInt;
29use malachite_base::num::basic::traits::Zero;
30use malachite_base::num::logic::traits::{BitAccess, NotAssign, TrailingZeros};
31use malachite_base::slices::slice_leading_zeros;
32
33// # Worst-case complexity
34// Constant time and additional memory.
35//
36// This is equivalent to `mpz_jacobi` from `mpz/jacobi.c`, GMP 6.2.1, where the absolute values of
37// both `a` and `b` fit in a limb.
38pub_crate_test! {limbs_kronecker_symbol_single(
39 x_sign: bool,
40 x: Limb,
41 y_sign: bool,
42 mut y: Limb,
43) -> i8 {
44 // Common factor of 2 => (a/b) = 0
45 if (x | y).even() {
46 return 0;
47 }
48 // (a/-1) = -1 if a < 0, +1 if a >= 0
49 let mut negate = !x_sign && !y_sign;
50 let y_twos = TrailingZeros::trailing_zeros(y);
51 y >>= y_twos;
52 // (-1/b) = -1 iff b = 3 (mod 4)
53 if !x_sign && y.get_bit(1) {
54 negate.not_assign();
55 }
56 if y_twos.odd() & ((x >> 1) ^ x).get_bit(1) {
57 negate.not_assign();
58 }
59 let j = if y == 1 { 1 } else { x.jacobi_symbol(y) };
60 if negate {
61 -j
62 } else {
63 j
64 }
65}}
66
67// # Worst-case complexity
68// $T(n) = O(n (\log n)^2 \log\log n)$
69//
70// $M(n) = O(n \log n)$
71//
72// where $T$ is time, $M$ is additional memory, and $n$ is `max(xs.len(), ys.len())`.
73//
74// This is equivalent to `mpz_jacobi` from `mpz/jacobi.c`, GMP 6.2.1.
75pub_crate_test! {
76 limbs_kronecker_symbol(x_sign: bool, xs: &[Limb], y_sign: bool, ys: &[Limb]) -> i8 {
77 let mut xs_len = xs.len();
78 let mut ys_len = ys.len();
79 // The `limbs_jacobi_symbol_same_length` function requires positive x and y, and x odd. So we
80 // must handle the cases of x or y zero, then signs, and then the case of even y.
81 //
82 // (x / 0) = (x = 1 or x = -1)
83 if ys_len == 0 {
84 return i8::from(xs == [1]);
85 }
86 // (0 / y) = (y = 1 or y = -1)
87 if xs_len == 0 {
88 return i8::from(ys == [1]);
89 }
90 assert_ne!(xs[xs_len - 1], 0);
91 assert_ne!(ys[ys_len - 1], 0);
92 let mut xs = xs;
93 let mut ys = ys;
94 // Common factor of 2 => (x / y) = 0
95 if (xs[0] | ys[0]).even() {
96 return 0;
97 }
98 // (x / -1) = -1 if x < 0, 1 if x >= 0
99 let mut negate = !x_sign && !y_sign;
100 ys = &ys[slice_leading_zeros(ys)..];
101 ys_len = ys.len();
102 let mut y_lo = ys[0];
103 let mut y_twos = TrailingZeros::trailing_zeros(y_lo);
104 y_lo >>= y_twos;
105 if ys_len > 1 && y_twos != 0 {
106 let y_1 = ys[1];
107 y_lo |= y_1 << (Limb::WIDTH - y_twos);
108 if ys_len == 2 && y_1 >> y_twos == 0 {
109 ys_len = 1;
110 }
111 }
112 // (-1 / y) = -1 iff y ≡ 3 mod 4
113 if !x_sign && y_lo.get_bit(1) {
114 negate.not_assign();
115 }
116 xs = &xs[slice_leading_zeros(xs)..];
117 xs_len = xs.len();
118 let mut x_lo = xs[0];
119 // Ensure xs_len >= ys_len. Take advantage of the generalized reciprocity law: (x / y * 2 ^ n) =
120 // (y * 2 ^ n / x) * recip(x, y)
121 if xs_len < ys_len {
122 swap(&mut xs, &mut ys);
123 swap(&mut xs_len, &mut ys_len);
124 swap(&mut x_lo, &mut y_lo);
125 // The value of x_lo (old y_lo) is a bit subtle. For this code path, we get x_lo as the low,
126 // always odd, limb of shifted x. Which is what we need for the reciprocity update below.
127 //
128 // However, all other uses of x_lo assumes that it is *not* shifted. Luckily, x_lo matters
129 // only when either
130 // - y_twos > 0, in which case x is always odd
131 // - xs_len = ys_len = 1, in which case this code path is never taken.
132 y_twos = TrailingZeros::trailing_zeros(y_lo);
133 y_lo >>= y_twos;
134 if ys_len > 1 && y_twos != 0 {
135 let y_1 = ys[1];
136 y_lo |= y_1 << (Limb::WIDTH - y_twos);
137 if ys_len == 2 && y_1 >> y_twos == 0 {
138 ys_len = 1;
139 }
140 }
141 if (x_lo & y_lo).get_bit(1) {
142 negate.not_assign();
143 }
144 }
145 if ys_len == 1 {
146 if y_twos.odd() & ((x_lo >> 1) ^ x_lo).get_bit(1) {
147 negate.not_assign();
148 }
149 if y_lo == 1 {
150 return if negate { -1 } else { 1 };
151 }
152 if xs_len > 1 {
153 assert!(y_lo.odd());
154 x_lo = if xs.len() >= BMOD_1_TO_MOD_1_THRESHOLD {
155 limbs_mod_limb_alt_2::<DoubleLimb, Limb>(xs, y_lo)
156 } else {
157 if y_lo.get_bit(1) {
158 negate.not_assign();
159 }
160 limbs_mod_exact_odd_limb(xs, y_lo, 0)
161 };
162 }
163 let j = x_lo.jacobi_symbol(y_lo);
164 return if negate { -j } else { j };
165 }
166 // Allocation strategy: For x, we allocate a working copy only for x % y, but when x is much
167 // larger than y, we have to allocate space for the large quotient. We use the same area,
168 // pointed to by ys_alt, for both the quotient x / y and the working copy of y.
169 let mut scratch = vec![
170 0;
171 if xs_len >= ys_len << 1 {
172 xs_len + 1
173 } else {
174 ys_len << 1
175 }
176 ];
177 let (mut xs_alt, mut ys_alt) = scratch.split_at_mut(ys_len);
178 // In the case of even y, we conceptually shift out the powers of two first, and then divide x %
179 // y. Hence, when taking those powers of two into account, we must use alow *before* the
180 // division. Doing the actual division first is ok, because the point is to remove multiples of
181 // y from x, and multiples of 2 ^ k y are good enough.
182 if xs_len > ys_len {
183 limbs_div_mod_to_out(ys_alt, xs_alt, xs, ys);
184 ys_alt = &mut ys_alt[..ys_len];
185 } else {
186 xs_alt.copy_from_slice(xs);
187 }
188 if y_twos != 0 {
189 if y_twos.odd() & ((x_lo >> 1) ^ x_lo).get_bit(1) {
190 negate.not_assign();
191 }
192 limbs_shr_to_out(ys_alt, ys, y_twos);
193 if xs_alt[ys_len - 1] == 0 && ys_alt[ys_len - 1] == 0 {
194 xs_alt = &mut xs_alt[..ys_len - 1];
195 ys_alt = &mut ys_alt[..ys_len - 1];
196 }
197 } else {
198 ys_alt.copy_from_slice(ys);
199 }
200 assert_eq!(y_lo, ys_alt[0]);
201 let bits = limbs_jacobi_symbol_init(xs_alt[0], y_lo, u8::from(negate));
202 limbs_jacobi_symbol_same_length(xs_alt, ys_alt, bits)
203}}
204
205impl LegendreSymbol<Self> for Integer {
206 /// Computes the Legendre symbol of two [`Integer`]s, taking both by value.
207 ///
208 /// This implementation is identical to that of [`JacobiSymbol`], since there is no
209 /// computational benefit to requiring that the denominator be prime.
210 ///
211 /// $$
212 /// f(x, y) = \left ( \frac{x}{y} \right ).
213 /// $$
214 ///
215 /// # Worst-case complexity
216 /// $T(n) = O(n (\log n)^2 \log\log n)$
217 ///
218 /// $M(n) = O(n \log n)$
219 ///
220 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
221 /// other.significant_bits())`.
222 ///
223 /// # Panics
224 /// Panics if `self` is negative or if `other` is even.
225 ///
226 /// # Examples
227 /// ```
228 /// use malachite_base::num::arithmetic::traits::LegendreSymbol;
229 /// use malachite_nz::integer::Integer;
230 ///
231 /// assert_eq!(Integer::from(10).legendre_symbol(Integer::from(5)), 0);
232 /// assert_eq!(Integer::from(7).legendre_symbol(Integer::from(5)), -1);
233 /// assert_eq!(Integer::from(11).legendre_symbol(Integer::from(5)), 1);
234 /// assert_eq!(Integer::from(-7).legendre_symbol(Integer::from(5)), -1);
235 /// assert_eq!(Integer::from(-11).legendre_symbol(Integer::from(5)), 1);
236 /// ```
237 #[inline]
238 fn legendre_symbol(self, other: Self) -> i8 {
239 assert!(other > 0u32);
240 assert!(other.odd());
241 (&self).kronecker_symbol(&other)
242 }
243}
244
245impl LegendreSymbol<&Self> for Integer {
246 /// Computes the Legendre symbol of two [`Integer`]s, taking the first by value and the second
247 /// by reference.
248 ///
249 /// This implementation is identical to that of [`JacobiSymbol`], since there is no
250 /// computational benefit to requiring that the denominator be prime.
251 ///
252 /// $$
253 /// f(x, y) = \left ( \frac{x}{y} \right ).
254 /// $$
255 ///
256 /// # Worst-case complexity
257 /// $T(n) = O(n (\log n)^2 \log\log n)$
258 ///
259 /// $M(n) = O(n \log n)$
260 ///
261 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
262 /// other.significant_bits())`.
263 ///
264 /// # Panics
265 /// Panics if `self` is negative or if `other` is even.
266 ///
267 /// # Examples
268 /// ```
269 /// use malachite_base::num::arithmetic::traits::LegendreSymbol;
270 /// use malachite_nz::integer::Integer;
271 ///
272 /// assert_eq!(Integer::from(10).legendre_symbol(&Integer::from(5)), 0);
273 /// assert_eq!(Integer::from(7).legendre_symbol(&Integer::from(5)), -1);
274 /// assert_eq!(Integer::from(11).legendre_symbol(&Integer::from(5)), 1);
275 /// assert_eq!(Integer::from(-7).legendre_symbol(&Integer::from(5)), -1);
276 /// assert_eq!(Integer::from(-11).legendre_symbol(&Integer::from(5)), 1);
277 /// ```
278 #[inline]
279 fn legendre_symbol(self, other: &Self) -> i8 {
280 assert!(*other > 0u32);
281 assert!(other.odd());
282 (&self).kronecker_symbol(other)
283 }
284}
285
286impl LegendreSymbol<Integer> for &Integer {
287 /// Computes the Legendre symbol of two [`Integer`]s, taking the first by reference and the
288 /// second by value.
289 ///
290 /// This implementation is identical to that of [`JacobiSymbol`], since there is no
291 /// computational benefit to requiring that the denominator be prime.
292 ///
293 /// $$
294 /// f(x, y) = \left ( \frac{x}{y} \right ).
295 /// $$
296 ///
297 /// # Worst-case complexity
298 /// $T(n) = O(n (\log n)^2 \log\log n)$
299 ///
300 /// $M(n) = O(n \log n)$
301 ///
302 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
303 /// other.significant_bits())`.
304 ///
305 /// # Panics
306 /// Panics if `self` is negative or if `other` is even.
307 ///
308 /// # Examples
309 /// ```
310 /// use malachite_base::num::arithmetic::traits::LegendreSymbol;
311 /// use malachite_nz::integer::Integer;
312 ///
313 /// assert_eq!((&Integer::from(10)).legendre_symbol(Integer::from(5)), 0);
314 /// assert_eq!((&Integer::from(7)).legendre_symbol(Integer::from(5)), -1);
315 /// assert_eq!((&Integer::from(11)).legendre_symbol(Integer::from(5)), 1);
316 /// assert_eq!((&Integer::from(-7)).legendre_symbol(Integer::from(5)), -1);
317 /// assert_eq!((&Integer::from(-11)).legendre_symbol(Integer::from(5)), 1);
318 /// ```
319 #[inline]
320 fn legendre_symbol(self, other: Integer) -> i8 {
321 assert!(other > 0u32);
322 assert!(other.odd());
323 self.kronecker_symbol(&other)
324 }
325}
326
327impl LegendreSymbol<&Integer> for &Integer {
328 /// Computes the Legendre symbol of two [`Integer`]s, taking both by reference.
329 ///
330 /// This implementation is identical to that of [`JacobiSymbol`], since there is no
331 /// computational benefit to requiring that the denominator be prime.
332 ///
333 /// $$
334 /// f(x, y) = \left ( \frac{x}{y} \right ).
335 /// $$
336 ///
337 /// # Worst-case complexity
338 /// $T(n) = O(n (\log n)^2 \log\log n)$
339 ///
340 /// $M(n) = O(n \log n)$
341 ///
342 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
343 /// other.significant_bits())`.
344 ///
345 /// # Panics
346 /// Panics if `self` is negative or if `other` is even.
347 ///
348 /// # Examples
349 /// ```
350 /// use malachite_base::num::arithmetic::traits::LegendreSymbol;
351 /// use malachite_nz::integer::Integer;
352 ///
353 /// assert_eq!((&Integer::from(10)).legendre_symbol(&Integer::from(5)), 0);
354 /// assert_eq!((&Integer::from(7)).legendre_symbol(&Integer::from(5)), -1);
355 /// assert_eq!((&Integer::from(11)).legendre_symbol(&Integer::from(5)), 1);
356 /// assert_eq!((&Integer::from(-7)).legendre_symbol(&Integer::from(5)), -1);
357 /// assert_eq!((&Integer::from(-11)).legendre_symbol(&Integer::from(5)), 1);
358 /// ```
359 #[inline]
360 fn legendre_symbol(self, other: &Integer) -> i8 {
361 assert!(*other > 0u32);
362 assert!(other.odd());
363 self.kronecker_symbol(other)
364 }
365}
366
367impl JacobiSymbol<Self> for Integer {
368 /// Computes the Jacobi symbol of two [`Integer`]s, taking both by value.
369 ///
370 /// $$
371 /// f(x, y) = \left ( \frac{x}{y} \right ).
372 /// $$
373 ///
374 /// # Worst-case complexity
375 /// $T(n) = O(n (\log n)^2 \log\log n)$
376 ///
377 /// $M(n) = O(n \log n)$
378 ///
379 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
380 /// other.significant_bits())`.
381 ///
382 /// # Panics
383 /// Panics if `self` is negative or if `other` is even.
384 ///
385 /// # Examples
386 /// ```
387 /// use malachite_base::num::arithmetic::traits::JacobiSymbol;
388 /// use malachite_nz::integer::Integer;
389 ///
390 /// assert_eq!(Integer::from(10).jacobi_symbol(Integer::from(5)), 0);
391 /// assert_eq!(Integer::from(7).jacobi_symbol(Integer::from(5)), -1);
392 /// assert_eq!(Integer::from(11).jacobi_symbol(Integer::from(5)), 1);
393 /// assert_eq!(Integer::from(11).jacobi_symbol(Integer::from(9)), 1);
394 /// assert_eq!(Integer::from(-7).jacobi_symbol(Integer::from(5)), -1);
395 /// assert_eq!(Integer::from(-11).jacobi_symbol(Integer::from(5)), 1);
396 /// assert_eq!(Integer::from(-11).jacobi_symbol(Integer::from(9)), 1);
397 /// ```
398 #[inline]
399 fn jacobi_symbol(self, other: Self) -> i8 {
400 assert!(other > 0u32);
401 assert!(other.odd());
402 (&self).kronecker_symbol(&other)
403 }
404}
405
406impl JacobiSymbol<&Self> for Integer {
407 /// Computes the Jacobi symbol of two [`Integer`]s, taking the first by value and the second by
408 /// reference.
409 ///
410 /// $$
411 /// f(x, y) = \left ( \frac{x}{y} \right ).
412 /// $$
413 ///
414 /// # Worst-case complexity
415 /// $T(n) = O(n (\log n)^2 \log\log n)$
416 ///
417 /// $M(n) = O(n \log n)$
418 ///
419 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
420 /// other.significant_bits())`.
421 ///
422 /// # Panics
423 /// Panics if `self` is negative or if `other` is even.
424 ///
425 /// # Examples
426 /// ```
427 /// use malachite_base::num::arithmetic::traits::JacobiSymbol;
428 /// use malachite_nz::integer::Integer;
429 ///
430 /// assert_eq!(Integer::from(10).jacobi_symbol(&Integer::from(5)), 0);
431 /// assert_eq!(Integer::from(7).jacobi_symbol(&Integer::from(5)), -1);
432 /// assert_eq!(Integer::from(11).jacobi_symbol(&Integer::from(5)), 1);
433 /// assert_eq!(Integer::from(11).jacobi_symbol(&Integer::from(9)), 1);
434 /// assert_eq!(Integer::from(-7).jacobi_symbol(&Integer::from(5)), -1);
435 /// assert_eq!(Integer::from(-11).jacobi_symbol(&Integer::from(5)), 1);
436 /// assert_eq!(Integer::from(-11).jacobi_symbol(&Integer::from(9)), 1);
437 /// ```
438 #[inline]
439 fn jacobi_symbol(self, other: &Self) -> i8 {
440 assert!(*other > 0u32);
441 assert!(other.odd());
442 (&self).kronecker_symbol(other)
443 }
444}
445
446impl JacobiSymbol<Integer> for &Integer {
447 /// Computes the Jacobi symbol of two [`Integer`]s, taking the first by reference and the second
448 /// by value.
449 ///
450 /// $$
451 /// f(x, y) = \left ( \frac{x}{y} \right ).
452 /// $$
453 ///
454 /// # Worst-case complexity
455 /// $T(n) = O(n (\log n)^2 \log\log n)$
456 ///
457 /// $M(n) = O(n \log n)$
458 ///
459 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
460 /// other.significant_bits())`.
461 ///
462 /// # Panics
463 /// Panics if `self` is negative or if `other` is even.
464 ///
465 /// # Examples
466 /// ```
467 /// use malachite_base::num::arithmetic::traits::JacobiSymbol;
468 /// use malachite_nz::integer::Integer;
469 ///
470 /// assert_eq!((&Integer::from(10)).jacobi_symbol(Integer::from(5)), 0);
471 /// assert_eq!((&Integer::from(7)).jacobi_symbol(Integer::from(5)), -1);
472 /// assert_eq!((&Integer::from(11)).jacobi_symbol(Integer::from(5)), 1);
473 /// assert_eq!((&Integer::from(11)).jacobi_symbol(Integer::from(9)), 1);
474 /// assert_eq!((&Integer::from(-7)).jacobi_symbol(Integer::from(5)), -1);
475 /// assert_eq!((&Integer::from(-11)).jacobi_symbol(Integer::from(5)), 1);
476 /// assert_eq!((&Integer::from(-11)).jacobi_symbol(Integer::from(9)), 1);
477 /// ```
478 #[inline]
479 fn jacobi_symbol(self, other: Integer) -> i8 {
480 assert!(other > 0u32);
481 assert!(other.odd());
482 self.kronecker_symbol(&other)
483 }
484}
485
486impl JacobiSymbol<&Integer> for &Integer {
487 /// Computes the Jacobi symbol of two [`Integer`]s, taking both by reference.
488 ///
489 /// $$
490 /// f(x, y) = \left ( \frac{x}{y} \right ).
491 /// $$
492 ///
493 /// # Worst-case complexity
494 /// $T(n) = O(n (\log n)^2 \log\log n)$
495 ///
496 /// $M(n) = O(n \log n)$
497 ///
498 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
499 /// other.significant_bits())`.
500 ///
501 /// # Panics
502 /// Panics if `self` is negative or if `other` is even.
503 ///
504 /// # Examples
505 /// ```
506 /// use malachite_base::num::arithmetic::traits::JacobiSymbol;
507 /// use malachite_nz::integer::Integer;
508 ///
509 /// assert_eq!((&Integer::from(10)).jacobi_symbol(&Integer::from(5)), 0);
510 /// assert_eq!((&Integer::from(7)).jacobi_symbol(&Integer::from(5)), -1);
511 /// assert_eq!((&Integer::from(11)).jacobi_symbol(&Integer::from(5)), 1);
512 /// assert_eq!((&Integer::from(11)).jacobi_symbol(&Integer::from(9)), 1);
513 /// assert_eq!((&Integer::from(-7)).jacobi_symbol(&Integer::from(5)), -1);
514 /// assert_eq!((&Integer::from(-11)).jacobi_symbol(&Integer::from(5)), 1);
515 /// assert_eq!((&Integer::from(-11)).jacobi_symbol(&Integer::from(9)), 1);
516 /// ```
517 #[inline]
518 fn jacobi_symbol(self, other: &Integer) -> i8 {
519 assert!(*other > 0u32);
520 assert!(other.odd());
521 self.kronecker_symbol(other)
522 }
523}
524
525impl KroneckerSymbol<Self> for Integer {
526 /// Computes the Kronecker symbol of two [`Integer`]s, taking both by value.
527 ///
528 /// $$
529 /// f(x, y) = \left ( \frac{x}{y} \right ).
530 /// $$
531 ///
532 /// # Worst-case complexity
533 /// $T(n) = O(n (\log n)^2 \log\log n)$
534 ///
535 /// $M(n) = O(n \log n)$
536 ///
537 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
538 /// other.significant_bits())`.
539 ///
540 /// # Examples
541 /// ```
542 /// use malachite_base::num::arithmetic::traits::KroneckerSymbol;
543 /// use malachite_nz::integer::Integer;
544 ///
545 /// assert_eq!(Integer::from(10).kronecker_symbol(Integer::from(5)), 0);
546 /// assert_eq!(Integer::from(7).kronecker_symbol(Integer::from(5)), -1);
547 /// assert_eq!(Integer::from(11).kronecker_symbol(Integer::from(5)), 1);
548 /// assert_eq!(Integer::from(11).kronecker_symbol(Integer::from(9)), 1);
549 /// assert_eq!(Integer::from(11).kronecker_symbol(Integer::from(8)), -1);
550 /// assert_eq!(Integer::from(-7).kronecker_symbol(Integer::from(5)), -1);
551 /// assert_eq!(Integer::from(-11).kronecker_symbol(Integer::from(5)), 1);
552 /// assert_eq!(Integer::from(-11).kronecker_symbol(Integer::from(9)), 1);
553 /// assert_eq!(Integer::from(-11).kronecker_symbol(Integer::from(8)), -1);
554 /// assert_eq!(Integer::from(-11).kronecker_symbol(Integer::from(-8)), 1);
555 /// ```
556 #[inline]
557 fn kronecker_symbol(self, other: Self) -> i8 {
558 (&self).kronecker_symbol(&other)
559 }
560}
561
562impl KroneckerSymbol<&Self> for Integer {
563 /// Computes the Kronecker symbol of two [`Integer`]s, taking the first by value and the second
564 /// by reference.
565 ///
566 /// $$
567 /// f(x, y) = \left ( \frac{x}{y} \right ).
568 /// $$
569 ///
570 /// # Worst-case complexity
571 /// $T(n) = O(n (\log n)^2 \log\log n)$
572 ///
573 /// $M(n) = O(n \log n)$
574 ///
575 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
576 /// other.significant_bits())`.
577 ///
578 /// # Examples
579 /// ```
580 /// use malachite_base::num::arithmetic::traits::KroneckerSymbol;
581 /// use malachite_nz::integer::Integer;
582 ///
583 /// assert_eq!(Integer::from(10).kronecker_symbol(&Integer::from(5)), 0);
584 /// assert_eq!(Integer::from(7).kronecker_symbol(&Integer::from(5)), -1);
585 /// assert_eq!(Integer::from(11).kronecker_symbol(&Integer::from(5)), 1);
586 /// assert_eq!(Integer::from(11).kronecker_symbol(&Integer::from(9)), 1);
587 /// assert_eq!(Integer::from(11).kronecker_symbol(&Integer::from(8)), -1);
588 /// assert_eq!(Integer::from(-7).kronecker_symbol(&Integer::from(5)), -1);
589 /// assert_eq!(Integer::from(-11).kronecker_symbol(&Integer::from(5)), 1);
590 /// assert_eq!(Integer::from(-11).kronecker_symbol(&Integer::from(9)), 1);
591 /// assert_eq!(Integer::from(-11).kronecker_symbol(&Integer::from(8)), -1);
592 /// assert_eq!(Integer::from(-11).kronecker_symbol(&Integer::from(-8)), 1);
593 /// ```
594 #[inline]
595 fn kronecker_symbol(self, other: &Self) -> i8 {
596 (&self).kronecker_symbol(other)
597 }
598}
599
600impl KroneckerSymbol<Integer> for &Integer {
601 /// Computes the Kronecker symbol of two [`Integer`]s, taking the first by reference and the
602 /// second value.
603 ///
604 /// $$
605 /// f(x, y) = \left ( \frac{x}{y} \right ).
606 /// $$
607 ///
608 /// # Worst-case complexity
609 /// $T(n) = O(n (\log n)^2 \log\log n)$
610 ///
611 /// $M(n) = O(n \log n)$
612 ///
613 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
614 /// other.significant_bits())`.
615 ///
616 /// # Examples
617 /// ```
618 /// use malachite_base::num::arithmetic::traits::KroneckerSymbol;
619 /// use malachite_nz::integer::Integer;
620 ///
621 /// assert_eq!((&Integer::from(10)).kronecker_symbol(Integer::from(5)), 0);
622 /// assert_eq!((&Integer::from(7)).kronecker_symbol(Integer::from(5)), -1);
623 /// assert_eq!((&Integer::from(11)).kronecker_symbol(Integer::from(5)), 1);
624 /// assert_eq!((&Integer::from(11)).kronecker_symbol(Integer::from(9)), 1);
625 /// assert_eq!((&Integer::from(11)).kronecker_symbol(Integer::from(8)), -1);
626 /// assert_eq!((&Integer::from(-7)).kronecker_symbol(Integer::from(5)), -1);
627 /// assert_eq!((&Integer::from(-11)).kronecker_symbol(Integer::from(5)), 1);
628 /// assert_eq!((&Integer::from(-11)).kronecker_symbol(Integer::from(9)), 1);
629 /// assert_eq!((&Integer::from(-11)).kronecker_symbol(Integer::from(8)), -1);
630 /// assert_eq!((&Integer::from(-11)).kronecker_symbol(Integer::from(-8)), 1);
631 /// ```
632 #[inline]
633 fn kronecker_symbol(self, other: Integer) -> i8 {
634 self.kronecker_symbol(&other)
635 }
636}
637
638impl KroneckerSymbol<&Integer> for &Integer {
639 /// Computes the Kronecker symbol of two [`Integer`]s, taking both by reference.
640 ///
641 /// $$
642 /// f(x, y) = \left ( \frac{x}{y} \right ).
643 /// $$
644 ///
645 /// # Worst-case complexity
646 /// $T(n) = O(n (\log n)^2 \log\log n)$
647 ///
648 /// $M(n) = O(n \log n)$
649 ///
650 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
651 /// other.significant_bits())`.
652 ///
653 /// # Examples
654 /// ```
655 /// use malachite_base::num::arithmetic::traits::KroneckerSymbol;
656 /// use malachite_nz::integer::Integer;
657 ///
658 /// assert_eq!((&Integer::from(10)).kronecker_symbol(&Integer::from(5)), 0);
659 /// assert_eq!((&Integer::from(7)).kronecker_symbol(&Integer::from(5)), -1);
660 /// assert_eq!((&Integer::from(11)).kronecker_symbol(&Integer::from(5)), 1);
661 /// assert_eq!((&Integer::from(11)).kronecker_symbol(&Integer::from(9)), 1);
662 /// assert_eq!((&Integer::from(11)).kronecker_symbol(&Integer::from(8)), -1);
663 /// assert_eq!((&Integer::from(-7)).kronecker_symbol(&Integer::from(5)), -1);
664 /// assert_eq!((&Integer::from(-11)).kronecker_symbol(&Integer::from(5)), 1);
665 /// assert_eq!((&Integer::from(-11)).kronecker_symbol(&Integer::from(9)), 1);
666 /// assert_eq!(
667 /// (&Integer::from(-11)).kronecker_symbol(&Integer::from(8)),
668 /// -1
669 /// );
670 /// assert_eq!(
671 /// (&Integer::from(-11)).kronecker_symbol(&Integer::from(-8)),
672 /// 1
673 /// );
674 /// ```
675 fn kronecker_symbol(self, other: &Integer) -> i8 {
676 match (self, other) {
677 (x, integer_zero!()) => i8::from(*x.unsigned_abs_ref() == 1u32),
678 (integer_zero!(), y) => i8::from(*y.unsigned_abs_ref() == 1u32),
679 (
680 Integer {
681 sign: x_sign,
682 abs: Natural(Small(x_abs)),
683 },
684 Integer {
685 sign: y_sign,
686 abs: Natural(Small(y_abs)),
687 },
688 ) => limbs_kronecker_symbol_single(*x_sign, *x_abs, *y_sign, *y_abs),
689 (
690 Integer {
691 sign: x_sign,
692 abs: Natural(Small(x_abs)),
693 },
694 Integer {
695 sign: y_sign,
696 abs: Natural(Large(ys)),
697 },
698 ) => limbs_kronecker_symbol(*x_sign, &[*x_abs], *y_sign, ys),
699 (
700 Integer {
701 sign: x_sign,
702 abs: Natural(Large(xs)),
703 },
704 Integer {
705 sign: y_sign,
706 abs: Natural(Small(y_abs)),
707 },
708 ) => limbs_kronecker_symbol(*x_sign, xs, *y_sign, &[*y_abs]),
709 (
710 Integer {
711 sign: x_sign,
712 abs: Natural(Large(xs)),
713 },
714 Integer {
715 sign: y_sign,
716 abs: Natural(Large(ys)),
717 },
718 ) => limbs_kronecker_symbol(*x_sign, xs, *y_sign, ys),
719 }
720 }
721}