adic/lib.rs
1//! Adic number math
2//!
3//! # Adic numbers
4//!
5//! p-adic numbers are an alternate number system to the reals.
6//! This system is p-periodic and hierarchical.
7//! It is used throughout number theory, but it not well-known outside of pure math.
8//! This crate is partially an attempt to change that.
9//!
10//! ## Links
11//! - [crates.io/adic](<https://crates.io/crates/adic>)
12//! - [docs/adic](<https://docs.rs/adic/latest/adic/>)
13//! - [gitlab/adic](https://gitlab.com/pmodular/adic)
14//! - [adicmath.com](https://adicmath.com) - our site, to learn about and play with adic numbers
15//! - [crates.io/adic-shape](<https://crates.io/crates/adic-shape>) - crate for visualizations and charts of adic numbers
16//! - [wiki/P-adic_number](<https://en.wikipedia.org/wiki/P-adic_number>) - wikipedia for p-adic numbers
17//!
18//! ## References
19//!
20//! - [Murty: Introduction to p-adic...](<https://bookstore.ams.org/amsip-27/>) -
21//! Introduces p-adics starting from Bernoulli numbers and interpolation; good first book
22//! - [Koblitz: p-adic Numbers...](<https://link.springer.com/book/10.1007/978-1-4612-1112-9>) -
23//! Introduces p-adics slowly while analyzing zeta functions; good first book
24//! - [Gouveau: p-adic Numbers](https://link.springer.com/book/10.1007/978-3-030-47295-5)
25//! Widely recommended; likely a good first book
26//! - [Roberts: A Course in p-adic Analysis](<https://link.springer.com/book/10.1007/978-1-4757-3254-2>) -
27//! p-adics from Z_p through analytical functions; formal and thorough, fantastic
28//!
29//!
30//! ## Motivation
31//!
32//! Adic numbers can represent any rational number as well as many numbers between them, just like the real numbers.
33//! They can be represented similarly to the reals as infinite digital expansions.
34//! Except where the reals have a finite number of digits to the **left** of the decimal and possibly infinite to the **right**
35//! (`1.414...`), the adics have finite digits to the **right** and infinite to the **left** (`...4132.13`).
36//!
37//! ```
38//! # use adic::{traits::AdicInteger, EAdic, QAdic, UAdic, ZAdic};
39//! assert_eq!("2314._5", UAdic::new(5, vec![4, 1, 3, 2]).to_string());
40//! assert_eq!("2314._5", EAdic::new(5, vec![4, 1, 3, 2]).to_string());
41//! assert_eq!("(4)11._5", EAdic::new_neg(5, vec![1, 1]).to_string());
42//! assert_eq!("(233)4._5", EAdic::new_repeating(5, vec![4], vec![3, 3, 2]).to_string());
43//! assert_eq!("...004123._5", ZAdic::new_approx(5, 6, vec![3, 2, 1, 4]).to_string());
44//! assert_eq!("...0041.23_5", QAdic::new(ZAdic::new_approx(5, 6, vec![3, 2, 1, 4]), -2).to_string());
45//! ```
46//!
47//! You might think this means they are "infinite" numbers, but they are not.
48//! The key difference is how a number's **size** is measured.
49//!
50//! For a number, its size is its norm, its absolute value.
51//! In the reals, the size of `4` is `4`, the size of `-2.31` is `2.31`, etc.
52//!
53//! Each p-adic space is linked to a prime, `p`.
54//! In the p-adics, the size of a number is the inverse of how many powers of `p` are in it: `|x| = |a/b * p^v| = p^(-v)`.
55//! So in the 5-adics, 1, 2, 3, and 4 are all size `1`, while 5, 10, 15, and 20 are size `1/5`.
56//! When you represent these numbers as digital expansions in base-p, the numbers further to the left are **smaller**, not bigger.
57//!
58//! ```
59//! # use num::rational::Ratio;
60//! # use adic::{normed::Normed, EAdic};
61//! let one = EAdic::new(5, vec![1]);
62//! let two = EAdic::new(5, vec![2]);
63//! let three = EAdic::new(5, vec![3]);
64//! let five = EAdic::new(5, vec![0, 1]);
65//! let ten = EAdic::new(5, vec![0, 2]);
66//! let twenty_five = EAdic::new(5, vec![0, 0, 1]);
67//! let six_hundred_twenty_five = EAdic::new(5, vec![0, 0, 0, 0, 1]);
68//! assert_eq!(Ratio::new(1, 1), one.norm());
69//! assert_eq!(Ratio::new(1, 1), two.norm());
70//! assert_eq!(Ratio::new(1, 1), three.norm());
71//! assert_eq!(Ratio::new(1, 5), five.norm());
72//! assert_eq!(Ratio::new(1, 5), ten.norm());
73//! assert_eq!(Ratio::new(1, 25), twenty_five.norm());
74//! assert_eq!(Ratio::new(1, 625), six_hundred_twenty_five.norm());
75//! ```
76//!
77//! Adic numbers are used:
78//! - to solve [diophantine equations](https://en.wikipedia.org/wiki/Diophantine_equation)
79//! - as fundamental examples of [ultrametric spaces](https://en.wikipedia.org/wiki/Ultrametric_space)
80//! - to form combined local/global structures, e.g. [adeles and ideles](https://en.wikipedia.org/wiki/Adelic_algebraic_group)
81//! - in glassy physical systems, like in [replica/cavity theory](https://en.wikipedia.org/wiki/Cavity_method)
82//! - in [tropical geometry](https://en.wikipedia.org/wiki/Tropical_geometry)
83//!
84//!
85//! ## Crate
86//!
87//! This crate handles adic numbers, arithmetic, and calculations.
88//!
89//! Calculations:
90//! - Adic arithmetic: Add, Sub, Mul, Div, Pow, Neg
91//! - Rootfinding, through use of [hensel lifting](https://en.wikipedia.org/wiki/Hensel%27s_lemma)
92//! - Polynomial, power series, and sequence manipulations
93//! - Idempotent computation for `MAdic` zero divisors
94//!
95//! Adic number structs:
96//!
97//! | Struct | Type | Represents | Example |
98//! | ------ | ---- | ---------- | ------- |
99//! | [`UAdic`](num_adic::UAdic) | Integer | Unsigned ordinary integers | 86 = `321._5` |
100//! | [`EAdic`](num_adic::EAdic) | Integer | Exact p-adic integers | -7/6 = `(31)2._5` |
101//! | [`ZAdic`](num_adic::ZAdic) | Integer | Approximate p-adic integers | sqrt(6) ~= `...24031._5` |
102//! | [`QAdic<A>`](num_adic::QAdic) | Fraction | p-fractional numbers | 86/5 = `32.1_5` |
103//! | [`PowAdic<A>`](num_adic::PowAdic) | Composite | p^n-adic numbers | 86 = `3b._25` |
104//! | [`MAdic`](num_adic::MAdic) | Composite | Non-prime adic numbers | 86 = `...0086._10` |
105//!
106//! Functions:
107//! - [`Polynomial`](function::Polynomial) - Polynomial, enhanced with adic integer or adic number coefficients e.g. with rootfinding
108//! - [`PowerSeries`](function::PowerSeries) - A power series, useful for expressing special functions
109//! e.g. [the Iwasawa Log function](function::special::iwasawa_log)
110//! - [`Variety`](function::Variety) - A collection of approximate items representing the roots of a polynomial
111//!
112//! #### Example: calculate the two varieties for 7-adic sqrt(2) to 6 digits:
113//! ```
114//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
115//! use adic::{traits::AdicInteger, EAdic, Variety, ZAdic};
116//! // Create the 7-adic number 2
117//! let seven_adic_two = EAdic::new(7, vec![2]);
118//! // Take the square root of seven_adic_two, to 6 "decimal places"
119//! let sqrt_two_variety = seven_adic_two.nth_root(2, 6);
120//! assert_eq!(Ok(Variety::new(vec![
121//! ZAdic::new_approx(7, 6, vec![3, 1, 2, 6, 1, 2]),
122//! ZAdic::new_approx(7, 6, vec![4, 5, 4, 0, 5, 4]),
123//! ])), sqrt_two_variety);
124//! let roots = sqrt_two_variety?.into_roots().collect::<Vec<_>>();
125//! assert_eq!("...216213._7", roots[0].to_string());
126//! assert_eq!("...450454._7", roots[1].to_string());
127//! # Ok(()) }
128//! ```
129//!
130//! #### Example: 5-adic arithmetic
131//! ```
132//! use adic::{traits::CanTruncate, EAdic, UAdic};
133//! // 3 is a single digit (3) and no repeating digits
134//! let three = EAdic::new_repeating(5, vec![3], vec![]);
135//! // -1/6 consists only of repeating ...040404.
136//! let neg_one_sixth = EAdic::new_repeating(5, vec![], vec![4, 0]);
137//! // 3 - 1/6 = 17/6 is two digits 12. and then repeating 04
138//! let seventeen_sixth = three + neg_one_sixth;
139//! assert_eq!(EAdic::new_repeating(5, vec![2, 1], vec![4, 0]), seventeen_sixth);
140//! assert_eq!(UAdic::new(5, vec![2, 1, 4, 0, 4, 0]), seventeen_sixth.truncation(6));
141//! ```
142//!
143//! #### Example: 5-adic fourth roots of unity
144//! ```
145//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
146//! use num::traits::Pow;
147//! use adic::{traits::AdicInteger, Variety, ZAdic};
148//! // Every (odd) p-adic number space has p-1 roots of unity
149//! let roots = ZAdic::roots_of_unity(5, 6)?;
150//! assert_eq!(
151//! Variety::new(vec![
152//! ZAdic::new_approx(5, 6, vec![1]),
153//! ZAdic::new_approx(5, 6, vec![2, 1, 2, 1, 3, 4]),
154//! ZAdic::new_approx(5, 6, vec![3, 3, 2, 3, 1, 0]),
155//! ZAdic::new_approx(5, 6, vec![4, 4, 4, 4, 4, 4]),
156//! ]),
157//! roots
158//! );
159//! // Each root taken to the (5-1)-th power is approximately one
160//! for root in roots.into_roots() {
161//! assert!(root.pow(4).is_approx_one());
162//! }
163//! # Ok(()) }
164//! ```
165//!
166//!
167//! ## Future
168//!
169//! - `QXAdic` for a number from a finite extension of [`QAdic`](num_adic::QAdic)
170//! - `QCAdic` for a number in the algebraic closure of [`QAdic`](num_adic::QAdic)
171//! - `CAdic`, a "complex adic number", in the norm completion of `QCAdic`
172//! - `SAdic`, a "spherically complete adic number", in the spherical completion of `QCAdic`/`CAdic`
173
174
175// RE-EXPORTS
176
177// Re-export the version of `num` used in the API.
178pub use num;
179
180
181// MACROS
182
183// Private macros
184#[macro_use]
185mod macros;
186
187
188// MODULES
189
190// Public modules
191pub mod error;
192pub mod function;
193pub mod num_adic;
194pub mod sequence;
195pub mod traits;
196
197// Future public modules
198// None
199
200// Private modules
201mod algorithm;
202mod math;
203
204// Public submodules
205pub use math::{
206 divisible, local_num, mapping, normed,
207};
208
209
210// EXPORTS (enum, struct, trait, type)
211
212// Public exports
213#[doc(inline)]
214pub use function::{
215 Polynomial, PowerSeries, Variety,
216};
217#[doc(inline)]
218pub use num_adic::{
219 EAdic, QAdic, UAdic, ZAdic,
220};
221#[doc(inline)]
222pub use sequence::{
223 Sequence,
224};
225
226// Future public exports
227#[allow(unused_imports)]
228use math::combinatorics;
229
230// Private exports
231use num_adic::{IAdic, IntegerVariant, LazyDiv, RAdic};