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}