num_dual/
macros.rs

1#[macro_export]
2macro_rules! impl_from_f {
3    ($struct:ident, [$($im:ident),*]$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
4        impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> From<F> for $struct<T, F$($(, $dim)*)?>
5        where
6            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
7            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
8        {
9            #[inline]
10            fn from(float: F) -> Self {
11                Self::from_re(T::from(float))
12            }
13        }
14    };
15}
16
17#[macro_export]
18macro_rules! impl_zero_one {
19    ($struct:ident$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
20        impl<T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> Zero for $struct<T, F$($(, $dim)*)?>
21        where
22            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
23            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
24        {
25            #[inline]
26            fn zero() -> Self {
27                Self::from_re(T::zero())
28            }
29
30            #[inline]
31            fn is_zero(&self) -> bool {
32                self.re.is_zero()
33            }
34        }
35
36        impl<T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> One for $struct<T, F$($(, $dim)*)?>
37        where
38            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
39            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
40        {
41            #[inline]
42            fn one() -> Self {
43                Self::from_re(T::one())
44            }
45
46            #[inline]
47            fn is_one(&self) -> bool {
48                self.re.is_one()
49            }
50        }
51    };
52}
53
54#[macro_export]
55macro_rules! impl_add_sub_rem {
56    ($struct:ident, [$($im:ident),*]$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
57        impl<'a, 'b, T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> Add<&'a $struct<T, F$($(, $dim)*)?>>
58            for &'b $struct<T, F$($(, $dim)*)?>
59        where
60            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
61            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
62        {
63            type Output = $struct<T, F$($(, $dim)*)?>;
64            #[inline]
65            fn add(self, other: &$struct<T, F$($(, $dim)*)?>) -> $struct<T, F$($(, $dim)*)?> {
66                Self::Output::new(self.re.clone() + &other.re, $(self.$im.clone() + &other.$im,)*)
67            }
68        }
69
70        impl<'a, 'b, T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> Sub<&'a $struct<T, F$($(, $dim)*)?>>
71            for &'b $struct<T, F$($(, $dim)*)?>
72        where
73            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
74            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
75        {
76            type Output = $struct<T, F$($(, $dim)*)?>;
77            #[inline]
78            fn sub(self, other: &$struct<T, F$($(, $dim)*)?>) -> $struct<T, F$($(, $dim)*)?> {
79                Self::Output::new(self.re.clone() - &other.re, $(self.$im.clone() - &other.$im,)*)
80            }
81        }
82
83        impl<'a, 'b, T: DualNum<F>, F$($(, $dim: Dim)*)?> Rem<&'a $struct<T, F$($(, $dim)*)?>> for &'b $struct<T, F$($(, $dim)*)?>
84        where
85            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
86            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
87        {
88            type Output = $struct<T, F$($(, $dim)*)?>;
89            #[inline]
90            fn rem(self, _other: &$struct<T, F$($(, $dim)*)?>) -> $struct<T, F$($(, $dim)*)?> {
91                unimplemented!()
92            }
93        }
94    };
95}
96
97#[macro_export]
98macro_rules! forward_binop {
99    ($struct:ident, $trt:ident, $operator:tt, $mth:ident$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
100        impl<T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> $trt<$struct<T, F$($(, $dim)*)?>> for &$struct<T, F$($(, $dim)*)?>
101        where
102            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
103            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
104        {
105            type Output = $struct<T, F$($(, $dim)*)?>;
106            #[inline]
107            fn $mth(self, rhs: $struct<T, F$($(, $dim)*)?>) -> Self::Output {
108                self $operator &rhs
109            }
110        }
111
112        impl<T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> $trt<&$struct<T, F$($(, $dim)*)?>> for $struct<T, F$($(, $dim)*)?>
113        where
114            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
115            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
116        {
117            type Output = $struct<T, F$($(, $dim)*)?>;
118            #[inline]
119            fn $mth(self, rhs: &$struct<T, F$($(, $dim)*)?>) -> Self::Output {
120                &self $operator rhs
121            }
122        }
123
124        impl<T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> $trt for $struct<T, F$($(, $dim)*)?>
125        where
126            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
127            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
128        {
129            type Output = $struct<T, F$($(, $dim)*)?>;
130            #[inline]
131            fn $mth(self, rhs: $struct<T, F$($(, $dim)*)?>) -> Self::Output {
132                &self $operator &rhs
133            }
134        }
135    };
136}
137
138#[macro_export]
139macro_rules! impl_neg {
140    ($struct:ident, [$($im:ident),*]$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
141        impl<T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> Neg for $struct<T, F$($(, $dim)*)?>
142        where
143            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
144            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
145        {
146            type Output = Self;
147            #[inline]
148            fn neg(self) -> Self {
149                -&self
150            }
151        }
152
153        impl<T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> Neg for &$struct<T, F$($(, $dim)*)?>
154        where
155            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
156            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
157        {
158            type Output = $struct<T, F$($(, $dim)*)?>;
159            #[inline]
160            fn neg(self) -> Self::Output {
161                <$struct<T, F$($(, $dim)*)?>>::new(-self.re.clone(), $(-self.$im.clone()),*)
162            }
163        }
164    };
165}
166
167#[macro_export]
168macro_rules! impl_assign_ops {
169    ($struct:ident, [$($im:ident),*]$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
170        impl<T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> MulAssign for $struct<T, F$($(, $dim)*)?>
171        where
172            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
173            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
174        {
175            #[inline]
176            fn mul_assign(&mut self, other: Self) {
177                *self = self.clone() * other;
178            }
179        }
180
181        impl<T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> DivAssign for $struct<T, F$($(, $dim)*)?>
182        where
183            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
184            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
185        {
186            #[inline]
187            fn div_assign(&mut self, other: Self) {
188                *self = self.clone() / other;
189            }
190        }
191
192        impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> AddAssign for $struct<T, F$($(, $dim)*)?>
193        where
194            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
195            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
196        {
197            #[inline]
198            fn add_assign(&mut self, other: Self) {
199                self.re += other.re;
200                $(self.$im += other.$im;)*
201            }
202        }
203
204        impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> SubAssign for $struct<T, F$($(, $dim)*)?>
205        where
206            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
207            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
208        {
209            #[inline]
210            fn sub_assign(&mut self, other: Self) {
211                self.re -= other.re;
212                $(self.$im -= other.$im;)*
213            }
214        }
215
216        impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> RemAssign for $struct<T, F$($(, $dim)*)?>
217        where
218            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
219            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
220        {
221            #[inline]
222            fn rem_assign(&mut self, _other: Self) {
223                unimplemented!()
224            }
225        }
226    };
227}
228
229#[macro_export]
230macro_rules! impl_scalar_op {
231    ($struct:ident, [$($im:ident),*]$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
232        impl<T: DualNum<F>, F: DualNumFloat$($(, $dim: Dim)*)?> Mul<F> for $struct<T, F$($(, $dim)*)?>
233        where
234            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
235            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
236        {
237            type Output = Self;
238            #[inline]
239            fn mul(mut self, other: F) -> Self {
240                self *= other;
241                self
242            }
243        }
244
245        impl<T: DualNum<F>, F: DualNumFloat$($(, $dim: Dim)*)?> MulAssign<F> for $struct<T, F$($(, $dim)*)?>
246        where
247            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
248            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
249        {
250            #[inline]
251            fn mul_assign(&mut self, other: F) {
252                self.re *= other;
253                $(self.$im *= T::from(other);)*
254            }
255        }
256
257        impl<T: DualNum<F>, F: DualNumFloat$($(, $dim: Dim)*)?> Div<F> for $struct<T, F$($(, $dim)*)?>
258        where
259            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
260            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
261        {
262            type Output = Self;
263            #[inline]
264            fn div(mut self, other: F) -> Self {
265                self /= other;
266                self
267            }
268        }
269
270        impl<T: DualNum<F>, F: DualNumFloat$($(, $dim: Dim)*)?> DivAssign<F> for $struct<T, F$($(, $dim)*)?>
271        where
272            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
273            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
274        {
275            #[inline]
276            fn div_assign(&mut self, other: F) {
277                self.re /= other;
278                $(self.$im /= T::from(other);)*
279            }
280        }
281
282        impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> Add<F> for $struct<T, F$($(, $dim)*)?>
283        where
284            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
285            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
286        {
287            type Output = Self;
288            #[inline]
289            fn add(mut self, other: F) -> Self {
290                self.re += other;
291                self
292            }
293        }
294
295        impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> AddAssign<F> for $struct<T, F$($(, $dim)*)?>
296        where
297            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
298            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
299        {
300            #[inline]
301            fn add_assign(&mut self, other: F)  {
302                self.re += other;
303            }
304        }
305
306        impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> Sub<F> for $struct<T, F$($(, $dim)*)?>
307        where
308            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
309            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
310        {
311            type Output = Self;
312            #[inline]
313            fn sub(mut self, other: F) -> Self {
314                self.re -= other;
315                self
316            }
317        }
318
319        impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> SubAssign<F> for $struct<T, F$($(, $dim)*)?>
320        where
321            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
322            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
323        {
324            #[inline]
325            fn sub_assign(&mut self, other: F)  {
326                self.re -= other;
327            }
328        }
329
330        impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> Rem<F> for $struct<T, F$($(, $dim)*)?>
331        where
332            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
333            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
334        {
335            type Output = Self;
336            #[inline]
337            fn rem(self, _other: F) -> Self {
338                unimplemented!()
339            }
340        }
341
342        impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> RemAssign<F> for $struct<T, F$($(, $dim)*)?>
343        where
344            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
345            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
346        {
347            #[inline]
348            fn rem_assign(&mut self, _other: F) {
349                unimplemented!()
350            }
351        }
352    };
353}
354
355#[macro_export]
356macro_rules! impl_inv {
357    ($struct:ident$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
358        impl<T: DualNum<F>, F: DualNumFloat$($(, $dim: Dim)*)?> Inv for $struct<T, F$($(, $dim)*)?>
359        where
360            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
361            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
362        {
363            type Output = Self;
364            #[inline]
365            fn inv(self) -> Self {
366                self.recip()
367            }
368        }
369    };
370}
371
372#[macro_export]
373macro_rules! impl_iterator {
374    ($struct:ident$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
375        impl<T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> Sum for $struct<T, F$($(, $dim)*)?>
376        where
377            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
378            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
379        {
380            #[inline]
381            fn sum<I>(iter: I) -> Self
382            where
383                I: Iterator<Item = Self>,
384            {
385                iter.fold(Self::zero(), |acc, c| acc + c)
386            }
387        }
388
389        impl<'a, T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> Sum<&'a $struct<T, F$($(, $dim)*)?>>
390            for $struct<T, F$($(, $dim)*)?>
391        where
392            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
393            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
394        {
395            #[inline]
396            fn sum<I>(iter: I) -> Self
397            where
398                I: Iterator<Item = &'a $struct<T, F$($(, $dim)*)?>>,
399            {
400                iter.fold(Self::zero(), |acc, c| acc + c)
401            }
402        }
403        impl<T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> Product for $struct<T, F$($(, $dim)*)?>
404        where
405            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
406            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
407        {
408            #[inline]
409            fn product<I>(iter: I) -> Self
410            where
411                I: Iterator<Item = Self>,
412            {
413                iter.fold(Self::one(), |acc, c| acc * c)
414            }
415        }
416        impl<'a, T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> Product<&'a $struct<T, F$($(, $dim)*)?>>
417            for $struct<T, F$($(, $dim)*)?>
418        where
419            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
420            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
421        {
422            #[inline]
423            fn product<I>(iter: I) -> Self
424            where
425                I: Iterator<Item = &'a $struct<T, F$($(, $dim)*)?>>,
426            {
427                iter.fold(Self::one(), |acc, c| acc * c)
428            }
429        }
430    };
431}
432
433#[macro_export]
434macro_rules! impl_from_primitive {
435    ($struct:ident$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
436        impl<T: DualNum<F>, F: Float + FromPrimitive$($(, $dim: Dim)*)?> FromPrimitive for $struct<T, F$($(, $dim)*)?>
437        where
438            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
439            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
440        {
441            #[inline]
442            fn from_isize(n: isize) -> Option<Self> {
443                F::from_isize(n).map(|f| f.into())
444            }
445
446            #[inline]
447            fn from_i8(n: i8) -> Option<Self> {
448                F::from_i8(n).map(|f| f.into())
449            }
450
451            #[inline]
452            fn from_i16(n: i16) -> Option<Self> {
453                F::from_i16(n).map(|f| f.into())
454            }
455
456            #[inline]
457            fn from_i32(n: i32) -> Option<Self> {
458                F::from_i32(n).map(|f| f.into())
459            }
460
461            #[inline]
462            fn from_i64(n: i64) -> Option<Self> {
463                F::from_i64(n).map(|f| f.into())
464            }
465
466            #[inline]
467            fn from_i128(n: i128) -> Option<Self> {
468                F::from_i128(n).map(|f| f.into())
469            }
470
471            #[inline]
472            fn from_usize(n: usize) -> Option<Self> {
473                F::from_usize(n).map(|f| f.into())
474            }
475
476            #[inline]
477            fn from_u8(n: u8) -> Option<Self> {
478                F::from_u8(n).map(|f| f.into())
479            }
480
481            #[inline]
482            fn from_u16(n: u16) -> Option<Self> {
483                F::from_u16(n).map(|f| f.into())
484            }
485
486            #[inline]
487            fn from_u32(n: u32) -> Option<Self> {
488                F::from_u32(n).map(|f| f.into())
489            }
490
491            #[inline]
492            fn from_u64(n: u64) -> Option<Self> {
493                F::from_u64(n).map(|f| f.into())
494            }
495
496            #[inline]
497            fn from_u128(n: u128) -> Option<Self> {
498                F::from_u128(n).map(|f| f.into())
499            }
500
501            #[inline]
502            fn from_f32(n: f32) -> Option<Self> {
503                F::from_f32(n).map(|f| f.into())
504            }
505
506            #[inline]
507            fn from_f64(n: f64) -> Option<Self> {
508                F::from_f64(n).map(|f| f.into())
509            }
510        }
511    };
512}
513
514#[macro_export]
515macro_rules! impl_signed {
516    ($struct:ident$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
517        impl<T: DualNum<F>, F: DualNumFloat$($(, $dim: Dim)*)?> Signed for $struct<T, F$($(, $dim)*)?>
518        where
519            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
520            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
521        {
522            #[inline]
523            fn abs(&self) -> Self {
524                if self.is_positive() {
525                    self.clone()
526                } else {
527                    -self
528                }
529            }
530
531            #[inline]
532            fn abs_sub(&self, other: &Self) -> Self {
533                if self.re() > other.re() {
534                    self - other
535                } else {
536                    Self::zero()
537                }
538            }
539
540            #[inline]
541            fn signum(&self) -> Self {
542                if self.is_positive() {
543                    Self::one()
544                } else if self.is_zero() {
545                    Self::zero()
546                } else {
547                    -Self::one()
548                }
549            }
550
551            #[inline]
552            fn is_positive(&self) -> bool {
553                self.re.is_positive()
554            }
555
556            #[inline]
557            fn is_negative(&self) -> bool {
558                self.re.is_negative()
559            }
560        }
561    };
562}
563
564#[macro_export]
565macro_rules! impl_float_const {
566    ($struct:ident$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
567        impl<T: DualNum<F>, F: Float + FloatConst$($(, $dim: Dim)*)?> FloatConst for $struct<T, F$($(, $dim)*)?>
568        where
569            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
570            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
571        {
572            fn E() -> Self {
573                Self::from(F::E())
574            }
575
576            fn FRAC_1_PI() -> Self {
577                Self::from(F::FRAC_1_PI())
578            }
579
580            fn FRAC_1_SQRT_2() -> Self {
581                Self::from(F::FRAC_1_SQRT_2())
582            }
583
584            fn FRAC_2_PI() -> Self {
585                Self::from(F::FRAC_2_PI())
586            }
587
588            fn FRAC_2_SQRT_PI() -> Self {
589                Self::from(F::FRAC_2_SQRT_PI())
590            }
591
592            fn FRAC_PI_2() -> Self {
593                Self::from(F::FRAC_PI_2())
594            }
595
596            fn FRAC_PI_3() -> Self {
597                Self::from(F::FRAC_PI_3())
598            }
599
600            fn FRAC_PI_4() -> Self {
601                Self::from(F::FRAC_PI_4())
602            }
603
604            fn FRAC_PI_6() -> Self {
605                Self::from(F::FRAC_PI_6())
606            }
607
608            fn FRAC_PI_8() -> Self {
609                Self::from(F::FRAC_PI_8())
610            }
611
612            fn LN_10() -> Self {
613                Self::from(F::LN_10())
614            }
615
616            fn LN_2() -> Self {
617                Self::from(F::LN_2())
618            }
619
620            fn LOG10_E() -> Self {
621                Self::from(F::LOG10_E())
622            }
623
624            fn LOG2_E() -> Self {
625                Self::from(F::LOG2_E())
626            }
627
628            fn PI() -> Self {
629                Self::from(F::PI())
630            }
631
632            fn SQRT_2() -> Self {
633                Self::from(F::SQRT_2())
634            }
635        }
636    };
637}
638
639#[macro_export]
640macro_rules! impl_num {
641    ($struct:ident$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
642        impl<T: DualNum<F> + Signed, F: Float$($(, $dim: Dim)*)?> Num for $struct<T, F$($(, $dim)*)?>
643        where
644            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
645            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
646        {
647            type FromStrRadixErr = F::FromStrRadixErr;
648            #[inline]
649            fn from_str_radix(_str: &str, _radix: u32) -> Result<Self, Self::FromStrRadixErr> {
650                unimplemented!()
651            }
652        }
653    };
654}
655
656#[macro_export]
657macro_rules! impl_dual_struct {
658    ($struct:ident$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
659        impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> $crate::DualStruct<Self,F> for $struct<T, F$($(, $dim)*)?>
660        where
661            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
662            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
663        {
664            type Real = F;
665            type Inner = T;
666            #[inline]
667            fn re(&self) -> Self::Real {
668                self.re.re()
669            }
670            #[inline]
671            fn from_inner(inner: &Self::Inner) -> Self {
672                Self::from_re(inner.clone())
673            }
674        }
675
676        impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> $crate::Mappable<Self> for $struct<T, F$($(, $dim)*)?>
677        where
678            // $($(DefaultAllocator: Allocator<$dim> + Allocator<U1, $dim> + Allocator<$dim, $dim>,)*)?
679            $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
680        {
681            type Output<O> = O;
682            #[inline]
683            fn map_dual<G: Fn(Self) -> O, O>(self, g: G) -> O {
684                g(self)
685            }
686        }
687    };
688}
689
690#[macro_export]
691macro_rules! impl_dual {
692    ($struct:ident, [$($im:ident),*]$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
693        impl_from_f!($struct, [$($im),*]$(, [$($dim),*]$(, [$($ddim),*])*)?);
694        impl_zero_one!($struct$(, [$($dim),*]$(, [$($ddim),*])*)?);
695        impl_add_sub_rem!($struct, [$($im),*]$(, [$($dim),*]$(, [$($ddim),*])*)?);
696        forward_binop!($struct, Add, +, add$(, [$($dim),*]$(, [$($ddim),*])*)?);
697        forward_binop!($struct, Sub, -, sub$(, [$($dim),*]$(, [$($ddim),*])*)?);
698        forward_binop!($struct, Mul, *, mul$(, [$($dim),*]$(, [$($ddim),*])*)?);
699        forward_binop!($struct, Div, /, div$(, [$($dim),*]$(, [$($ddim),*])*)?);
700        forward_binop!($struct, Rem, %, rem$(, [$($dim),*]$(, [$($ddim),*])*)?);
701        impl_neg!($struct, [$($im),*]$(, [$($dim),*]$(, [$($ddim),*])*)?);
702        impl_assign_ops!($struct, [$($im),*]$(, [$($dim),*]$(, [$($ddim),*])*)?);
703        impl_scalar_op!($struct, [$($im),*]$(, [$($dim),*]$(, [$($ddim),*])*)?);
704        impl_inv!($struct$(, [$($dim),*]$(, [$($ddim),*])*)?);
705        impl_iterator!($struct$(, [$($dim),*]$(, [$($ddim),*])*)?);
706        impl_from_primitive!($struct$(, [$($dim),*]$(, [$($ddim),*])*)?);
707        impl_signed!($struct$(, [$($dim),*]$(, [$($ddim),*])*)?);
708        impl_num!($struct$(, [$($dim),*]$(, [$($ddim),*])*)?);
709        impl_float_const!($struct$(, [$($dim),*]$(, [$($ddim),*])*)?);
710        impl_dual_struct!($struct$(, [$($dim),*]$(, [$($ddim),*])*)?);
711    };
712}