1macro_rules! impl_math_consts {
2 ($T:ty) => {
3 impl $crate::MathConsts for $T {
4 const E: Self = Self::from_f64(core::f64::consts::E);
5 const FRAC_1_PI: Self = Self::from_f64(core::f64::consts::FRAC_1_PI);
6 const FRAC_1_SQRT_2: Self = Self::from_f64(core::f64::consts::FRAC_1_SQRT_2);
7 const FRAC_2_PI: Self = Self::from_f64(core::f64::consts::FRAC_2_PI);
8 const FRAC_2_SQRT_PI: Self = Self::from_f64(core::f64::consts::FRAC_2_SQRT_PI);
9 const FRAC_PI_2: Self = Self::from_f64(core::f64::consts::FRAC_PI_2);
10 const FRAC_PI_3: Self = Self::from_f64(core::f64::consts::FRAC_PI_3);
11 const FRAC_PI_4: Self = Self::from_f64(core::f64::consts::FRAC_PI_4);
12 const FRAC_PI_6: Self = Self::from_f64(core::f64::consts::FRAC_PI_6);
13 const FRAC_PI_8: Self = Self::from_f64(core::f64::consts::FRAC_PI_8);
14 const LN_10: Self = Self::from_f64(core::f64::consts::LN_10);
15 const LN_2: Self = Self::from_f64(core::f64::consts::LN_2);
16 const LOG10_E: Self = Self::from_f64(core::f64::consts::LOG10_E);
17 const LOG2_E: Self = Self::from_f64(core::f64::consts::LOG2_E);
18 const PI: Self = Self::from_f64(core::f64::consts::PI);
19 const SQRT_2: Self = Self::from_f64(core::f64::consts::SQRT_2);
20 const LOG2_10: Self = Self::from_f64(core::f64::consts::LOG2_10);
21 const LOG10_2: Self = Self::from_f64(core::f64::consts::LOG10_2);
22 }
23 };
24}
25pub(crate) use impl_math_consts;
26
27macro_rules! impl_const_fns {
28 ($T:ty) => {
29 impl $T {
30 #[inline]
31 pub const fn abs(self) -> Self {
32 if self.is_sign_negative() {
33 self.neg()
34 } else {
35 self
36 }
37 }
38 #[inline]
39 pub const fn is_zero(self) -> bool {
40 self.eq(Self::ZERO)
41 }
42 #[inline]
43 pub const fn is_nar(self) -> bool {
44 self.eq(Self::NAR)
45 }
46 #[inline]
47 pub const fn is_nan(self) -> bool {
48 self.is_nar()
49 }
50 #[inline]
51 pub const fn is_infinite(self) -> bool {
52 self.is_nar()
53 }
54 #[inline]
55 pub const fn is_finite(self) -> bool {
56 !self.is_nar()
57 }
58 #[inline]
59 pub const fn is_normal(self) -> bool {
60 !self.is_nar()
61 }
62 #[inline]
63 pub const fn clamp(mut self, min: Self, max: Self) -> Self {
64 assert!(min.le(max));
65 if self.lt(min) {
66 self = min;
67 }
68 if self.gt(max) {
69 self = max;
70 }
71 self
72 }
73 #[inline]
74 pub const fn min(self, other: Self) -> Self {
75 if self.lt(other) {
76 self
77 } else {
78 other
79 }
80 }
81 #[inline]
82 pub const fn max(self, other: Self) -> Self {
83 if self.gt(other) {
84 self
85 } else {
86 other
87 }
88 }
89 #[inline]
90 pub const fn classify(self) -> core::num::FpCategory {
91 use core::num::FpCategory::*;
92 match self {
93 Self::ZERO => Zero,
94 Self::NAR => Nan,
95 _ => Normal,
96 }
97 }
98 #[inline]
99 pub const fn is_sign_positive(self) -> bool {
100 !self.is_sign_negative()
101 }
102 #[inline]
103 pub const fn is_sign_negative(self) -> bool {
104 self.lt(Self::ZERO)
105 }
106 #[inline]
107 pub const fn signum(self) -> Self {
108 match self.0 {
109 n if n == Self::NAR.0 => Self::NAR,
110 n if n > 0 => Self::ONE,
111 0 => Self::ZERO,
112 _ => Self::ONE.neg(),
113 }
114 }
115 #[inline]
116 pub const fn copysign(self, other: Self) -> Self {
117 if ((self.to_bits() ^ other.to_bits()) & Self::SIGN_MASK) != 0 {
118 self.neg()
119 } else {
120 self
121 }
122 }
123 #[inline]
124 pub const fn eq(self, other: Self) -> bool {
125 self.0 == other.0
126 }
127 #[inline]
128 pub const fn cmp(self, other: Self) -> Ordering {
129 let a = self.0;
130 let b = other.0;
131 if a == b {
132 Ordering::Equal
133 } else if a < b {
134 Ordering::Less
135 } else {
136 Ordering::Greater
137 }
138 }
139 #[inline]
140 pub const fn lt(&self, other: Self) -> bool {
141 self.0 < other.0
142 }
143 #[inline]
144 pub const fn le(&self, other: Self) -> bool {
145 self.0 <= other.0
146 }
147 #[inline]
148 pub const fn ge(&self, other: Self) -> bool {
149 self.0 >= other.0
150 }
151 #[inline]
152 pub const fn gt(&self, other: Self) -> bool {
153 self.0 > other.0
154 }
155 }
156 };
157}
158pub(crate) use impl_const_fns;
159
160macro_rules! impl_ops {
161 ($T:ty) => {
162 impl ops::Neg for $T {
163 type Output = Self;
164 #[inline]
165 fn neg(self) -> Self {
166 self.neg()
167 }
168 }
169
170 impl ops::Add for $T {
171 type Output = Self;
172 #[inline]
173 fn add(self, other: Self) -> Self {
174 self.add(other)
175 }
176 }
177
178 impl ops::Sub for $T {
179 type Output = Self;
180 #[inline]
181 fn sub(self, other: Self) -> Self {
182 self.sub(other)
183 }
184 }
185
186 impl ops::Div for $T {
187 type Output = Self;
188 #[inline]
189 fn div(self, other: Self) -> Self {
190 self.div(other)
191 }
192 }
193
194 impl ops::Mul for $T {
195 type Output = Self;
196 #[inline]
197 fn mul(self, other: Self) -> Self {
198 self.mul(other)
199 }
200 }
201
202 impl ops::Rem for $T {
203 type Output = Self;
204 fn rem(self, other: Self) -> Self {
205 self.rem(other)
206 }
207 }
208
209 impl ops::AddAssign for $T {
210 #[inline]
211 fn add_assign(&mut self, other: Self) {
212 *self = *self + other
213 }
214 }
215
216 impl ops::SubAssign for $T {
217 #[inline]
218 fn sub_assign(&mut self, other: Self) {
219 *self = *self - other
220 }
221 }
222
223 impl ops::MulAssign for $T {
224 #[inline]
225 fn mul_assign(&mut self, other: Self) {
226 *self = *self * other
227 }
228 }
229
230 impl ops::DivAssign for $T {
231 #[inline]
232 fn div_assign(&mut self, other: Self) {
233 *self = *self / other
234 }
235 }
236
237 impl ops::RemAssign for $T {
238 #[inline]
239 fn rem_assign(&mut self, other: Self) {
240 *self = *self % other
241 }
242 }
243 };
244}
245pub(crate) use impl_ops;
246
247macro_rules! impl_num_traits {
248 ($posit:ty) => {
249 impl num_traits::Zero for $posit {
250 fn zero() -> Self {
251 Self::ZERO
252 }
253 fn is_zero(&self) -> bool {
254 *self == Self::ZERO
255 }
256 }
257
258 impl num_traits::One for $posit {
259 #[inline]
260 fn one() -> Self {
261 Self::ONE
262 }
263 #[inline]
264 fn is_one(&self) -> bool {
265 *self == Self::ONE
266 }
267 }
268
269 impl num_traits::Num for $posit {
270 type FromStrRadixErr = num_traits::ParseFloatError;
271 fn from_str_radix(src: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
272 Ok(Self::from(f64::from_str_radix(src, radix)?))
273 }
274 }
275
276 impl num_traits::ToPrimitive for $posit {
277 fn to_i64(&self) -> Option<i64> {
278 Some((*self).to_i64())
279 }
280 fn to_u64(&self) -> Option<u64> {
281 Some((*self).to_u64())
282 }
283 fn to_f64(&self) -> Option<f64> {
284 Some((*self).to_f64())
285 }
286 }
287
288 impl num_traits::NumCast for $posit {
289 fn from<N: num_traits::ToPrimitive>(n: N) -> Option<Self> {
290 n.to_f64().map(|x| x.into())
291 }
292 }
293
294 impl num_traits::FromPrimitive for $posit {
295 #[inline]
296 fn from_i8(n: i8) -> Option<$posit> {
297 Some(Self::from_i8(n))
298 }
299 #[inline]
300 fn from_i16(n: i16) -> Option<$posit> {
301 Some(Self::from_i16(n))
302 }
303 #[inline]
304 fn from_i32(n: i32) -> Option<$posit> {
305 Some(Self::from_i32(n))
306 }
307 #[inline]
308 fn from_i64(n: i64) -> Option<$posit> {
309 Some(Self::from_i64(n))
310 }
311
312 #[inline]
313 fn from_u8(n: u8) -> Option<$posit> {
314 Some(Self::from_u8(n))
315 }
316 #[inline]
317 fn from_u16(n: u16) -> Option<$posit> {
318 Some(Self::from_u16(n))
319 }
320 #[inline]
321 fn from_u32(n: u32) -> Option<$posit> {
322 Some(Self::from_u32(n))
323 }
324 #[inline]
325 fn from_u64(n: u64) -> Option<$posit> {
326 Some(Self::from_u64(n))
327 }
328
329 #[inline]
330 fn from_f32(f: f32) -> Option<$posit> {
331 Some(Self::from_f32(f))
332 }
333 #[inline]
334 fn from_f64(f: f64) -> Option<$posit> {
335 Some(Self::from_f64(f))
336 }
337 }
338
339 impl num_traits::Signed for $posit {
340 fn abs(&self) -> Self {
341 Self::abs(*self)
342 }
343 fn abs_sub(&self, other: &Self) -> Self {
344 if *self <= *other {
345 Self::ZERO
346 } else {
347 *self - *other
348 }
349 }
350 fn signum(&self) -> Self {
351 Self::signum(*self)
352 }
353 fn is_positive(&self) -> bool {
354 !self.is_negative()
355 }
356 fn is_negative(&self) -> bool {
357 self.0 < 0
358 }
359 }
360
361 impl num_traits::Float for $posit {
362 fn nan() -> Self {
363 Self::NAR
364 }
365 fn infinity() -> Self {
366 Self::NAR
367 }
368 fn neg_infinity() -> Self {
369 Self::NAR
370 }
371 fn neg_zero() -> Self {
372 Self::ZERO
373 }
374 fn min_value() -> Self {
375 Self::MIN
376 }
377 fn min_positive_value() -> Self {
378 Self::MIN_POSITIVE
379 }
380 fn max_value() -> Self {
381 Self::MAX
382 }
383 fn is_nan(self) -> bool {
384 self == Self::NAR
385 }
386 fn is_infinite(self) -> bool {
387 self == Self::NAR
388 }
389 fn is_finite(self) -> bool {
390 !self.is_nar()
391 }
392 fn is_normal(self) -> bool {
393 !self.is_nar()
394 }
395 fn classify(self) -> core::num::FpCategory {
396 Self::classify(self)
397 }
398 fn floor(self) -> Self {
399 Self::floor(self)
400 }
401 fn ceil(self) -> Self {
402 Self::ceil(self)
403 }
404 fn round(self) -> Self {
405 Self::round(self)
406 }
407 fn trunc(self) -> Self {
408 Self::trunc(self)
409 }
410 fn fract(self) -> Self {
411 Self::fract(self)
412 }
413 fn abs(self) -> Self {
414 Self::abs(self)
415 }
416 fn signum(self) -> Self {
417 Self::signum(self)
418 }
419 fn is_sign_positive(self) -> bool {
420 Self::is_sign_positive(self)
421 }
422 fn is_sign_negative(self) -> bool {
423 Self::is_sign_negative(self)
424 }
425 fn mul_add(self, a: Self, b: Self) -> Self {
426 Self::mul_add(self, a, b)
427 }
428 fn recip(self) -> Self {
429 Self::recip(self)
430 }
431 fn powi(self, n: i32) -> Self {
432 Self::powi(self, n)
433 }
434 fn powf(self, n: Self) -> Self {
435 Self::powf(self, n)
436 }
437 fn sqrt(self) -> Self {
438 Self::sqrt(self)
439 }
440 fn exp(self) -> Self {
441 Self::exp(self)
442 }
443 fn exp2(self) -> Self {
444 Self::exp2(self)
445 }
446 fn ln(self) -> Self {
447 Self::ln(self)
448 }
449 fn log(self, base: Self) -> Self {
450 Self::log(self, base)
451 }
452 fn log2(self) -> Self {
453 Self::log2(self)
454 }
455 fn log10(self) -> Self {
456 Self::log10(self)
457 }
458 fn max(self, other: Self) -> Self {
459 core::cmp::Ord::max(self, other)
460 }
461 fn min(self, other: Self) -> Self {
462 core::cmp::Ord::min(self, other)
463 }
464 fn abs_sub(self, _other: Self) -> Self {
465 todo!()
466 }
467 fn cbrt(self) -> Self {
468 Self::cbrt(self)
469 }
470 fn hypot(self, other: Self) -> Self {
471 Self::hypot(self, other)
472 }
473 fn sin(self) -> Self {
474 Self::sin(self)
475 }
476 fn cos(self) -> Self {
477 Self::cos(self)
478 }
479 fn tan(self) -> Self {
480 Self::tan(self)
481 }
482 fn asin(self) -> Self {
483 Self::asin(self)
484 }
485 fn acos(self) -> Self {
486 Self::acos(self)
487 }
488 fn atan(self) -> Self {
489 Self::atan(self)
490 }
491 fn atan2(self, other: Self) -> Self {
492 Self::atan2(self, other)
493 }
494 fn sin_cos(self) -> (Self, Self) {
495 Self::sin_cos(self)
496 }
497 fn exp_m1(self) -> Self {
498 Self::exp_m1(self)
499 }
500 fn ln_1p(self) -> Self {
501 Self::ln_1p(self)
502 }
503 fn sinh(self) -> Self {
504 Self::sinh(self)
505 }
506 fn cosh(self) -> Self {
507 Self::cosh(self)
508 }
509 fn tanh(self) -> Self {
510 Self::tanh(self)
511 }
512 fn asinh(self) -> Self {
513 Self::asinh(self)
514 }
515 fn acosh(self) -> Self {
516 Self::acosh(self)
517 }
518 fn atanh(self) -> Self {
519 Self::atanh(self)
520 }
521 fn integer_decode(self) -> (u64, i16, i8) {
522 todo!()
523 }
524 }
525
526 use $crate::MathConsts;
527 impl num_traits::FloatConst for $posit {
528 fn E() -> Self {
529 MathConsts::E
530 }
531 fn FRAC_1_PI() -> Self {
532 MathConsts::FRAC_1_PI
533 }
534 fn FRAC_1_SQRT_2() -> Self {
535 MathConsts::FRAC_1_SQRT_2
536 }
537 fn FRAC_2_PI() -> Self {
538 MathConsts::FRAC_2_PI
539 }
540 fn FRAC_2_SQRT_PI() -> Self {
541 MathConsts::FRAC_2_SQRT_PI
542 }
543 fn FRAC_PI_2() -> Self {
544 MathConsts::FRAC_PI_2
545 }
546 fn FRAC_PI_3() -> Self {
547 MathConsts::FRAC_PI_3
548 }
549 fn FRAC_PI_4() -> Self {
550 MathConsts::FRAC_PI_4
551 }
552 fn FRAC_PI_6() -> Self {
553 MathConsts::FRAC_PI_6
554 }
555 fn FRAC_PI_8() -> Self {
556 MathConsts::FRAC_PI_8
557 }
558 fn LN_10() -> Self {
559 MathConsts::LN_10
560 }
561 fn LN_2() -> Self {
562 MathConsts::LN_2
563 }
564 fn LOG10_E() -> Self {
565 MathConsts::LOG10_E
566 }
567 fn LOG2_E() -> Self {
568 MathConsts::LOG2_E
569 }
570 fn PI() -> Self {
571 MathConsts::PI
572 }
573 fn SQRT_2() -> Self {
574 MathConsts::SQRT_2
575 }
576 }
577
578 impl num_traits::Bounded for $posit {
579 fn min_value() -> Self {
580 Self::MIN
581 }
582 fn max_value() -> Self {
583 Self::MAX
584 }
585 }
586 };
587}
588pub(crate) use impl_num_traits;
589
590macro_rules! impl_convert {
591 ($posit:ty) => {
592 impl From<i8> for $posit {
593 #[inline]
594 fn from(a: i8) -> Self {
595 Self::from_i8(a)
596 }
597 }
598
599 impl From<$posit> for i8 {
600 #[inline]
601 fn from(a: $posit) -> Self {
602 a.to_i8()
603 }
604 }
605
606 impl From<i16> for $posit {
607 #[inline]
608 fn from(a: i16) -> Self {
609 Self::from_i16(a)
610 }
611 }
612
613 impl From<$posit> for i16 {
614 #[inline]
615 fn from(a: $posit) -> Self {
616 a.to_i16()
617 }
618 }
619
620 impl From<isize> for $posit {
621 #[inline]
622 fn from(a: isize) -> Self {
623 Self::from_isize(a)
624 }
625 }
626
627 impl From<$posit> for isize {
628 #[inline]
629 fn from(a: $posit) -> Self {
630 a.to_isize()
631 }
632 }
633
634 impl From<u8> for $posit {
635 #[inline]
636 fn from(a: u8) -> Self {
637 Self::from_u8(a)
638 }
639 }
640
641 impl From<$posit> for u8 {
642 #[inline]
643 fn from(a: $posit) -> Self {
644 a.to_u8()
645 }
646 }
647
648 impl From<u16> for $posit {
649 #[inline]
650 fn from(a: u16) -> Self {
651 Self::from_u16(a)
652 }
653 }
654
655 impl From<$posit> for u16 {
656 #[inline]
657 fn from(a: $posit) -> Self {
658 a.to_u16()
659 }
660 }
661
662 impl From<usize> for $posit {
663 #[inline]
664 fn from(a: usize) -> Self {
665 Self::from_usize(a)
666 }
667 }
668
669 impl From<$posit> for usize {
670 #[inline]
671 fn from(a: $posit) -> Self {
672 a.to_usize()
673 }
674 }
675
676 impl $posit {
677 #[inline]
678 pub const fn from_i8(a: i8) -> Self {
679 Self::from_i32(a as i32)
680 }
681
682 #[inline]
683 pub const fn to_i8(self) -> i8 {
684 self.to_i32() as i8
685 }
686
687 #[inline]
688 pub const fn from_i16(a: i16) -> Self {
689 Self::from_i32(a as i32)
690 }
691
692 #[inline]
693 pub const fn to_i16(self) -> i16 {
694 self.to_i32() as i16
695 }
696
697 #[inline]
698 pub const fn from_isize(a: isize) -> Self {
699 Self::from_i64(a as i64)
700 }
701
702 #[inline]
703 pub const fn to_isize(self) -> isize {
704 self.to_i64() as isize
705 }
706
707 #[inline]
708 pub const fn from_u8(a: u8) -> Self {
709 Self::from_u32(a as u32)
710 }
711
712 #[inline]
713 pub const fn to_u8(self) -> u8 {
714 self.to_u32() as u8
715 }
716
717 #[inline]
718 pub const fn from_u16(a: u16) -> Self {
719 Self::from_u32(a as u32)
720 }
721
722 #[inline]
723 pub const fn to_u16(self) -> u16 {
724 self.to_u32() as u16
725 }
726
727 #[inline]
728 pub const fn from_usize(a: usize) -> Self {
729 Self::from_u64(a as u64)
730 }
731
732 #[inline]
733 pub const fn to_usize(self) -> usize {
734 self.to_u64() as usize
735 }
736 }
737
738 impl From<f32> for $posit {
739 #[inline]
740 fn from(float: f32) -> Self {
741 Self::from_f32(float)
742 }
743 }
744
745 impl From<f64> for $posit {
746 #[inline]
747 fn from(float: f64) -> Self {
748 Self::from_f64(float)
749 }
750 }
751
752 impl From<$posit> for f32 {
753 #[inline]
754 fn from(p_a: $posit) -> Self {
755 p_a.to_f32()
756 }
757 }
758
759 impl From<$posit> for f64 {
760 #[inline]
761 fn from(p_a: $posit) -> Self {
762 p_a.to_f64()
763 }
764 }
765
766 impl From<$posit> for i32 {
767 #[inline]
768 fn from(p_a: $posit) -> Self {
769 p_a.to_i32()
770 }
771 }
772
773 impl From<$posit> for i64 {
774 #[inline]
775 fn from(p_a: $posit) -> Self {
776 p_a.to_i64()
777 }
778 }
779
780 impl From<u32> for $posit {
781 #[inline]
782 fn from(a: u32) -> Self {
783 Self::from_u32(a)
784 }
785 }
786
787 impl From<i32> for $posit {
788 #[inline]
789 fn from(i_a: i32) -> Self {
790 Self::from_i32(i_a)
791 }
792 }
793
794 impl From<u64> for $posit {
795 #[inline]
796 fn from(a: u64) -> Self {
797 Self::from_u64(a)
798 }
799 }
800
801 impl From<i64> for $posit {
802 #[inline]
803 fn from(i_a: i64) -> Self {
804 Self::from_i64(i_a)
805 }
806 }
807
808 impl From<$posit> for u64 {
809 #[inline]
810 fn from(p_a: $posit) -> Self {
811 p_a.to_u64()
812 }
813 }
814
815 impl From<$posit> for u32 {
816 #[inline]
817 fn from(p_a: $posit) -> Self {
818 p_a.to_u32()
819 }
820 }
821 };
822}
823pub(crate) use impl_convert;
824
825macro_rules! quire_add_sub_array {
826 ($posit:ty, $quire:ty, $($i:literal),*) => {$(
827 impl ops::AddAssign<($posit, [$posit; $i])> for $quire {
828 #[inline]
829 fn add_assign(&mut self, rhs: ($posit, [$posit; $i])) {
830 for p in &rhs.1 {
831 *self += (rhs.0, *p);
832 }
833 }
834 }
835
836 impl ops::SubAssign<($posit, [$posit; $i])> for $quire {
837 #[inline]
838 fn sub_assign(&mut self, rhs: ($posit, [$posit; $i])) {
839 for p in &rhs.1 {
840 *self -= (rhs.0, *p);
841 }
842 }
843 }
844 )*}
845}
846pub(crate) use quire_add_sub_array;
847
848macro_rules! quire_add_sub {
849 ($posit:ty, $quire:ty) => {
850 impl ops::AddAssign<($posit, $posit)> for $quire {
851 #[inline]
852 fn add_assign(&mut self, rhs: ($posit, $posit)) {
853 let ui_a = (rhs.0).to_bits();
854 let ui_b = (rhs.1).to_bits();
855 fdp(self, ui_a, ui_b, true);
856 }
857 }
858
859 impl ops::AddAssign<($posit, ($posit, $posit))> for $quire {
860 #[inline]
861 fn add_assign(&mut self, rhs: ($posit, ($posit, $posit))) {
862 *self += (rhs.0, (rhs.1).0);
863 *self += (rhs.0, (rhs.1).1);
864 }
865 }
866
867 impl ops::AddAssign<($posit, ($posit, $posit, $posit))> for $quire {
868 #[inline]
869 fn add_assign(&mut self, rhs: ($posit, ($posit, $posit, $posit))) {
870 *self += (rhs.0, (rhs.1).0);
871 *self += (rhs.0, (rhs.1).1);
872 *self += (rhs.0, (rhs.1).2);
873 }
874 }
875
876 impl ops::AddAssign<$posit> for $quire {
877 #[inline]
878 fn add_assign(&mut self, rhs: $posit) {
879 let ui = rhs.to_bits();
880 fdp_one(self, ui, true);
881 }
882 }
883
884 impl ops::AddAssign<(($posit, $posit), ($posit, $posit))> for $quire {
885 #[inline]
886 fn add_assign(&mut self, rhs: (($posit, $posit), ($posit, $posit))) {
887 *self += ((rhs.0).0, (rhs.1).0);
888 *self += ((rhs.0).0, (rhs.1).1);
889 *self += ((rhs.0).1, (rhs.1).0);
890 *self += ((rhs.0).1, (rhs.1).1);
891 }
892 }
893
894 impl ops::SubAssign<($posit, $posit)> for $quire {
895 #[inline]
896 fn sub_assign(&mut self, rhs: ($posit, $posit)) {
897 let ui_a = (rhs.0).to_bits();
898 let ui_b = (rhs.1).to_bits();
899 fdp(self, ui_a, ui_b, false);
900 }
901 }
902
903 impl ops::SubAssign<$posit> for $quire {
904 #[inline]
905 fn sub_assign(&mut self, rhs: $posit) {
906 let ui = rhs.to_bits();
907 fdp_one(self, ui, false);
908 }
909 }
910
911 impl ops::SubAssign<($posit, ($posit, $posit))> for $quire {
912 #[inline]
913 fn sub_assign(&mut self, rhs: ($posit, ($posit, $posit))) {
914 *self -= (rhs.0, (rhs.1).0);
915 *self -= (rhs.0, (rhs.1).1);
916 }
917 }
918
919 impl ops::SubAssign<(($posit, $posit), ($posit, $posit))> for $quire {
920 #[inline]
921 fn sub_assign(&mut self, rhs: (($posit, $posit), ($posit, $posit))) {
922 *self -= ((rhs.0).0, (rhs.1).0);
923 *self -= ((rhs.0).0, (rhs.1).1);
924 *self -= ((rhs.0).1, (rhs.1).0);
925 *self -= ((rhs.0).1, (rhs.1).1);
926 }
927 }
928 };
929}
930pub(crate) use quire_add_sub;
931
932macro_rules! quire_add_sub_array_x {
933 ($posit:ty, $quire:ty, $($i:literal),*) => {$(
934 impl<const N: u32> ops::AddAssign<($posit, [$posit; $i])> for $quire {
935 #[inline]
936 fn add_assign(&mut self, rhs: ($posit, [$posit; $i])) {
937 for p in &rhs.1 {
938 *self += (rhs.0, *p);
939 }
940 }
941 }
942
943 impl<const N: u32> ops::SubAssign<($posit, [$posit; $i])> for $quire {
944 #[inline]
945 fn sub_assign(&mut self, rhs: ($posit, [$posit; $i])) {
946 for p in &rhs.1 {
947 *self -= (rhs.0, *p);
948 }
949 }
950 }
951 )*}
952}
953pub(crate) use quire_add_sub_array_x;
954
955macro_rules! quire_add_sub_x {
956 ($posit:ty, $quire:ty) => {
957 impl<const N: u32> ops::AddAssign<($posit, $posit)> for $quire {
958 #[inline]
959 fn add_assign(&mut self, rhs: ($posit, $posit)) {
960 let ui_a = (rhs.0).to_bits();
961 let ui_b = (rhs.1).to_bits();
962 fdp(self, ui_a, ui_b, true);
963 }
964 }
965
966 impl<const N: u32> ops::AddAssign<($posit, ($posit, $posit))> for $quire {
967 #[inline]
968 fn add_assign(&mut self, rhs: ($posit, ($posit, $posit))) {
969 *self += (rhs.0, (rhs.1).0);
970 *self += (rhs.0, (rhs.1).1);
971 }
972 }
973
974 impl<const N: u32> ops::AddAssign<($posit, ($posit, $posit, $posit))> for $quire {
975 #[inline]
976 fn add_assign(&mut self, rhs: ($posit, ($posit, $posit, $posit))) {
977 *self += (rhs.0, (rhs.1).0);
978 *self += (rhs.0, (rhs.1).1);
979 *self += (rhs.0, (rhs.1).2);
980 }
981 }
982
983 impl<const N: u32> ops::AddAssign<$posit> for $quire {
984 #[inline]
985 fn add_assign(&mut self, rhs: $posit) {
986 let ui = rhs.to_bits();
987 fdp_one(self, ui, true);
988 }
989 }
990
991 impl<const N: u32> ops::AddAssign<(($posit, $posit), ($posit, $posit))> for $quire {
992 #[inline]
993 fn add_assign(&mut self, rhs: (($posit, $posit), ($posit, $posit))) {
994 *self += ((rhs.0).0, (rhs.1).0);
995 *self += ((rhs.0).0, (rhs.1).1);
996 *self += ((rhs.0).1, (rhs.1).0);
997 *self += ((rhs.0).1, (rhs.1).1);
998 }
999 }
1000
1001 impl<const N: u32> ops::SubAssign<($posit, $posit)> for $quire {
1002 #[inline]
1003 fn sub_assign(&mut self, rhs: ($posit, $posit)) {
1004 let ui_a = (rhs.0).to_bits();
1005 let ui_b = (rhs.1).to_bits();
1006 fdp(self, ui_a, ui_b, false);
1007 }
1008 }
1009
1010 impl<const N: u32> ops::SubAssign<$posit> for $quire {
1011 #[inline]
1012 fn sub_assign(&mut self, rhs: $posit) {
1013 let ui = rhs.to_bits();
1014 fdp_one(self, ui, false);
1015 }
1016 }
1017
1018 impl<const N: u32> ops::SubAssign<($posit, ($posit, $posit))> for $quire {
1019 #[inline]
1020 fn sub_assign(&mut self, rhs: ($posit, ($posit, $posit))) {
1021 *self -= (rhs.0, (rhs.1).0);
1022 *self -= (rhs.0, (rhs.1).1);
1023 }
1024 }
1025
1026 impl<const N: u32> ops::SubAssign<(($posit, $posit), ($posit, $posit))> for $quire {
1027 #[inline]
1028 fn sub_assign(&mut self, rhs: (($posit, $posit), ($posit, $posit))) {
1029 *self -= ((rhs.0).0, (rhs.1).0);
1030 *self -= ((rhs.0).0, (rhs.1).1);
1031 *self -= ((rhs.0).1, (rhs.1).0);
1032 *self -= ((rhs.0).1, (rhs.1).1);
1033 }
1034 }
1035 };
1036}
1037pub(crate) use quire_add_sub_x;
1038
1039#[cfg(feature = "simba")]
1040pub mod simba {
1041 macro_rules! impl_real {
1042 ($T:ty) => {
1043 impl simba::scalar::RealField for $T {
1044 #[inline]
1045 fn is_sign_positive(&self) -> bool {
1046 Self::is_sign_positive(*self)
1047 }
1048
1049 #[inline]
1050 fn is_sign_negative(&self) -> bool {
1051 Self::is_sign_negative(*self)
1052 }
1053
1054 #[inline]
1055 fn copysign(self, sign: Self) -> Self {
1056 Self::copysign(self, sign)
1057 }
1058
1059 #[inline]
1060 fn max(self, other: Self) -> Self {
1061 core::cmp::Ord::max(self, other)
1062 }
1063
1064 #[inline]
1065 fn min(self, other: Self) -> Self {
1066 core::cmp::Ord::min(self, other)
1067 }
1068
1069 #[inline]
1070 fn clamp(self, min: Self, max: Self) -> Self {
1071 Self::clamp(self, min, max)
1072 }
1073
1074 #[inline]
1075 fn atan2(self, other: Self) -> Self {
1076 Self::atan2(self, other)
1077 }
1078
1079 #[inline]
1080 fn min_value() -> Option<Self> {
1081 Some(Self::MIN)
1082 }
1083
1084 #[inline]
1085 fn max_value() -> Option<Self> {
1086 Some(Self::MAX)
1087 }
1088
1089 #[inline]
1091 fn pi() -> Self {
1092 MathConsts::PI
1093 }
1094
1095 #[inline]
1097 fn two_pi() -> Self {
1098 <Self as MathConsts>::PI + <Self as MathConsts>::PI
1099 }
1100
1101 #[inline]
1103 fn frac_pi_2() -> Self {
1104 MathConsts::FRAC_PI_2
1105 }
1106
1107 #[inline]
1109 fn frac_pi_3() -> Self {
1110 MathConsts::FRAC_PI_3
1111 }
1112
1113 #[inline]
1115 fn frac_pi_4() -> Self {
1116 MathConsts::FRAC_PI_4
1117 }
1118
1119 #[inline]
1121 fn frac_pi_6() -> Self {
1122 MathConsts::FRAC_PI_6
1123 }
1124
1125 #[inline]
1127 fn frac_pi_8() -> Self {
1128 MathConsts::FRAC_PI_8
1129 }
1130
1131 #[inline]
1133 fn frac_1_pi() -> Self {
1134 MathConsts::FRAC_1_PI
1135 }
1136
1137 #[inline]
1139 fn frac_2_pi() -> Self {
1140 MathConsts::FRAC_2_PI
1141 }
1142
1143 #[inline]
1145 fn frac_2_sqrt_pi() -> Self {
1146 MathConsts::FRAC_2_SQRT_PI
1147 }
1148
1149 #[inline]
1151 fn e() -> Self {
1152 MathConsts::E
1153 }
1154
1155 #[inline]
1157 fn log2_e() -> Self {
1158 MathConsts::LOG2_E
1159 }
1160
1161 #[inline]
1163 fn log10_e() -> Self {
1164 MathConsts::LOG10_E
1165 }
1166
1167 #[inline]
1169 fn ln_2() -> Self {
1170 MathConsts::LN_2
1171 }
1172
1173 #[inline]
1175 fn ln_10() -> Self {
1176 MathConsts::LN_10
1177 }
1178 }
1179 };
1180 }
1181 pub(crate) use impl_real;
1182
1183 macro_rules! impl_complex {
1184 ($T:ty) => {
1185 impl simba::scalar::ComplexField for $T {
1186 type RealField = $T;
1187
1188 #[inline]
1189 fn from_real(re: Self::RealField) -> Self {
1190 re
1191 }
1192
1193 #[inline]
1194 fn real(self) -> Self::RealField {
1195 self
1196 }
1197
1198 #[inline]
1199 fn imaginary(self) -> Self::RealField {
1200 Self::ZERO
1201 }
1202
1203 #[inline]
1204 fn norm1(self) -> Self::RealField {
1205 Self::abs(self)
1206 }
1207
1208 #[inline]
1209 fn modulus(self) -> Self::RealField {
1210 Self::abs(self)
1211 }
1212
1213 #[inline]
1214 fn modulus_squared(self) -> Self::RealField {
1215 self * self
1216 }
1217
1218 #[inline]
1219 fn argument(self) -> Self::RealField {
1220 if self >= Self::ZERO {
1221 Self::ZERO
1222 } else {
1223 MathConsts::PI
1224 }
1225 }
1226
1227 #[inline]
1228 fn to_exp(self) -> (Self, Self) {
1229 if self >= Self::ZERO {
1230 (self, Self::ONE)
1231 } else {
1232 (-self, -Self::ONE)
1233 }
1234 }
1235
1236 #[inline]
1237 fn recip(self) -> Self {
1238 Self::recip(self)
1239 }
1240
1241 #[inline]
1242 fn conjugate(self) -> Self {
1243 self
1244 }
1245
1246 #[inline]
1247 fn scale(self, factor: Self::RealField) -> Self {
1248 self * factor
1249 }
1250
1251 #[inline]
1252 fn unscale(self, factor: Self::RealField) -> Self {
1253 self / factor
1254 }
1255
1256 #[inline]
1257 fn floor(self) -> Self {
1258 Self::floor(self)
1259 }
1260
1261 #[inline]
1262 fn ceil(self) -> Self {
1263 Self::ceil(self)
1264 }
1265
1266 #[inline]
1267 fn round(self) -> Self {
1268 Self::round(self)
1269 }
1270
1271 #[inline]
1272 fn trunc(self) -> Self {
1273 Self::trunc(self)
1274 }
1275
1276 #[inline]
1277 fn fract(self) -> Self {
1278 Self::fract(self)
1279 }
1280
1281 #[inline]
1282 fn abs(self) -> Self {
1283 Self::abs(self)
1284 }
1285
1286 #[inline]
1287 fn signum(self) -> Self {
1288 Self::signum(self)
1289 }
1290
1291 #[inline]
1292 fn mul_add(self, a: Self, b: Self) -> Self {
1293 Self::mul_add(self, a, b)
1294 }
1295
1296 #[inline]
1297 fn powi(self, n: i32) -> Self {
1298 Self::powi(self, n)
1299 }
1300
1301 #[inline]
1302 fn powf(self, n: Self) -> Self {
1303 Self::powf(self, n)
1304 }
1305
1306 #[inline]
1307 fn powc(self, n: Self) -> Self {
1308 Self::powf(self, n)
1310 }
1311
1312 #[inline]
1313 fn sqrt(self) -> Self {
1314 Self::sqrt(self)
1315 }
1316
1317 #[inline]
1318 fn try_sqrt(self) -> Option<Self> {
1319 if self >= Self::ZERO {
1320 Some(Self::sqrt(self))
1321 } else {
1322 None
1323 }
1324 }
1325
1326 #[inline]
1327 fn exp(self) -> Self {
1328 Self::exp(self)
1329 }
1330
1331 #[inline]
1332 fn exp2(self) -> Self {
1333 Self::exp2(self)
1334 }
1335
1336 #[inline]
1337 fn exp_m1(self) -> Self {
1338 Self::exp_m1(self)
1339 }
1340
1341 #[inline]
1342 fn ln_1p(self) -> Self {
1343 Self::ln_1p(self)
1344 }
1345
1346 #[inline]
1347 fn ln(self) -> Self {
1348 Self::ln(self)
1349 }
1350
1351 #[inline]
1352 fn log(self, base: Self) -> Self {
1353 Self::log(self, base)
1354 }
1355
1356 #[inline]
1357 fn log2(self) -> Self {
1358 Self::log2(self)
1359 }
1360
1361 #[inline]
1362 fn log10(self) -> Self {
1363 Self::log10(self)
1364 }
1365
1366 #[inline]
1367 fn cbrt(self) -> Self {
1368 Self::cbrt(self)
1369 }
1370
1371 #[inline]
1372 fn hypot(self, other: Self) -> Self::RealField {
1373 Self::hypot(self, other)
1374 }
1375
1376 #[inline]
1377 fn sin(self) -> Self {
1378 Self::sin(self)
1379 }
1380
1381 #[inline]
1382 fn cos(self) -> Self {
1383 Self::cos(self)
1384 }
1385
1386 #[inline]
1387 fn tan(self) -> Self {
1388 Self::tan(self)
1389 }
1390
1391 #[inline]
1392 fn asin(self) -> Self {
1393 Self::asin(self)
1394 }
1395
1396 #[inline]
1397 fn acos(self) -> Self {
1398 Self::acos(self)
1399 }
1400
1401 #[inline]
1402 fn atan(self) -> Self {
1403 Self::atan(self)
1404 }
1405
1406 #[inline]
1407 fn sin_cos(self) -> (Self, Self) {
1408 Self::sin_cos(self)
1409 }
1410
1411 #[inline]
1412 fn sinh(self) -> Self {
1413 Self::sinh(self)
1414 }
1415
1416 #[inline]
1417 fn cosh(self) -> Self {
1418 Self::cosh(self)
1419 }
1420
1421 #[inline]
1422 fn tanh(self) -> Self {
1423 Self::tanh(self)
1424 }
1425
1426 #[inline]
1427 fn asinh(self) -> Self {
1428 Self::asinh(self)
1429 }
1430
1431 #[inline]
1432 fn acosh(self) -> Self {
1433 Self::acosh(self)
1434 }
1435
1436 #[inline]
1437 fn atanh(self) -> Self {
1438 Self::atanh(self)
1439 }
1440
1441 #[inline]
1442 fn is_finite(&self) -> bool {
1443 Self::is_finite(*self)
1444 }
1445 }
1446 };
1447 }
1448 pub(crate) use impl_complex;
1449
1450 macro_rules! impl_primitive_simd_value_for_scalar(
1451 ($($t: ty),*) => {$(
1452 impl simba::simd::PrimitiveSimdValue for $t {}
1453 impl simba::simd::SimdValue for $t {
1454 type Element = $t;
1455 type SimdBool = bool;
1456
1457 #[inline(always)]
1458 fn lanes() -> usize {
1459 1
1460 }
1461
1462 #[inline(always)]
1463 fn splat(val: Self::Element) -> Self {
1464 val
1465 }
1466
1467 #[inline(always)]
1468 fn extract(&self, _: usize) -> Self::Element {
1469 *self
1470 }
1471
1472 #[inline(always)]
1473 unsafe fn extract_unchecked(&self, _: usize) -> Self::Element {
1474 *self
1475 }
1476
1477 #[inline(always)]
1478 fn replace(&mut self, _: usize, val: Self::Element) {
1479 *self = val
1480 }
1481
1482 #[inline(always)]
1483 unsafe fn replace_unchecked(&mut self, _: usize, val: Self::Element) {
1484 *self = val
1485 }
1486
1487 #[inline(always)]
1488 fn select(self, cond: Self::SimdBool, other: Self) -> Self {
1489 if cond {
1490 self
1491 } else {
1492 other
1493 }
1494 }
1495 }
1496 )*}
1497 );
1498 pub(crate) use impl_primitive_simd_value_for_scalar;
1499
1500 macro_rules! impl_subset_into(
1501 ($($subset: ty as $( $superset: ty),+ );* $(;)*) => {
1502 $($(
1503 impl simba::scalar::SubsetOf<$superset> for $subset {
1504 #[inline]
1505 fn to_superset(&self) -> $superset {
1506 (*self).into()
1507 }
1508
1509 #[inline]
1510 fn from_superset_unchecked(element: &$superset) -> $subset {
1511 (*element).into()
1512 }
1513
1514 #[inline]
1515 fn is_in_subset(_: &$superset) -> bool {
1516 true
1517 }
1518 }
1519 )+)*
1520 });
1521 pub(crate) use impl_subset_into;
1522}
1523
1524#[cfg(feature = "approx")]
1525pub mod approx {
1526 macro_rules! impl_ulps_eq {
1527 ($T:ident, $U:ident) => {
1528 impl approx::UlpsEq for $T {
1529 #[inline]
1530 fn default_max_ulps() -> u32 {
1531 4
1532 }
1533
1534 #[inline]
1535 fn ulps_eq(&self, other: &$T, epsilon: $T, max_ulps: u32) -> bool {
1536 if $T::abs_diff_eq(self, other, epsilon) {
1538 return true;
1539 }
1540
1541 if self.signum() != other.signum() {
1543 return false;
1544 }
1545
1546 let int_self: $U = unsafe { core::mem::transmute(*self) };
1548 let int_other: $U = unsafe { core::mem::transmute(*other) };
1549
1550 $U::abs(int_self - int_other) <= max_ulps as $U
1551 }
1552 }
1553 };
1554 }
1555 pub(crate) use impl_ulps_eq;
1556
1557 macro_rules! impl_signed_abs_diff_eq {
1558 ($T:ident, $default_epsilon:expr) => {
1559 impl approx::AbsDiffEq for $T {
1560 type Epsilon = $T;
1561
1562 #[inline]
1563 fn default_epsilon() -> $T {
1564 $default_epsilon
1565 }
1566
1567 #[inline]
1568 fn abs_diff_eq(&self, other: &$T, epsilon: $T) -> bool {
1569 $T::abs(*self - *other) <= epsilon
1570 }
1571 }
1572 };
1573 }
1574 pub(crate) use impl_signed_abs_diff_eq;
1575
1576 macro_rules! impl_relative_eq {
1577 ($T:ident, $U:ident) => {
1578 impl approx::RelativeEq for $T {
1579 #[inline]
1580 fn default_max_relative() -> $T {
1581 $T::EPSILON
1582 }
1583
1584 #[inline]
1585 fn relative_eq(&self, other: &$T, epsilon: $T, max_relative: $T) -> bool {
1586 if self == other {
1588 return true;
1589 }
1590
1591 if $T::is_infinite(*self) || $T::is_infinite(*other) {
1593 return false;
1594 }
1595
1596 let abs_diff = $T::abs(*self - *other);
1597
1598 if abs_diff <= epsilon {
1600 return true;
1601 }
1602
1603 let abs_self = $T::abs(*self);
1604 let abs_other = $T::abs(*other);
1605
1606 let largest = if abs_other > abs_self {
1607 abs_other
1608 } else {
1609 abs_self
1610 };
1611
1612 abs_diff <= largest * max_relative
1614 }
1615 }
1616 };
1617 }
1618 pub(crate) use impl_relative_eq;
1619}