1use crate::{FloatChecker, NoisyFloat};
16use core::{
17 cmp::Ordering,
18 convert::{From, TryFrom},
19 hash::{Hash, Hasher},
20 iter,
21 mem::transmute,
22 num::FpCategory,
23 ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign},
24};
25use num_traits::{
26 cast::{FromPrimitive, NumCast, ToPrimitive},
27 identities::{One, Zero},
28 Bounded, Float, FloatConst, Num, Signed,
29};
30
31impl<F: Float, C: FloatChecker<F>> Clone for NoisyFloat<F, C> {
32 #[inline]
33 fn clone(&self) -> Self {
34 Self::unchecked_new_generic(self.value)
35 }
36}
37
38impl<F: Float, C: FloatChecker<F>> Copy for NoisyFloat<F, C> {}
39
40impl<F: Float, C: FloatChecker<F>> AsRef<F> for NoisyFloat<F, C> {
41 fn as_ref(&self) -> &F {
42 &self.value
43 }
44}
45
46impl<F: Float, C: FloatChecker<F>> PartialEq<F> for NoisyFloat<F, C> {
47 #[inline]
48 fn eq(&self, other: &F) -> bool {
49 self.value.eq(&other)
50 }
51}
52
53impl<F: Float, C: FloatChecker<F>> PartialEq for NoisyFloat<F, C> {
54 #[inline]
55 fn eq(&self, other: &Self) -> bool {
56 self.eq(&other.value)
57 }
58}
59
60impl<F: Float, C: FloatChecker<F>> Eq for NoisyFloat<F, C> {}
61
62impl<F: Float, C: FloatChecker<F>> PartialOrd<F> for NoisyFloat<F, C> {
63 #[inline]
64 fn partial_cmp(&self, other: &F) -> Option<Ordering> {
65 self.value.partial_cmp(&other)
66 }
67 #[inline]
68 fn lt(&self, other: &F) -> bool {
69 self.value.lt(&other)
70 }
71 #[inline]
72 fn le(&self, other: &F) -> bool {
73 self.value.le(&other)
74 }
75 #[inline]
76 fn gt(&self, other: &F) -> bool {
77 self.value.gt(&other)
78 }
79 #[inline]
80 fn ge(&self, other: &F) -> bool {
81 self.value.ge(&other)
82 }
83}
84
85impl<F: Float, C: FloatChecker<F>> PartialOrd for NoisyFloat<F, C> {
86 #[inline]
87 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
88 self.value.partial_cmp(&other.value)
89 }
90 #[inline]
91 fn lt(&self, other: &Self) -> bool {
92 self.lt(&other.value)
93 }
94 #[inline]
95 fn le(&self, other: &Self) -> bool {
96 self.le(&other.value)
97 }
98 #[inline]
99 fn gt(&self, other: &Self) -> bool {
100 self.gt(&other.value)
101 }
102 #[inline]
103 fn ge(&self, other: &Self) -> bool {
104 self.ge(&other.value)
105 }
106}
107
108impl<F: Float, C: FloatChecker<F>> Ord for NoisyFloat<F, C> {
109 #[inline]
110 fn cmp(&self, other: &Self) -> Ordering {
111 if self.value < other.value {
112 Ordering::Less
113 } else if self.value == other.value {
114 Ordering::Equal
115 } else {
116 Ordering::Greater
117 }
118 }
119}
120
121impl<C: FloatChecker<f32>> Hash for NoisyFloat<f32, C> {
122 #[inline]
123 fn hash<H: Hasher>(&self, state: &mut H) {
124 let bits = if self.value == 0.0 {
125 0 } else {
127 unsafe { transmute::<f32, u32>(self.value) }
128 };
129 bits.hash(state);
130 }
131}
132
133impl<C: FloatChecker<f64>> Hash for NoisyFloat<f64, C> {
134 #[inline]
135 fn hash<H: Hasher>(&self, state: &mut H) {
136 let bits = if self.value == 0.0 {
137 0 } else {
139 unsafe { transmute::<f64, u64>(self.value) }
140 };
141 bits.hash(state);
142 }
143}
144
145impl<F: Float, C: FloatChecker<F>> Add<F> for NoisyFloat<F, C> {
148 type Output = Self;
149 #[inline]
150 fn add(self, rhs: F) -> Self {
151 Self::new(self.value.add(rhs))
152 }
153}
154
155impl<'a, F: Float, C: FloatChecker<F>> Add<&'a F> for NoisyFloat<F, C> {
156 type Output = Self;
157 #[inline]
158 fn add(self, rhs: &'a F) -> Self {
159 Self::new(self.value.add(*rhs))
160 }
161}
162
163impl<F: Float, C: FloatChecker<F>> Add for NoisyFloat<F, C> {
164 type Output = Self;
165 #[inline]
166 fn add(self, rhs: Self) -> Self {
167 self.add(rhs.value)
168 }
169}
170
171impl<'a, F: Float, C: FloatChecker<F>> Add<&'a Self> for NoisyFloat<F, C> {
172 type Output = Self;
173 #[inline]
174 fn add(self, rhs: &'a Self) -> Self {
175 self.add(rhs.value)
176 }
177}
178
179impl<F: Float, C: FloatChecker<F>> Sub<F> for NoisyFloat<F, C> {
180 type Output = Self;
181 #[inline]
182 fn sub(self, rhs: F) -> Self {
183 Self::new(self.value.sub(rhs))
184 }
185}
186
187impl<'a, F: Float, C: FloatChecker<F>> Sub<&'a F> for NoisyFloat<F, C> {
188 type Output = Self;
189 #[inline]
190 fn sub(self, rhs: &'a F) -> Self {
191 Self::new(self.value.sub(*rhs))
192 }
193}
194
195impl<F: Float, C: FloatChecker<F>> Sub for NoisyFloat<F, C> {
196 type Output = Self;
197 #[inline]
198 fn sub(self, rhs: Self) -> Self {
199 self.sub(rhs.value)
200 }
201}
202
203impl<'a, F: Float, C: FloatChecker<F>> Sub<&'a Self> for NoisyFloat<F, C> {
204 type Output = Self;
205 #[inline]
206 fn sub(self, rhs: &'a Self) -> Self {
207 self.sub(rhs.value)
208 }
209}
210
211impl<F: Float, C: FloatChecker<F>> Mul<F> for NoisyFloat<F, C> {
212 type Output = Self;
213 #[inline]
214 fn mul(self, rhs: F) -> Self {
215 Self::new(self.value.mul(rhs))
216 }
217}
218
219impl<'a, F: Float, C: FloatChecker<F>> Mul<&'a F> for NoisyFloat<F, C> {
220 type Output = Self;
221 #[inline]
222 fn mul(self, rhs: &'a F) -> Self {
223 Self::new(self.value.mul(*rhs))
224 }
225}
226
227impl<F: Float, C: FloatChecker<F>> Mul for NoisyFloat<F, C> {
228 type Output = Self;
229 #[inline]
230 fn mul(self, rhs: Self) -> Self {
231 self.mul(rhs.value)
232 }
233}
234
235impl<'a, F: Float, C: FloatChecker<F>> Mul<&'a Self> for NoisyFloat<F, C> {
236 type Output = Self;
237 #[inline]
238 fn mul(self, rhs: &'a Self) -> Self {
239 self.mul(rhs.value)
240 }
241}
242
243impl<F: Float, C: FloatChecker<F>> Div<F> for NoisyFloat<F, C> {
244 type Output = Self;
245 #[inline]
246 fn div(self, rhs: F) -> Self {
247 Self::new(self.value.div(rhs))
248 }
249}
250
251impl<'a, F: Float, C: FloatChecker<F>> Div<&'a F> for NoisyFloat<F, C> {
252 type Output = Self;
253 #[inline]
254 fn div(self, rhs: &'a F) -> Self {
255 Self::new(self.value.div(*rhs))
256 }
257}
258
259impl<F: Float, C: FloatChecker<F>> Div for NoisyFloat<F, C> {
260 type Output = Self;
261 #[inline]
262 fn div(self, rhs: Self) -> Self {
263 self.div(rhs.value)
264 }
265}
266
267impl<'a, F: Float, C: FloatChecker<F>> Div<&'a Self> for NoisyFloat<F, C> {
268 type Output = Self;
269 #[inline]
270 fn div(self, rhs: &'a Self) -> Self {
271 self.div(rhs.value)
272 }
273}
274
275impl<F: Float, C: FloatChecker<F>> Rem<F> for NoisyFloat<F, C> {
276 type Output = Self;
277 #[inline]
278 fn rem(self, rhs: F) -> Self {
279 Self::new(self.value.rem(rhs))
280 }
281}
282
283impl<'a, F: Float, C: FloatChecker<F>> Rem<&'a F> for NoisyFloat<F, C> {
284 type Output = Self;
285 #[inline]
286 fn rem(self, rhs: &'a F) -> Self {
287 Self::new(self.value.rem(*rhs))
288 }
289}
290
291impl<F: Float, C: FloatChecker<F>> Rem for NoisyFloat<F, C> {
292 type Output = Self;
293 #[inline]
294 fn rem(self, rhs: Self) -> Self {
295 self.rem(rhs.value)
296 }
297}
298
299impl<'a, F: Float, C: FloatChecker<F>> Rem<&'a Self> for NoisyFloat<F, C> {
300 type Output = Self;
301 #[inline]
302 fn rem(self, rhs: &'a Self) -> Self {
303 self.rem(rhs.value)
304 }
305}
306
307impl<F: Float + AddAssign, C: FloatChecker<F>> AddAssign<F> for NoisyFloat<F, C> {
308 #[inline]
309 fn add_assign(&mut self, rhs: F) {
310 self.value.add_assign(rhs);
311 C::assert(self.value);
312 }
313}
314
315impl<'a, F: Float + AddAssign, C: FloatChecker<F>> AddAssign<&'a F> for NoisyFloat<F, C> {
316 #[inline]
317 fn add_assign(&mut self, rhs: &'a F) {
318 self.value.add_assign(*rhs);
319 C::assert(self.value);
320 }
321}
322
323impl<F: Float + AddAssign, C: FloatChecker<F>> AddAssign for NoisyFloat<F, C> {
324 #[inline]
325 fn add_assign(&mut self, rhs: Self) {
326 self.add_assign(rhs.value);
327 }
328}
329
330impl<'a, F: Float + AddAssign, C: FloatChecker<F>> AddAssign<&'a Self> for NoisyFloat<F, C> {
331 #[inline]
332 fn add_assign(&mut self, rhs: &'a Self) {
333 self.add_assign(rhs.value);
334 }
335}
336
337impl<F: Float + SubAssign, C: FloatChecker<F>> SubAssign<F> for NoisyFloat<F, C> {
338 #[inline]
339 fn sub_assign(&mut self, rhs: F) {
340 self.value.sub_assign(rhs);
341 C::assert(self.value);
342 }
343}
344
345impl<'a, F: Float + SubAssign, C: FloatChecker<F>> SubAssign<&'a F> for NoisyFloat<F, C> {
346 #[inline]
347 fn sub_assign(&mut self, rhs: &'a F) {
348 self.value.sub_assign(*rhs);
349 C::assert(self.value);
350 }
351}
352
353impl<F: Float + SubAssign, C: FloatChecker<F>> SubAssign for NoisyFloat<F, C> {
354 #[inline]
355 fn sub_assign(&mut self, rhs: Self) {
356 self.sub_assign(rhs.value);
357 }
358}
359
360impl<'a, F: Float + SubAssign, C: FloatChecker<F>> SubAssign<&'a Self> for NoisyFloat<F, C> {
361 #[inline]
362 fn sub_assign(&mut self, rhs: &'a Self) {
363 self.sub_assign(rhs.value);
364 }
365}
366
367impl<F: Float + MulAssign, C: FloatChecker<F>> MulAssign<F> for NoisyFloat<F, C> {
368 #[inline]
369 fn mul_assign(&mut self, rhs: F) {
370 self.value.mul_assign(rhs);
371 C::assert(self.value);
372 }
373}
374
375impl<'a, F: Float + MulAssign, C: FloatChecker<F>> MulAssign<&'a F> for NoisyFloat<F, C> {
376 #[inline]
377 fn mul_assign(&mut self, rhs: &'a F) {
378 self.value.mul_assign(*rhs);
379 C::assert(self.value);
380 }
381}
382
383impl<F: Float + MulAssign, C: FloatChecker<F>> MulAssign for NoisyFloat<F, C> {
384 #[inline]
385 fn mul_assign(&mut self, rhs: Self) {
386 self.mul_assign(rhs.value);
387 }
388}
389
390impl<'a, F: Float + MulAssign, C: FloatChecker<F>> MulAssign<&'a Self> for NoisyFloat<F, C> {
391 #[inline]
392 fn mul_assign(&mut self, rhs: &'a Self) {
393 self.mul_assign(rhs.value);
394 }
395}
396
397impl<F: Float + DivAssign, C: FloatChecker<F>> DivAssign<F> for NoisyFloat<F, C> {
398 #[inline]
399 fn div_assign(&mut self, rhs: F) {
400 self.value.div_assign(rhs);
401 C::assert(self.value);
402 }
403}
404
405impl<'a, F: Float + DivAssign, C: FloatChecker<F>> DivAssign<&'a F> for NoisyFloat<F, C> {
406 #[inline]
407 fn div_assign(&mut self, rhs: &'a F) {
408 self.value.div_assign(*rhs);
409 C::assert(self.value);
410 }
411}
412
413impl<F: Float + DivAssign, C: FloatChecker<F>> DivAssign for NoisyFloat<F, C> {
414 #[inline]
415 fn div_assign(&mut self, rhs: Self) {
416 self.div_assign(rhs.value);
417 }
418}
419
420impl<'a, F: Float + DivAssign, C: FloatChecker<F>> DivAssign<&'a Self> for NoisyFloat<F, C> {
421 #[inline]
422 fn div_assign(&mut self, rhs: &'a Self) {
423 self.div_assign(rhs.value);
424 }
425}
426
427impl<F: Float + RemAssign, C: FloatChecker<F>> RemAssign<F> for NoisyFloat<F, C> {
428 #[inline]
429 fn rem_assign(&mut self, rhs: F) {
430 self.value.rem_assign(rhs);
431 C::assert(self.value);
432 }
433}
434
435impl<'a, F: Float + RemAssign, C: FloatChecker<F>> RemAssign<&'a F> for NoisyFloat<F, C> {
436 #[inline]
437 fn rem_assign(&mut self, rhs: &'a F) {
438 self.value.rem_assign(*rhs);
439 C::assert(self.value);
440 }
441}
442
443impl<F: Float + RemAssign, C: FloatChecker<F>> RemAssign for NoisyFloat<F, C> {
444 #[inline]
445 fn rem_assign(&mut self, rhs: Self) {
446 self.rem_assign(rhs.value);
447 }
448}
449
450impl<'a, F: Float + RemAssign, C: FloatChecker<F>> RemAssign<&'a Self> for NoisyFloat<F, C> {
451 #[inline]
452 fn rem_assign(&mut self, rhs: &'a Self) {
453 self.rem_assign(rhs.value);
454 }
455}
456
457impl<F: Float, C: FloatChecker<F>> Neg for NoisyFloat<F, C> {
458 type Output = Self;
459 #[inline]
460 fn neg(self) -> Self {
461 Self::new(self.value.neg())
462 }
463}
464
465impl<'a, F: Float, C: FloatChecker<F>> Neg for &'a NoisyFloat<F, C> {
466 type Output = NoisyFloat<F, C>;
467 #[inline]
468 fn neg(self) -> Self::Output {
469 Self::Output::neg(*self)
470 }
471}
472
473impl<F: Float, C: FloatChecker<F>> Zero for NoisyFloat<F, C> {
474 #[inline]
475 fn zero() -> Self {
476 Self::new(F::zero())
477 }
478 #[inline]
479 fn is_zero(&self) -> bool {
480 self.value.is_zero()
481 }
482}
483
484impl<F: Float, C: FloatChecker<F>> One for NoisyFloat<F, C> {
485 #[inline]
486 fn one() -> Self {
487 Self::new(F::one())
488 }
489}
490
491impl<F: Float, C: FloatChecker<F>> Num for NoisyFloat<F, C> {
492 type FromStrRadixErr = F::FromStrRadixErr;
493 #[inline]
494 fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
495 F::from_str_radix(str, radix).map(|v| Self::new(v))
496 }
497}
498
499impl<F: Float, C: FloatChecker<F>> ToPrimitive for NoisyFloat<F, C> {
500 #[inline]
501 fn to_i64(&self) -> Option<i64> {
502 self.value.to_i64()
503 }
504 #[inline]
505 fn to_u64(&self) -> Option<u64> {
506 self.value.to_u64()
507 }
508 #[inline]
509 fn to_isize(&self) -> Option<isize> {
510 self.value.to_isize()
511 }
512 #[inline]
513 fn to_i8(&self) -> Option<i8> {
514 self.value.to_i8()
515 }
516 #[inline]
517 fn to_i16(&self) -> Option<i16> {
518 self.value.to_i16()
519 }
520 #[inline]
521 fn to_i32(&self) -> Option<i32> {
522 self.value.to_i32()
523 }
524 #[inline]
525 fn to_usize(&self) -> Option<usize> {
526 self.value.to_usize()
527 }
528 #[inline]
529 fn to_u8(&self) -> Option<u8> {
530 self.value.to_u8()
531 }
532 #[inline]
533 fn to_u16(&self) -> Option<u16> {
534 self.value.to_u16()
535 }
536 #[inline]
537 fn to_u32(&self) -> Option<u32> {
538 self.value.to_u32()
539 }
540 #[inline]
541 fn to_f32(&self) -> Option<f32> {
542 self.value.to_f32()
543 }
544 #[inline]
545 fn to_f64(&self) -> Option<f64> {
546 self.value.to_f64()
547 }
548}
549
550impl<F: Float + FromPrimitive, C: FloatChecker<F>> FromPrimitive for NoisyFloat<F, C> {
551 #[inline]
552 fn from_isize(n: isize) -> Option<Self> {
553 Self::try_new(F::from_isize(n)?)
554 }
555 #[inline]
556 fn from_i8(n: i8) -> Option<Self> {
557 Self::try_new(F::from_i8(n)?)
558 }
559 #[inline]
560 fn from_i16(n: i16) -> Option<Self> {
561 Self::try_new(F::from_i16(n)?)
562 }
563 #[inline]
564 fn from_i32(n: i32) -> Option<Self> {
565 Self::try_new(F::from_i32(n)?)
566 }
567 #[inline]
568 fn from_i64(n: i64) -> Option<Self> {
569 Self::try_new(F::from_i64(n)?)
570 }
571 #[inline]
572 fn from_i128(n: i128) -> Option<Self> {
573 Self::try_new(F::from_i128(n)?)
574 }
575 #[inline]
576 fn from_usize(n: usize) -> Option<Self> {
577 Self::try_new(F::from_usize(n)?)
578 }
579 #[inline]
580 fn from_u8(n: u8) -> Option<Self> {
581 Self::try_new(F::from_u8(n)?)
582 }
583 #[inline]
584 fn from_u16(n: u16) -> Option<Self> {
585 Self::try_new(F::from_u16(n)?)
586 }
587 #[inline]
588 fn from_u32(n: u32) -> Option<Self> {
589 Self::try_new(F::from_u32(n)?)
590 }
591 #[inline]
592 fn from_u64(n: u64) -> Option<Self> {
593 Self::try_new(F::from_u64(n)?)
594 }
595 #[inline]
596 fn from_u128(n: u128) -> Option<Self> {
597 Self::try_new(F::from_u128(n)?)
598 }
599 #[inline]
600 fn from_f32(n: f32) -> Option<Self> {
601 Self::try_new(F::from_f32(n)?)
602 }
603 #[inline]
604 fn from_f64(n: f64) -> Option<Self> {
605 Self::try_new(F::from_f64(n)?)
606 }
607}
608
609impl<F: Float, C: FloatChecker<F>> NumCast for NoisyFloat<F, C> {
610 #[inline]
611 fn from<T: ToPrimitive>(n: T) -> Option<Self> {
612 F::from(n).and_then(|v| Self::try_new(v))
613 }
614}
615
616impl<C: FloatChecker<f32>> From<NoisyFloat<f32, C>> for f32 {
617 #[inline]
618 fn from(n: NoisyFloat<f32, C>) -> Self {
619 n.value
620 }
621}
622
623impl<C: FloatChecker<f64>> From<NoisyFloat<f64, C>> for f64 {
624 #[inline]
625 fn from(n: NoisyFloat<f64, C>) -> Self {
626 n.value
627 }
628}
629
630impl<C: FloatChecker<f32>> From<NoisyFloat<f32, C>> for f64 {
631 #[inline]
632 fn from(n: NoisyFloat<f32, C>) -> Self {
633 n.value as f64
634 }
635}
636
637impl<C: FloatChecker<f64>> TryFrom<f64> for NoisyFloat<f64, C> {
638 type Error = &'static str;
639 #[inline]
640 fn try_from(f: f64) -> Result<Self, Self::Error> {
641 Self::try_new(f).ok_or("illegal value")
642 }
643}
644
645impl<C: FloatChecker<f32>> TryFrom<f32> for NoisyFloat<f32, C> {
646 type Error = &'static str;
647 #[inline]
648 fn try_from(f: f32) -> Result<Self, Self::Error> {
649 Self::try_new(f).ok_or("illegal value")
650 }
651}
652
653impl<F: Float, C: FloatChecker<F>> Float for NoisyFloat<F, C> {
654 #[inline]
655 fn nan() -> Self {
656 panic!("unexpected NaN")
657 }
658 #[inline]
659 fn infinity() -> Self {
660 Self::new(F::infinity())
661 }
662 #[inline]
663 fn neg_infinity() -> Self {
664 Self::new(F::neg_infinity())
665 }
666 #[inline]
667 fn neg_zero() -> Self {
668 Self::new(F::neg_zero())
669 }
670 #[inline]
671 fn min_value() -> Self {
672 Self::new(F::min_value())
673 }
674 #[inline]
675 fn min_positive_value() -> Self {
676 Self::new(F::min_positive_value())
677 }
678 #[inline]
679 fn max_value() -> Self {
680 Self::new(F::max_value())
681 }
682 #[inline]
683 fn is_nan(self) -> bool {
684 self.value.is_nan()
685 }
686 #[inline]
687 fn is_infinite(self) -> bool {
688 self.value.is_infinite()
689 }
690 #[inline]
691 fn is_finite(self) -> bool {
692 self.value.is_finite()
693 }
694 #[inline]
695 fn is_normal(self) -> bool {
696 self.value.is_normal()
697 }
698 #[inline]
699 fn classify(self) -> FpCategory {
700 self.value.classify()
701 }
702 #[inline]
703 fn floor(self) -> Self {
704 Self::new(self.value.floor())
705 }
706 #[inline]
707 fn ceil(self) -> Self {
708 Self::new(self.value.ceil())
709 }
710 #[inline]
711 fn round(self) -> Self {
712 Self::new(self.value.round())
713 }
714 #[inline]
715 fn trunc(self) -> Self {
716 Self::new(self.value.trunc())
717 }
718 #[inline]
719 fn fract(self) -> Self {
720 Self::new(self.value.fract())
721 }
722 #[inline]
723 fn abs(self) -> Self {
724 Self::new(self.value.abs())
725 }
726 #[inline]
727 fn signum(self) -> Self {
728 Self::new(self.value.signum())
729 }
730 #[inline]
731 fn is_sign_positive(self) -> bool {
732 self.value.is_sign_positive()
733 }
734 #[inline]
735 fn is_sign_negative(self) -> bool {
736 self.value.is_sign_negative()
737 }
738 #[inline]
739 fn mul_add(self, a: Self, b: Self) -> Self {
740 Self::new(self.value.mul_add(a.value, b.value))
741 }
742 #[inline]
743 fn recip(self) -> Self {
744 Self::new(self.value.recip())
745 }
746 #[inline]
747 fn powi(self, n: i32) -> Self {
748 Self::new(self.value.powi(n))
749 }
750 #[inline]
751 fn powf(self, n: Self) -> Self {
752 Self::new(self.value.powf(n.value))
753 }
754 #[inline]
755 fn sqrt(self) -> Self {
756 Self::new(self.value.sqrt())
757 }
758 #[inline]
759 fn exp(self) -> Self {
760 Self::new(self.value.exp())
761 }
762 #[inline]
763 fn exp2(self) -> Self {
764 Self::new(self.value.exp2())
765 }
766 #[inline]
767 fn ln(self) -> Self {
768 Self::new(self.value.ln())
769 }
770 #[inline]
771 fn log(self, base: Self) -> Self {
772 Self::new(self.value.log(base.value))
773 }
774 #[inline]
775 fn log2(self) -> Self {
776 Self::new(self.value.log2())
777 }
778 #[inline]
779 fn log10(self) -> Self {
780 Self::new(self.value.log10())
781 }
782 #[inline]
783 fn max(self, other: Self) -> Self {
784 Self::new(self.value.max(other.value))
785 }
786 #[inline]
787 fn min(self, other: Self) -> Self {
788 Self::new(self.value.min(other.value))
789 }
790 #[inline]
791 fn abs_sub(self, other: Self) -> Self {
792 Self::new(self.value.abs_sub(other.value))
793 }
794 #[inline]
795 fn cbrt(self) -> Self {
796 Self::new(self.value.cbrt())
797 }
798 #[inline]
799 fn hypot(self, other: Self) -> Self {
800 Self::new(self.value.hypot(other.value))
801 }
802 #[inline]
803 fn sin(self) -> Self {
804 Self::new(self.value.sin())
805 }
806 #[inline]
807 fn cos(self) -> Self {
808 Self::new(self.value.cos())
809 }
810 #[inline]
811 fn tan(self) -> Self {
812 Self::new(self.value.tan())
813 }
814 #[inline]
815 fn asin(self) -> Self {
816 Self::new(self.value.asin())
817 }
818 #[inline]
819 fn acos(self) -> Self {
820 Self::new(self.value.acos())
821 }
822 #[inline]
823 fn atan(self) -> Self {
824 Self::new(self.value.atan())
825 }
826 #[inline]
827 fn atan2(self, other: Self) -> Self {
828 Self::new(self.value.atan2(other.value))
829 }
830 #[inline]
831 fn sin_cos(self) -> (Self, Self) {
832 let (a, b) = self.value.sin_cos();
833 (Self::new(a), Self::new(b))
834 }
835 #[inline]
836 fn exp_m1(self) -> Self {
837 Self::new(self.value.exp_m1())
838 }
839 #[inline]
840 fn ln_1p(self) -> Self {
841 Self::new(self.value.ln_1p())
842 }
843 #[inline]
844 fn sinh(self) -> Self {
845 Self::new(self.value.sinh())
846 }
847 #[inline]
848 fn cosh(self) -> Self {
849 Self::new(self.value.cosh())
850 }
851 #[inline]
852 fn tanh(self) -> Self {
853 Self::new(self.value.tanh())
854 }
855 #[inline]
856 fn asinh(self) -> Self {
857 Self::new(self.value.asinh())
858 }
859 #[inline]
860 fn acosh(self) -> Self {
861 Self::new(self.value.acosh())
862 }
863 #[inline]
864 fn atanh(self) -> Self {
865 Self::new(self.value.atanh())
866 }
867 #[inline]
868 fn integer_decode(self) -> (u64, i16, i8) {
869 self.value.integer_decode()
870 }
871 #[inline]
872 fn epsilon() -> Self {
873 Self::new(F::epsilon())
874 }
875 #[inline]
876 fn to_degrees(self) -> Self {
877 Self::new(self.value.to_degrees())
878 }
879 #[inline]
880 fn to_radians(self) -> Self {
881 Self::new(self.value.to_radians())
882 }
883}
884
885impl<F: Float + FloatConst, C: FloatChecker<F>> FloatConst for NoisyFloat<F, C> {
886 #[inline]
887 fn E() -> Self {
888 Self::new(F::E())
889 }
890 #[inline]
891 fn FRAC_1_PI() -> Self {
892 Self::new(F::FRAC_1_PI())
893 }
894 #[inline]
895 fn FRAC_1_SQRT_2() -> Self {
896 Self::new(F::FRAC_1_SQRT_2())
897 }
898 #[inline]
899 fn FRAC_2_PI() -> Self {
900 Self::new(F::FRAC_2_PI())
901 }
902 #[inline]
903 fn FRAC_2_SQRT_PI() -> Self {
904 Self::new(F::FRAC_2_SQRT_PI())
905 }
906 #[inline]
907 fn FRAC_PI_2() -> Self {
908 Self::new(F::FRAC_PI_2())
909 }
910 #[inline]
911 fn FRAC_PI_3() -> Self {
912 Self::new(F::FRAC_PI_3())
913 }
914 #[inline]
915 fn FRAC_PI_4() -> Self {
916 Self::new(F::FRAC_PI_4())
917 }
918 #[inline]
919 fn FRAC_PI_6() -> Self {
920 Self::new(F::FRAC_PI_6())
921 }
922 #[inline]
923 fn FRAC_PI_8() -> Self {
924 Self::new(F::FRAC_PI_8())
925 }
926 #[inline]
927 fn LN_10() -> Self {
928 Self::new(F::LN_10())
929 }
930 #[inline]
931 fn LN_2() -> Self {
932 Self::new(F::LN_2())
933 }
934 #[inline]
935 fn LOG10_E() -> Self {
936 Self::new(F::LOG10_E())
937 }
938 #[inline]
939 fn LOG2_E() -> Self {
940 Self::new(F::LOG2_E())
941 }
942 #[inline]
943 fn PI() -> Self {
944 Self::new(F::PI())
945 }
946 #[inline]
947 fn SQRT_2() -> Self {
948 Self::new(F::SQRT_2())
949 }
950}
951
952impl<F: Float + Signed, C: FloatChecker<F>> Signed for NoisyFloat<F, C> {
953 #[inline]
954 fn abs(&self) -> Self {
955 Self::new(self.value.abs())
956 }
957 #[inline]
958 fn abs_sub(&self, other: &Self) -> Self {
959 Self::new(self.value.abs_sub(other.value))
960 }
961 #[inline]
962 fn signum(&self) -> Self {
963 Self::new(self.value.signum())
964 }
965 #[inline]
966 fn is_positive(&self) -> bool {
967 self.value.is_positive()
968 }
969 #[inline]
970 fn is_negative(&self) -> bool {
971 self.value.is_negative()
972 }
973}
974
975impl<F: Float + Bounded, C: FloatChecker<F>> Bounded for NoisyFloat<F, C> {
976 #[inline]
977 fn min_value() -> Self {
978 Self::new(Float::min_value())
979 }
980 #[inline]
981 fn max_value() -> Self {
982 Self::new(Float::max_value())
983 }
984}
985
986impl<F: Float, C: FloatChecker<F>> iter::Sum for NoisyFloat<F, C> {
987 fn sum<I>(iter: I) -> Self
988 where
989 I: Iterator<Item = Self>,
990 {
991 Self::new(iter.map(|i| i.raw()).fold(F::zero(), |acc, i| acc + i))
992 }
993}
994
995impl<'a, F: Float, C: FloatChecker<F>> iter::Sum<&'a Self> for NoisyFloat<F, C> {
996 fn sum<I>(iter: I) -> Self
997 where
998 I: Iterator<Item = &'a Self>,
999 {
1000 Self::new(iter.map(|i| i.raw()).fold(F::zero(), |acc, i| acc + i))
1001 }
1002}
1003
1004impl<F: Float, C: FloatChecker<F>> iter::Product for NoisyFloat<F, C> {
1005 fn product<I>(iter: I) -> Self
1006 where
1007 I: Iterator<Item = Self>,
1008 {
1009 Self::new(iter.map(|i| i.raw()).fold(F::one(), |acc, i| acc * i))
1010 }
1011}
1012
1013impl<'a, F: Float, C: FloatChecker<F>> iter::Product<&'a Self> for NoisyFloat<F, C> {
1014 fn product<I>(iter: I) -> Self
1015 where
1016 I: Iterator<Item = &'a Self>,
1017 {
1018 Self::new(iter.map(|i| i.raw()).fold(F::one(), |acc, i| acc * i))
1019 }
1020}
1021
1022#[cfg(feature = "approx")]
1023mod approx_impl {
1024 use super::*;
1025 use approx::{AbsDiffEq, RelativeEq, UlpsEq};
1026
1027 impl<F, C> AbsDiffEq<Self> for NoisyFloat<F, C>
1028 where
1029 F: Float + AbsDiffEq<Epsilon = F>,
1030 C: FloatChecker<F>,
1031 {
1032 type Epsilon = NoisyFloat<F, C>;
1033
1034 fn default_epsilon() -> Self::Epsilon {
1035 Self::Epsilon::new(F::default_epsilon())
1036 }
1037
1038 fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
1039 self.raw().abs_diff_eq(&other.raw(), epsilon.raw())
1040 }
1041 }
1042
1043 impl<F, C> RelativeEq<Self> for NoisyFloat<F, C>
1044 where
1045 F: Float + RelativeEq<Epsilon = F>,
1046 C: FloatChecker<F>,
1047 {
1048 fn default_max_relative() -> Self::Epsilon {
1049 Self::new(F::default_max_relative())
1050 }
1051
1052 fn relative_eq(
1053 &self,
1054 other: &Self,
1055 epsilon: Self::Epsilon,
1056 max_relative: Self::Epsilon,
1057 ) -> bool {
1058 self.raw()
1059 .relative_eq(&other.raw(), epsilon.raw(), max_relative.raw())
1060 }
1061 }
1062
1063 impl<F, C> UlpsEq<Self> for NoisyFloat<F, C>
1064 where
1065 F: Float + UlpsEq<Epsilon = F>,
1066 C: FloatChecker<F>,
1067 {
1068 fn default_max_ulps() -> u32 {
1069 F::default_max_ulps()
1070 }
1071
1072 fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
1073 self.raw().ulps_eq(&other.raw(), epsilon.raw(), max_ulps)
1074 }
1075 }
1076}