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}