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);