Skip to main content

arthroprod/
macros.rs

1/// Simpler variadic generation of [`Alpha`] values.
2/// This is the recommended way of creating raw alpha values if they are needed. Arguments
3/// are u8s in the range 0-3.
4///
5/// # Panics
6///
7/// Panics if the specified alpha indices do not correspond to an allowed alpha (see
8/// [`ALLOWED_ALPHA_FORMS`]).
9///
10/// # Examples
11///
12/// ```
13/// # #[macro_use] extern crate arthroprod; fn main() {
14/// use arthroprod::algebra::*;
15///
16/// let a1 = alpha!(0 2 3);
17/// let a2 = -alpha!(0 1);
18/// let a3 = alpha!();
19///
20/// assert_eq!(a1, Alpha::new(Sign::Pos, Form::Trivector(Index::Zero, Index::Two, Index::Three)).unwrap());
21/// assert_eq!(a2, Alpha::new(Sign::Neg, Form::Bivector(Index::Zero, Index::One)).unwrap());
22/// assert_eq!(a3, Alpha::new(Sign::Pos, Form::Point).unwrap());
23/// # }
24/// ```
25#[macro_export]
26macro_rules! alpha(
27    ($($num:expr) *) => {
28        {
29            let sign = $crate::algebra::Sign::Pos;
30            #[allow(unused_mut)]
31            let mut ixs = Vec::new();
32            $(ixs.push($crate::algebra::Index::try_from_u8($num).unwrap());)*
33
34            $crate::algebra::Alpha::try_from_indices(sign, &ixs).unwrap()
35        }
36    };
37);
38
39/// Simpler variadic generation of [`Term`] values.
40/// Terms created this way will have a default value (if one is not provided) and a
41/// magnitude of 1. See [`alpha`] for more information on how the underlying [`Alpha`]
42/// value is generated. It is also possible to specify a set of [`Xi`] values to use
43/// for the term by providing a list of strings to use as the Xi symbolic values.
44///
45/// # Panics
46///
47/// Panics if the specified alpha indices do not correspond to an allowed alpha (see
48/// [`ALLOWED_ALPHA_FORMS`]) or if the [`Xi`] values can not be converted to Strings.
49///
50/// # Examples
51///
52/// ```
53/// # #[macro_use] extern crate arthroprod; fn main() {
54/// use arthroprod::algebra::*;
55///
56/// let t1 = term!(0 2 3);
57/// let t2 = -term!("symbolic", 0 1);
58/// let t3 = term!(["X", "Y"], 2);
59///
60/// let a1 = Alpha::new(Sign::Pos, Form::Trivector(Index::Zero, Index::Two, Index::Three)).unwrap();
61/// let a2 = Alpha::new(Sign::Neg, Form::Bivector(Index::Zero, Index::One)).unwrap();
62/// let a3 = Alpha::new(Sign::Pos, Form::Vector(Index::Two)).unwrap();
63///
64/// assert_eq!(t1, Term::new(None, a1));
65/// assert_eq!(t2, Term::new(Some("symbolic"), a2));
66/// assert_eq!(t3, Term::from_xis_and_alpha(vec!["X", "Y"], a3));
67/// # }
68/// ```
69#[macro_export]
70macro_rules! term(
71    ($($num:expr) *) => {
72        {
73            let sign = $crate::algebra::Sign::Pos;
74            #[allow(unused_mut)]
75            let mut ixs = Vec::new();
76            $(ixs.push($crate::algebra::Index::try_from_u8($num).unwrap());)*
77            let alpha = $crate::algebra::Alpha::try_from_indices(sign, &ixs).unwrap();
78
79            $crate::algebra::Term::new(None, alpha)
80        }
81    };
82
83    ([$($xi:expr),+], $($num:expr) *) => {
84        {
85            let sign = $crate::algebra::Sign::Pos;
86            #[allow(unused_mut)]
87            let mut ixs = Vec::new();
88            let mut xis = vec![];
89            $(xis.push($xi);)+
90            $(ixs.push($crate::algebra::Index::try_from_u8($num).unwrap());)*
91            let alpha = $crate::algebra::Alpha::try_from_indices(sign, &ixs).unwrap();
92
93            $crate::algebra::Term::from_xis_and_alpha(xis, alpha)
94        }
95    };
96
97    ($sym:tt, $($num:expr) +) => {
98        {
99            let sign = $crate::algebra::Sign::Pos;
100            #[allow(unused_mut)]
101            let mut ixs = Vec::new();
102            $(ixs.push($crate::algebra::Index::try_from_u8($num).unwrap());)+
103            let alpha = $crate::algebra::Alpha::try_from_indices(sign, &ixs).unwrap();
104
105            $crate::algebra::Term::new(Some($sym), alpha)
106        }
107    };
108);
109
110/// Simpler variadic generation of [`MultiVector`] values.
111/// Each argument must impliment the AR trait so that it is possible to convert them to
112/// [`Term`]s, with the resulting MultiVector is the sum of all terms generated this way.
113///
114/// # Panics
115///
116/// Panics if any of the arguments do not impliment the AR trait.
117///
118/// # Examples
119///
120/// ```
121/// # #[macro_use] extern crate arthroprod; fn main() {
122/// use arthroprod::algebra::*;
123///
124/// let m1 = mvec![alpha!(1), -term!(0 3)];
125/// let mut m2 = MultiVector::new();
126/// m2.push(Term::new(None, alpha!(1)));
127/// m2.push(-term!(0 3));
128///
129/// assert_eq!(m1, m2);
130/// # }
131/// ```
132#[macro_export]
133macro_rules! mvec(
134    [$($ar_elem:expr),+] => {
135        {
136            let mut terms = Vec::new();
137            $(terms.extend($ar_elem.as_terms());)+
138
139            $crate::algebra::MultiVector::from_terms(terms)
140        }
141    };
142);
143
144/// A simple helper for constructing hashmaps with less verbosity.
145/// # Examples
146///
147/// ```
148/// # #[macro_use] extern crate arthroprod; fn main() {
149/// use std::collections::HashMap;
150///
151/// let m = map!{
152///     "foo" => vec![1, 2, 3],
153///     "bar" => vec![4, 5, 6]
154/// };
155///
156/// assert_eq!(m.get("foo"), Some(&vec![1, 2, 3]));
157/// # }
158/// ```
159#[macro_export]
160macro_rules! map(
161    { $($key:expr => $value:expr),+ } => {
162        {
163            let mut _map = ::std::collections::HashMap::new();
164            $(_map.insert($key, $value);)+
165            _map
166        }
167    };
168);