Skip to main content

malachite_nz/gaussian_integer/
mod.rs

1// Copyright © 2026 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::integer::Integer;
10use core::ops::Deref;
11
12/// Traits for arithmetic.
13pub mod arithmetic;
14/// Comparison of [`ComparableGaussianInteger`]s and [`ComparableGaussianIntegerRef`]s.
15pub mod comparison;
16/// Functions for converting a [`GaussianInteger`] to and from other types and strings.
17pub mod conversion;
18/// Iterators that generate [`GaussianInteger`]s without repetition.
19pub mod exhaustive;
20/// Functions for the factorization of [`GaussianInteger`]s.
21pub mod factorization;
22/// Traits for logic and bit manipulation.
23pub mod logic;
24#[cfg(feature = "random")]
25/// Iterators that generate [`GaussianInteger`]s randomly.
26pub mod random;
27
28use malachite_base::named::Named;
29use malachite_base::num::basic::traits::{I, NegativeI, NegativeOne, One, Two, Zero};
30
31/// A Gaussian integer: a complex number whose real and imaginary parts are both integers.
32///
33/// The fields are public, since every combination of real and imaginary parts is a valid Gaussian
34/// integer.
35#[derive(Clone, Default, Eq, Hash, PartialEq)]
36#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
37pub struct GaussianInteger {
38    pub real: Integer,
39    pub imaginary: Integer,
40}
41
42/// The constant 0.
43impl Zero for GaussianInteger {
44    const ZERO: Self = Self {
45        real: Integer::ZERO,
46        imaginary: Integer::ZERO,
47    };
48}
49
50/// The constant 1.
51impl One for GaussianInteger {
52    const ONE: Self = Self {
53        real: Integer::ONE,
54        imaginary: Integer::ZERO,
55    };
56}
57
58/// The constant 2.
59impl Two for GaussianInteger {
60    const TWO: Self = Self {
61        real: Integer::TWO,
62        imaginary: Integer::ZERO,
63    };
64}
65
66/// The constant -1.
67impl NegativeOne for GaussianInteger {
68    const NEGATIVE_ONE: Self = Self {
69        real: Integer::NEGATIVE_ONE,
70        imaginary: Integer::ZERO,
71    };
72}
73
74/// The constant i.
75impl I for GaussianInteger {
76    const I: Self = Self {
77        real: Integer::ZERO,
78        imaginary: Integer::ONE,
79    };
80}
81
82/// The constant -i.
83impl NegativeI for GaussianInteger {
84    const NEGATIVE_I: Self = Self {
85        real: Integer::ZERO,
86        imaginary: Integer::NEGATIVE_ONE,
87    };
88}
89
90// Implements `Named` for `GaussianInteger`.
91impl_named!(GaussianInteger);
92
93/// `ComparableGaussianInteger` is a wrapper around a [`GaussianInteger`], taking the
94/// [`GaussianInteger`] by value.
95///
96/// The complex numbers have no total order compatible with their arithmetic, so [`GaussianInteger`]
97/// does not implement [`Ord`]. Sometimes a canonical order is wanted anyway: for sorting a list of
98/// Gaussian integers, or for using them as keys in a [`BTreeMap`](alloc::collections::BTreeMap) or
99/// a [`BTreeSet`](alloc::collections::BTreeSet). Wrapping a [`GaussianInteger`] in a
100/// `ComparableGaussianInteger` provides one: values are compared lexicographically, first by real
101/// part and then by imaginary part. This order is total, and equality under it agrees with
102/// [`GaussianInteger`] equality; it just isn't arithmetically meaningful.
103///
104/// The analogous wrapper for [`Float`](https://docs.rs/malachite-float/latest/malachite_float/)s is
105/// `ComparableFloat`, although that wrapper also changes equality behavior, something that isn't
106/// necessary here.
107///
108/// `ComparableGaussianInteger` owns its value. This is useful in many cases, for example if you
109/// want to use [`GaussianInteger`]s as keys in a map. In other situations, it is better to use
110/// [`ComparableGaussianIntegerRef`], which only has a reference to its value.
111// Serialized as its inner `GaussianInteger`, since the wrapper adds no data of its own.
112#[derive(Clone, Debug, Eq, Hash, PartialEq)]
113#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
114#[cfg_attr(feature = "serde", serde(transparent))]
115pub struct ComparableGaussianInteger(pub GaussianInteger);
116
117/// `ComparableGaussianIntegerRef` is a wrapper around a [`GaussianInteger`], taking the
118/// [`GaussianInteger`] by reference.
119///
120/// See the [`ComparableGaussianInteger`] documentation for details.
121#[derive(Clone, Debug, Eq, Hash, PartialEq)]
122pub struct ComparableGaussianIntegerRef<'a>(pub &'a GaussianInteger);
123
124impl ComparableGaussianInteger {
125    /// Borrows a [`ComparableGaussianInteger`] as a [`ComparableGaussianIntegerRef`].
126    ///
127    /// # Worst-case complexity
128    /// Constant time and additional memory.
129    ///
130    /// # Examples
131    /// ```
132    /// use malachite_base::num::basic::traits::I;
133    /// use malachite_nz::gaussian_integer::{
134    ///     ComparableGaussianInteger, ComparableGaussianIntegerRef, GaussianInteger,
135    /// };
136    ///
137    /// let x = ComparableGaussianInteger(GaussianInteger::I);
138    /// assert_eq!(
139    ///     x.as_ref(),
140    ///     ComparableGaussianIntegerRef(&GaussianInteger::I)
141    /// );
142    /// ```
143    pub const fn as_ref(&self) -> ComparableGaussianIntegerRef<'_> {
144        ComparableGaussianIntegerRef(&self.0)
145    }
146}
147
148impl Deref for ComparableGaussianInteger {
149    type Target = GaussianInteger;
150
151    /// Allows a [`ComparableGaussianInteger`] to dereference to a [`GaussianInteger`].
152    ///
153    /// ```
154    /// use malachite_base::num::basic::traits::One;
155    /// use malachite_nz::gaussian_integer::{ComparableGaussianInteger, GaussianInteger};
156    ///
157    /// let x = ComparableGaussianInteger(GaussianInteger::ONE);
158    /// assert_eq!(*x, GaussianInteger::ONE);
159    /// ```
160    fn deref(&self) -> &GaussianInteger {
161        &self.0
162    }
163}
164
165impl Deref for ComparableGaussianIntegerRef<'_> {
166    type Target = GaussianInteger;
167
168    /// Allows a [`ComparableGaussianIntegerRef`] to dereference to a [`GaussianInteger`].
169    ///
170    /// ```
171    /// use malachite_base::num::basic::traits::One;
172    /// use malachite_nz::gaussian_integer::{ComparableGaussianIntegerRef, GaussianInteger};
173    ///
174    /// let x = GaussianInteger::ONE;
175    /// let y = ComparableGaussianIntegerRef(&x);
176    /// assert_eq!(*y, GaussianInteger::ONE);
177    /// ```
178    fn deref(&self) -> &GaussianInteger {
179        self.0
180    }
181}