adic_shape/lib.rs
1// Would like to pass this in config rustdocflags, but relative paths don't work for some reason
2#![doc = "<style>"]
3#![doc = include_str!("../img/rustdoc.css")]
4#![doc = "</style>"]
5#![doc = ""]
6
7//! Draw adic visualizations
8//!
9//! #### 7-adic sqrt(2)
10#![doc = ""]
11#![doc = include_str!("../img/clock-7-sqrt-2.svg")]
12#![doc = include_str!("../img/zoomed-tree-7-sqrt-2.svg")]
13#![doc = ""]
14
15//! # Adic visualizations
16//!
17//! - Adic clocks
18//! - Adic trees
19//!
20//! ## Links
21//! - [crates.io/adic-shape](<https://crates.io/crates/adic-shape>)
22//! - [docs/adic-shape](https://docs.rs/adic-shape/latest/adic_shape/)
23//! - [gitlab/adic](https://gitlab.com/pmodular/adic)
24//! - [adicmath.com](https://adicmath.com) - our site, to learn about and play with adic numbers
25//! - [crates.io/adic](<https://crates.io/crates/adic>) - crate for adic number math
26//! - [wiki/P-adic_number](<https://en.wikipedia.org/wiki/P-adic_number>) - wikipedia for p-adic numbers
27//!
28//!
29//! ## Motivation
30//!
31//! p-adic numbers are an alternate number system to the reals, containing the rationals.
32//! Digitally, these numbers are a number expansion where there can be an infinite numbers
33//! to the LEFT of the decimal point instead of the right.
34//! Assume for this documentation that `p=5`, i.e. the digits of the adic number are
35//! `0`, `1`, `2`, `3`, or `4`.
36//!
37//! Examples:
38//! - 0 = 0._5
39//! - 1 = 1._5
40//! - 2 = 2._5
41//! - 5 = 10._5
42//! - 25 = 100._5
43//! - 53 = 203._5
44//! - -1/4 = ...111._5
45//! - 3/4 = ...112._5
46//! - 7-adic 1st sqrt(2) = ...6623164112011266421216213._7
47//! - 7-adic 2nd sqrt(2) = ...0043502554655400245450454._7
48//!
49//! ## Adic tree visualization
50//!
51//! Given this digital expansion, you can construct a visualization in the form of a tree.
52//! Imagine a tree growing from a root with five branches.
53//! Each of the branches has five branches, and each of those has five, etc.
54//! You can associate an adic number with an infinite path from the root of this tree to the top.
55//! Each digit of the number is a choice at each branch point upward,
56//! from the "ones" place to the "fives" to the "twenty-fives" and so on.
57//! E.g. the number `158 = ...00001113._5` has a choice of the "third" branch and then
58//! "one", "one", "one", and then zeros infinitely upward.
59
60#![doc = ""]
61#![doc = include_str!("../img/full-tree-158.svg")]
62#![doc = ""]
63
64//! You can also plot a "zoomed-in" version that focuses just on the chosen branches.
65//! This is usually better both for performance and ease of understanding.
66
67#![doc = ""]
68#![doc = include_str!("../img/zoomed-tree-158.svg")]
69#![doc = ""]
70
71//! ## Adic clock visualization
72//!
73//! Similarly, you can construct a visualization in the form of a clock.
74//! Again, assume `p=5`.
75//! Imagine an analog clock, but with two differences:
76//! - There are `p=5` tick marks instead of `12` or `60`.
77//! - There are an infinite number of hands,
78//! from the "seconds" hand to the "minute = 5s" hand to the "hour = 5m = 25s" hand, on and on.
79//!
80//! For each digit from the "ones" place onward, set the corresponding hand to the corresponding tick mark.
81//! It makes more sense as a "sweeping clock", e.g. if the ones place is `3` and the fives place is `1`,
82//! then set the first hand to the `3` tick and the second hand to `3/5` past the `1` tick mark.
83
84#![doc = ""]
85#![doc = include_str!("../img/clock-158.svg")]
86#![doc = ""]
87
88//! ## Crate
89//!
90//! Currently this crate creates both SVG documents and Leptos components.
91//! The display-independent code is in the `shape` directory and the `leptos` and `svg_doc`
92//! directories have the code for those displays.
93//! The [`DisplayShape`] trait provides the interface between display-independent and display code.
94//! We are oriented around a SVG display implementation, since both `leptos` and `svg` are html svg displays.
95//!
96//! Adic numbers can be visualized with clocks ([`ClockShape`], [`ClockComponent`])
97//! and with trees ([`TreeShape`], [`TreeComponent`]).
98//! Just create an adic integer with the `adic` crate, and create your desired [`DisplayShape`],
99//! either a [`ClockShape`] or [`TreeShape`].
100//! If you want to print or save a raw SVG, use the [`SvgDocDisplay`] trait.
101//! If you want to create a component for use in your `leptos` application,
102//! install this crate with the `leptos` feature flag
103//! and feed the shape into the corresponding [`ComponentDisplay`],
104//! either a [`ClockComponent`] or [`TreeComponent`].
105//!
106//! Try the examples to see how to use the leptos components.
107//! `cd` into the [`examples/leptos-clock`](https://gitlab.com/pmodular/adic/-/tree/develop/adic-shape/examples/leptos-clock)
108//! or [`examples/leptos-tree`](https://gitlab.com/pmodular/adic/-/tree/develop/adic-shape/examples/leptos-tree)
109//! directories and call `trunk serve`.
110//!
111//! #### Save clock or tree SVG
112//!
113//! ```no_run
114//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
115//! # use adic::{IAdic, SignedAdicInteger, radic};
116//! # use adic_shape::{ClockShape, ClockShapeOptions, Direction, SvgDocDisplay, TreeShape, TreeShapeOptions};
117//! let depth = 25;
118//!
119//! // Draw clock SVG
120//! let neg_158 = IAdic::from_i32(5, -158);
121//! let shape_options = ClockShapeOptions::default();
122//! let clock_shape = ClockShape::new(&neg_158, depth, shape_options)?;
123//! let svg_doc = clock_shape.create_svg_doc();
124//! svg::save("image.svg", &svg_doc)?;
125//!
126//! // Draw zoomed tree SVG
127//! let neg_one_fourth = radic!(5, [], [1]);
128//! let shape_options = TreeShapeOptions {
129//! direction: Direction::Up,
130//! dangling_direction: Some(Direction::Down),
131//! ..Default::default()
132//! };
133//! let tree_shape = TreeShape::zoomed_tree(&neg_one_fourth, depth, shape_options)?;
134//! let svg_doc = tree_shape.create_svg_doc();
135//! svg::save("image.svg", &svg_doc)?;
136//! # Ok(()) }
137//! ```
138//!
139//! #### Draw clock or tree leptos component
140//!
141//! ```no_run
142//! # use adic::{uadic, zadic_approx};
143//! # use adic_shape::{ClockComponent, ClockShape, ClockShapeOptions, Direction, SvgDocDisplay, TreeComponent, TreeShape, TreeShapeOptions};
144//! # use leptos::prelude::*;
145//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
146//! let depth = 6;
147//!
148//! // Create clock view
149//! let five_eighty_six = uadic!(5, [1, 2, 3, 4]);
150//! let shape_options = ClockShapeOptions::default();
151//! let clock_shape = ClockShape::new(&five_eighty_six, depth, shape_options)?;
152//! let clock_view = view! {
153//! <ClockComponent class="clock" clock_shape=clock_shape/>
154//! };
155//!
156//! // Create tree view
157//! let approx_7_adic_sqrt_2 = zadic_approx!(7, 6, [3, 1, 2, 6, 1, 2]);
158//! let shape_options = ClockShapeOptions::default();
159//! let shape_options = TreeShapeOptions {
160//! direction: Direction::Right,
161//! dangling_direction: Some(Direction::Down),
162//! ..Default::default()
163//! };
164//! let tree_shape = TreeShape::zoomed_tree(&approx_7_adic_sqrt_2, depth, shape_options)?;
165//! let tree_view = view! {
166//! <TreeComponent class="tree" tree_shape=tree_shape/>
167//! };
168//! # Ok(()) }
169//! ```
170//!
171//! ## Dependencies
172//!
173//! ### adic
174//!
175//! The [`adic`](https://crates.io/crates/adic) crate handles the math of adic numbers.
176//! The primary intention of the `adic-shape` crate is for visualizations of these numbers.
177//! Combining the two crates is how to get the best out of `adic-shape`.
178//!
179//! E.g. you can calculate the 7-adic +/- sqrt(2) with the `adic` crate:
180//!
181//! ```
182//! # use adic::{AdicInteger, uadic, zadic_variety};
183//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
184//! let seven_adic_sqrt_2_variety = uadic!(7, [2]).nth_root(2, 6);
185//! assert_eq!(Ok(zadic_variety!(7, 6, [
186//! [3, 1, 2, 6, 1, 2],
187//! [4, 5, 4, 0, 5, 4]
188//! ])), seven_adic_sqrt_2_variety);
189//! # Ok(()) }
190//! ```
191//!
192//! Then you can plot these calculated numbers as above.
193//!
194//! ### svg
195//!
196//! We use the [`svg`](https://crates.io/crates/svg) crate to create simple, self contained SVG of adic objects.
197//! These can be transformed into text or files.
198//!
199//! ### leptos
200//!
201//! Using the optional `leptos` feature, we export [`leptos`](https://leptos.dev/) components.
202//!
203//! There are examples, `leptos-clock` and `leptos-tree`, showing off leptos clocks and trees.
204//!
205//! ## TODO
206//!
207//! - Animations
208//! - Interactive visualizations (drag the clock hands to change numbers)
209//! - Visualizing adic functions
210//! - Visualizing higher adic spaces, e.g. finite extensions and complex adic numbers
211
212
213/// Custom error
214mod error;
215/// Raw data needed to create display
216mod shape;
217/// Adic shape svg documents
218mod svg_doc;
219
220pub use error::AdicShapeError;
221pub use shape::{
222 AdicEl,
223 ClockMovement, ClockPosition, ClockShape, ClockShapeOptions,
224 Direction, DisplayShape,
225 TreePosition, TreeShape, TreeShapeOptions,
226};
227pub use svg_doc::SvgDocDisplay;
228
229/// adic shape leptos components
230#[cfg(feature="leptos")]
231mod leptos;
232
233#[cfg(feature="leptos")]
234pub use leptos::{
235 ClockComponent,
236 ComponentDisplay,
237 TreeComponent,
238};