adic_shape/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
// Would like to pass this in config rustdocflags, but relative paths don't work for some reason
#![doc = "<style>"]
#![doc = include_str!("../img/rustdoc.css")]
#![doc = "</style>"]
#![doc = ""]

//! Draw adic visualizations
//!
//! #### 7-adic sqrt(2)
#![doc = ""]
#![doc = include_str!("../img/clock-7-sqrt-2.svg")]
#![doc = include_str!("../img/zoomed-tree-7-sqrt-2.svg")]
#![doc = ""]

//! # Adic visualizations
//!
//! - Adic clocks
//! - Adic trees
//!
//! See the [`adic`](https://crates.io/crates/adic) crate for details about adic numbers and math.
//!
//! p-adic numbers ([wiki](<https://en.wikipedia.org/wiki/P-adic_number>))
//!  are an alternate number system to the reals, containing the rationals.
//! Digitally, these numbers are a number expansion where there can be an infinite numbers
//!  to the LEFT of the decimal point instead of the right.
//! Assume for this documentation that `p=5`, i.e. the digits of the adic number are
//!  `0`, `1`, `2`, `3`, or `4`.
//!
//! Examples:
//! - 0 = 0._5
//! - 1 = 1._5
//! - 2 = 2._5
//! - 5 = 10._5
//! - 25 = 100._5
//! - 53 = 203._5
//! - -1/4 = ...111._5
//! - 3/4 = ...112._5
//! - 7-adic 1st sqrt(2) = ...6623164112011266421216213._7
//! - 7-adic 2nd sqrt(2) = ...0043502554655400245450454._7
//!
//! ## Adic tree visualization
//!
//! Given this digital expansion, you can construct a visualization in the form of a tree.
//! Imagine a tree growing from a root with five branches.
//! Each of the branches has five branches, and each of those has five, etc.
//! You can associate an adic number with an infinite path from the root of this tree to the top.
//! Each digit of the number is a choice at each branch point upward,
//!  from the "ones" place to the "fives" to the "twenty-fives" and so on.
//! E.g. the number `158 = ...00001113._5` has a choice of the "third" branch and then
//!  "one", "one", "one", and then zeros infinitely upward.

#![doc = ""]
#![doc = include_str!("../img/full-tree-158.svg")]
#![doc = ""]

//! You can also plot a "zoomed-in" version that focuses just on the chosen branches.
//! This is usually better both for performance and ease of understanding.

#![doc = ""]
#![doc = include_str!("../img/zoomed-tree-158.svg")]
#![doc = ""]

//! ## Adic clock visualization
//!
//! Similarly, you can construct a visualization in the form of a clock.
//! Again, assume `p=5`.
//! Imagine an analog clock, but with two differences:
//! - There are `p=5` tick marks instead of `12` or `60`.
//! - There are an infinite number of hands,
//!   from the "seconds" hand to the "minute = 5s" hand to the "hour = 5m = 25s" hand, on and on.
//!
//! For each digit from the "ones" place onward, set the corresponding hand to the corresponding tick mark.
//! It makes more sense as a "sweeping clock", e.g. if the ones place is `3` and the fives place is `1`,
//!  then set the first hand to the `3` tick and the second hand to `3/5` past the `1` tick mark.

#![doc = ""]
#![doc = include_str!("../img/clock-158.svg")]
#![doc = ""]

//! ## Crate
//!
//! Currently this crate creates both SVG documents and Leptos components.
//! The display-independent code is in the `shape` directory and the `leptos` and `svg_doc`
//!  directories have the code for those displays.
//! The [`DisplayShape`] trait provides the interface between display-independent and display code.
//! We are oriented around a SVG display implementation, since both `leptos` and `svg` are html svg displays.
//!
//! Adic numbers can be visualized with clocks ([`ClockShape`], [`ClockComponent`])
//!  and with trees ([`TreeShape`], [`TreeComponent`]).
//! Just create an adic integer with the `adic` crate, and create your desired [`DisplayShape`],
//!  either a [`ClockShape`] or [`TreeShape`].
//! If you want to print or save a raw SVG, use the [`SvgDocDisplay`] trait.
//! If you want to create a component for use in your `leptos` application,
//!  install this crate with the `leptos` feature flag
//!  and feed the shape into the corresponding [`ComponentDisplay`],
//!  either a [`ClockComponent`] or [`TreeComponent`].
//!
//! Try the examples to see how to use the leptos components.
//! `cd` into the [`examples/leptos-clock`](https://gitlab.com/pmodular/adic/-/tree/develop/adic-shape/examples/leptos-clock)
//!  or [`examples/leptos-tree`](https://gitlab.com/pmodular/adic/-/tree/develop/adic-shape/examples/leptos-tree)
//!  directories and call `trunk serve`.
//!
//! #### Save clock or tree SVG
//!
//! ```no_run
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! # use adic::{IAdic, SignedAdicInteger, radic};
//! # use adic_shape::{ClockShape, ClockShapeOptions, Direction, SvgDocDisplay, TreeShape, TreeShapeOptions};
//! let depth = 25;
//!
//! // Draw clock SVG
//! let neg_158 = IAdic::from_i32(5, -158);
//! let shape_options = ClockShapeOptions::default();
//! let clock_shape = ClockShape::new(&neg_158, depth, shape_options)?;
//! let svg_doc = clock_shape.create_svg_doc();
//! svg::save("image.svg", &svg_doc)?;
//!
//! // Draw zoomed tree SVG
//! let neg_one_fourth = radic!(5, [], [1]);
//! let shape_options = TreeShapeOptions {
//!     direction: Direction::Up,
//!     dangling_direction: Some(Direction::Down),
//!     ..Default::default()
//! };
//! let tree_shape = TreeShape::zoomed_tree(&neg_one_fourth, depth, shape_options)?;
//! let svg_doc = tree_shape.create_svg_doc();
//! svg::save("image.svg", &svg_doc)?;
//! # Ok(()) }
//! ```
//!
//! #### Draw clock or tree leptos component
//!
//! ```no_run
//! # use adic::{uadic, zadic_approx};
//! # use adic_shape::{ClockComponent, ClockShape, ClockShapeOptions, Direction, SvgDocDisplay, TreeComponent, TreeShape, TreeShapeOptions};
//! # use leptos::prelude::*;
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let depth = 6;
//!
//! // Create clock view
//! let five_eighty_six = uadic!(5, [1, 2, 3, 4]);
//! let shape_options = ClockShapeOptions::default();
//! let clock_shape = ClockShape::new(&five_eighty_six, depth, shape_options)?;
//! let clock_view = view! {
//!     <ClockComponent class="clock" clock_shape=clock_shape/>
//! };
//!
//! // Create tree view
//! let approx_7_adic_sqrt_2 = zadic_approx!(7, 6, [3, 1, 2, 6, 1, 2]);
//! let shape_options = ClockShapeOptions::default();
//! let shape_options = TreeShapeOptions {
//!     direction: Direction::Right,
//!     dangling_direction: Some(Direction::Down),
//!     ..Default::default()
//! };
//! let tree_shape = TreeShape::zoomed_tree(&approx_7_adic_sqrt_2, depth, shape_options)?;
//! let tree_view = view! {
//!     <TreeComponent class="tree" tree_shape=tree_shape/>
//! };
//! # Ok(()) }
//! ```
//!
//! ## Dependencies
//!
//! ### adic
//!
//! The [`adic`](https://crates.io/crates/adic) crate handles the math of adic numbers.
//! The primary intention of the `adic-shape` crate is for visualizations of these numbers.
//! Combining the two crates is how to get the best out of `adic-shape`.
//!
//! E.g. you can calculate the 7-adic +/- sqrt(2) with the `adic` crate:
//!
//! ```
//! # use adic::{AdicInteger, uadic, zadic_variety};
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let seven_adic_sqrt_2_variety = uadic!(7, [2]).nth_root(2, 6);
//! assert_eq!(Ok(zadic_variety!(7, 6, [
//!     [3, 1, 2, 6, 1, 2],
//!     [4, 5, 4, 0, 5, 4]
//! ])), seven_adic_sqrt_2_variety);
//! # Ok(()) }
//! ```
//!
//! Then you can plot these calculated numbers as above.
//!
//! ### svg
//!
//! We use the [`svg`](https://crates.io/crates/svg) crate to create simple, self contained SVG of adic objects.
//! These can be transformed into text or files.
//!
//! ### leptos
//!
//! Using the optional `leptos` feature, we export [`leptos`](https://leptos.dev/) components.
//!
//! There are examples, `leptos-clock` and `leptos-tree`, showing off leptos clocks and trees.
//!
//! ## TODO
//!
//! - Animations
//! - Interactive visualizations (drag the clock hands to change numbers)
//! - Visualizing adic functions
//! - Visualizing higher adic spaces, e.g. finite extensions and complex adic numbers


/// Custom error
mod error;
/// Raw data needed to create display
mod shape;
/// Adic shape svg documents
mod svg_doc;

pub use error::AdicShapeError;
pub use shape::{
    AdicEl,
    ClockMovement, ClockPosition, ClockShape, ClockShapeOptions,
    Direction, DisplayShape,
    TreePosition, TreeShape, TreeShapeOptions,
};
pub use svg_doc::SvgDocDisplay;

/// adic shape leptos components
#[cfg(feature="leptos")]
mod leptos;

#[cfg(feature="leptos")]
pub use leptos::{
    ClockComponent,
    ComponentDisplay,
    TreeComponent,
};