1#![deny(rustdoc::broken_intra_doc_links)]
2
3use crate::kernels::{
76 ComplexValidated, NumKernelStrictFinite, NumKernelStrictFiniteInDebug, RealValidated,
77};
78
79pub type Native64StrictFinite = NumKernelStrictFinite<f64, 53>;
89pub type Native64StrictFiniteInDebug = NumKernelStrictFiniteInDebug<f64, 53>;
102pub type RealNative64StrictFinite = RealValidated<Native64StrictFinite>;
112
113pub type ComplexNative64StrictFinite = ComplexValidated<Native64StrictFinite>;
120pub type Native32StrictFinite = NumKernelStrictFinite<f32, 24>;
132pub type Native32StrictFiniteInDebug = NumKernelStrictFiniteInDebug<f32, 24>;
145pub type RealNative32StrictFinite = RealValidated<Native32StrictFinite>;
155
156pub type ComplexNative32StrictFinite = ComplexValidated<Native32StrictFinite>;
163pub type RealNative64StrictFiniteInDebug = RealValidated<Native64StrictFiniteInDebug>;
173
174pub type ComplexNative64StrictFiniteInDebug = ComplexValidated<Native64StrictFiniteInDebug>;
181#[cfg(test)]
196mod tests {
197 use super::*;
198 use crate::{
199 Clamp, ComplexScalarConstructors, ComplexScalarGetParts, ComplexScalarMutateParts,
200 ComplexScalarSetParts, Constants, ExpM1, FpChecks, Hypot, Ln1p, MulAddRef, RealScalar,
201 Rounding, Sign, TotalCmp,
202 core::errors::{ErrorsValidationRawComplex, ErrorsValidationRawReal},
203 functions::{
204 ACos, ACosH, ACosHErrors, ACosHInputErrors, ACosRealErrors, ACosRealInputErrors, ASin,
205 ASinH, ASinRealErrors, ASinRealInputErrors, ATan, ATan2, ATan2Errors,
206 ATanComplexErrors, ATanComplexInputErrors, ATanH, ATanHErrors, ATanHInputErrors, Abs,
207 Arg, Classify, Conjugate, Cos, CosH, Exp, ExpErrors, Ln, Log2, Log10,
208 LogarithmComplexErrors, LogarithmComplexInputErrors, Max, Min, NegAssign, Pow,
209 PowComplexBaseRealExponentErrors, PowIntExponentErrors, PowIntExponentInputErrors,
210 PowRealBaseRealExponentErrors, Reciprocal, ReciprocalErrors, Sin, SinH, Sqrt,
211 SqrtRealErrors, Tan, TanH,
212 },
213 };
214 use approx::assert_ulps_eq;
215 use num::{Complex, One, Zero};
216 use rand::RngExt;
217 use std::{
218 assert_matches,
219 cmp::Ordering,
220 f64::consts::*,
221 num::FpCategory,
222 ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
223 };
224 use try_create::{IntoInner, TryNew, TryNewValidated};
225
226 type RealValidated = RealNative64StrictFinite;
227 type ComplexValidated = ComplexNative64StrictFinite;
228
229 mod fp_checks {
230 use super::*;
231
232 #[test]
233 fn is_finite() {
234 let real = RealValidated::try_new(1.).unwrap();
235 assert!(real.is_finite());
236
237 let real = RealValidated::try_new(f64::INFINITY);
238 assert!(real.is_err());
239
240 let complex = ComplexValidated::try_new(Complex::new(1., 1.)).unwrap();
241 assert!(complex.is_finite());
242
243 let complex = ComplexValidated::try_new(Complex::new(f64::INFINITY, 1.));
244 assert!(complex.is_err());
245 }
246
247 #[test]
248 fn is_infinite() {
249 let real = RealValidated::try_new(1.).unwrap();
250 assert!(!real.is_infinite());
251
252 let real = RealValidated::try_new(f64::INFINITY);
253 assert!(real.is_err());
254
255 let complex = ComplexValidated::try_new(Complex::new(1., 1.)).unwrap();
256 assert!(!complex.is_infinite());
257
258 let complex = ComplexValidated::try_new(Complex::new(f64::INFINITY, 1.));
259 assert!(complex.is_err());
260 }
261
262 #[test]
263 fn is_nan() {
264 let real = RealValidated::try_new(1.).unwrap();
265 assert!(!real.is_nan());
266
267 let real = RealValidated::try_new(f64::NAN);
268 assert!(matches!(real, Err(ErrorsValidationRawReal::IsNaN { .. })));
269
270 let complex = ComplexValidated::try_new(Complex::new(1., 1.)).unwrap();
271 assert!(!complex.is_nan());
272
273 let err = ComplexValidated::try_new(Complex::new(f64::NAN, 1.)).unwrap_err();
274 assert_matches!(
275 err,
276 ErrorsValidationRawComplex::InvalidRealPart {
277 source,
278 } if matches!(*source, ErrorsValidationRawReal::IsNaN { .. })
279 );
280 }
281
282 #[test]
283 fn is_normal() {
284 let real = RealValidated::try_new(1.).unwrap();
285 assert!(real.is_normal());
286
287 let real = RealValidated::try_new(0.).unwrap();
288 assert!(!real.is_normal());
289
290 let complex = ComplexValidated::try_new(Complex::new(1., 1.)).unwrap();
291 assert!(complex.is_normal());
292
293 let complex = ComplexValidated::try_new(Complex::new(0., 0.)).unwrap();
294 assert!(!complex.is_normal());
295 }
296 }
297
298 mod new_unchecked {
299 use super::*;
300
301 mod real {
302 use super::*;
303
304 #[test]
305 fn new_unchecked_valid_value() {
306 let x = unsafe { RealValidated::new_unchecked(3.) };
308 assert_eq!(*x.as_ref(), 3.);
309 }
310
311 #[test]
312 fn new_unchecked_zero() {
313 let x = unsafe { RealValidated::new_unchecked(0.0) };
315 assert!(x.is_zero());
316 }
317
318 #[test]
319 fn new_unchecked_negative() {
320 let x = unsafe { RealValidated::new_unchecked(-42.5) };
322 assert_eq!(*x.as_ref(), -42.5);
323 }
324
325 #[test]
326 fn new_unchecked_large_value() {
327 let x = unsafe { RealValidated::new_unchecked(f64::MAX) };
329 assert_eq!(*x.as_ref(), f64::MAX);
330 }
331
332 #[test]
333 fn new_unchecked_small_value() {
334 let x = unsafe { RealValidated::new_unchecked(f64::MIN) };
336 assert_eq!(*x.as_ref(), f64::MIN);
337 }
338
339 #[test]
340 fn new_unchecked_epsilon() {
341 let x = unsafe { RealValidated::new_unchecked(f64::EPSILON) };
343 assert_eq!(*x.as_ref(), f64::EPSILON);
344 }
345
346 #[test]
347 #[cfg(debug_assertions)]
348 #[should_panic(expected = "new_unchecked() validation failed in debug mode")]
349 fn new_unchecked_nan_panics_in_debug() {
350 let _ = unsafe { RealValidated::new_unchecked(f64::NAN) };
352 }
353
354 #[test]
355 #[cfg(debug_assertions)]
356 #[should_panic(expected = "new_unchecked() validation failed in debug mode")]
357 fn new_unchecked_infinity_panics_in_debug() {
358 let _ = unsafe { RealValidated::new_unchecked(f64::INFINITY) };
360 }
361
362 #[test]
363 #[cfg(debug_assertions)]
364 #[should_panic(expected = "new_unchecked() validation failed in debug mode")]
365 fn new_unchecked_neg_infinity_panics_in_debug() {
366 let _ = unsafe { RealValidated::new_unchecked(f64::NEG_INFINITY) };
368 }
369 }
370
371 mod complex {
372 use super::*;
373
374 #[test]
375 fn new_unchecked_valid_value() {
376 let z = unsafe { ComplexValidated::new_unchecked(Complex::new(1.0, 2.0)) };
378 assert_eq!(z.real_part().into_inner(), 1.0);
379 assert_eq!(z.imag_part().into_inner(), 2.0);
380 }
381
382 #[test]
383 fn new_unchecked_zero() {
384 let z = unsafe { ComplexValidated::new_unchecked(Complex::new(0.0, 0.0)) };
386 assert!(z.is_zero());
387 }
388
389 #[test]
390 fn new_unchecked_real_only() {
391 let z = unsafe { ComplexValidated::new_unchecked(Complex::new(5.0, 0.0)) };
393 assert_eq!(z.real_part().into_inner(), 5.0);
394 assert_eq!(z.imag_part().into_inner(), 0.0);
395 }
396
397 #[test]
398 fn new_unchecked_imaginary_only() {
399 let z = unsafe { ComplexValidated::new_unchecked(Complex::new(0.0, -3.0)) };
401 assert_eq!(z.real_part().into_inner(), 0.0);
402 assert_eq!(z.imag_part().into_inner(), -3.0);
403 }
404
405 #[test]
406 fn new_unchecked_negative_components() {
407 let z = unsafe { ComplexValidated::new_unchecked(Complex::new(-1.5, -2.5)) };
409 assert_eq!(z.real_part().into_inner(), -1.5);
410 assert_eq!(z.imag_part().into_inner(), -2.5);
411 }
412
413 #[test]
414 fn new_unchecked_preserves_value_in_arithmetic() {
415 let a = unsafe { ComplexValidated::new_unchecked(Complex::new(1.0, 2.0)) };
417 let b = unsafe { ComplexValidated::new_unchecked(Complex::new(3.0, 4.0)) };
418 let sum = a + b;
419 assert_eq!(sum.real_part().into_inner(), 4.0);
420 assert_eq!(sum.imag_part().into_inner(), 6.0);
421 }
422
423 #[test]
424 #[cfg(debug_assertions)]
425 #[should_panic(expected = "new_unchecked() validation failed in debug mode")]
426 fn new_unchecked_nan_real_part_panics_in_debug() {
427 let _ = unsafe { ComplexValidated::new_unchecked(Complex::new(f64::NAN, 1.0)) };
429 }
430
431 #[test]
432 #[cfg(debug_assertions)]
433 #[should_panic(expected = "new_unchecked() validation failed in debug mode")]
434 fn new_unchecked_nan_imag_part_panics_in_debug() {
435 let _ = unsafe { ComplexValidated::new_unchecked(Complex::new(1.0, f64::NAN)) };
437 }
438
439 #[test]
440 #[cfg(debug_assertions)]
441 #[should_panic(expected = "new_unchecked() validation failed in debug mode")]
442 fn new_unchecked_infinity_real_part_panics_in_debug() {
443 let _ =
445 unsafe { ComplexValidated::new_unchecked(Complex::new(f64::INFINITY, 1.0)) };
446 }
447
448 #[test]
449 #[cfg(debug_assertions)]
450 #[should_panic(expected = "new_unchecked() validation failed in debug mode")]
451 fn new_unchecked_infinity_imag_part_panics_in_debug() {
452 let _ =
454 unsafe { ComplexValidated::new_unchecked(Complex::new(1.0, f64::INFINITY)) };
455 }
456
457 #[test]
458 #[cfg(debug_assertions)]
459 #[should_panic(expected = "new_unchecked() validation failed in debug mode")]
460 fn new_unchecked_neg_infinity_panics_in_debug() {
461 let _ = unsafe {
463 ComplexValidated::new_unchecked(Complex::new(
464 f64::NEG_INFINITY,
465 f64::NEG_INFINITY,
466 ))
467 };
468 }
469 }
470 }
471
472 mod abs {
473 use super::*;
474
475 mod real {
476 use super::*;
477
478 #[test]
479 fn abs_valid() {
480 let value = RealValidated::try_new(-4.).unwrap();
481
482 let expected_result = RealValidated::try_new(4.).unwrap();
483 assert_eq!(value.try_abs().unwrap().into_inner(), expected_result);
484 assert_eq!(value.abs().into_inner(), expected_result);
485 }
486
487 #[test]
488 fn abs_zero() {
489 let value = RealValidated::try_new(0.).unwrap();
490
491 let expected_result = RealValidated::try_new(0.).unwrap();
492 assert_eq!(value.try_abs().unwrap().into_inner(), expected_result);
493 assert_eq!(value.abs().into_inner(), expected_result);
494 }
495
496 }
520
521 mod complex {
522 use super::*;
523
524 #[test]
525 fn abs_valid() {
526 let value = ComplexValidated::try_new(Complex::new(3., 4.)).unwrap();
527
528 let expected_result = RealValidated::try_new(5.).unwrap();
529 assert_eq!(value.try_abs().unwrap().into_inner(), expected_result);
530 assert_eq!(value.abs().into_inner(), expected_result);
531 }
532
533 #[test]
534 fn abs_zero() {
535 let value = ComplexValidated::try_new(Complex::new(0., 0.)).unwrap();
536
537 let expected_result = RealValidated::try_new(0.).unwrap();
538 assert_eq!(value.try_abs().unwrap().into_inner(), expected_result);
539 assert_eq!(value.abs().into_inner(), expected_result);
540 }
541 }
575 }
576
577 mod builders {
578 use super::*;
579
580 mod real {
581 use super::*;
582
583 #[test]
584 fn into_inner() {
585 let value = RealValidated::try_new(1.23).unwrap();
586 assert_eq!(value.into_inner(), 1.23);
587 }
588
589 #[test]
590 fn new() {
591 let value = RealValidated::try_new(1.23).unwrap();
592 assert_eq!(*value.as_ref(), 1.23);
593 }
594
595 #[test]
596 fn try_new_nan() {
597 let err = RealValidated::try_new(f64::NAN).unwrap_err();
598 assert_matches!(err, ErrorsValidationRawReal::IsNaN { .. });
599 }
600
601 #[test]
602 fn try_new_pos_infinity() {
603 let err = RealValidated::try_new(f64::INFINITY).unwrap_err();
604 assert_matches!(err, ErrorsValidationRawReal::IsPosInfinity { .. });
605 }
606
607 #[test]
608 fn try_new_neg_infinity() {
609 let err = RealValidated::try_new(f64::NEG_INFINITY).unwrap_err();
610 assert_matches!(err, ErrorsValidationRawReal::IsNegInfinity { .. });
611 }
612 }
613
614 mod complex {
615 use super::*;
616
617 #[test]
618 fn into_inner() {
619 let v = Complex::new(1., 2.);
620 let value = ComplexValidated::try_new(v).unwrap();
621 assert_eq!(value.into_inner(), v);
622 }
623
624 #[test]
625 fn new() {
626 let v = Complex::new(1., 2.);
627 let value = ComplexValidated::try_new(v).unwrap();
628 assert_eq!(value.into_inner(), v);
629 }
630
631 #[test]
632 fn real_part() {
633 let c1 = ComplexValidated::try_new_validated(Complex::new(1.23, 4.56)).unwrap();
634 assert_eq!(c1.real_part().as_ref(), &1.23);
635
636 let c2 = ComplexValidated::try_new_validated(Complex::new(-7.89, 0.12)).unwrap();
637 assert_eq!(c2.real_part().as_ref(), &-7.89);
638
639 let c3 = ComplexValidated::try_new_validated(Complex::new(0., 10.)).unwrap();
640 assert!(c3.real_part().is_zero());
641
642 let c_nan_re =
643 ComplexValidated::try_new_validated(Complex::new(f64::NAN, 5.)).unwrap_err();
644 assert_matches!(
645 c_nan_re,
646 ErrorsValidationRawComplex::InvalidRealPart {
647 source
648 } if matches!(*source, ErrorsValidationRawReal::IsNaN { .. })
649 );
650
651 let c_inf_re = ComplexValidated::try_new_validated(Complex::new(f64::INFINITY, 5.))
652 .unwrap_err();
653 assert_matches!(
654 c_inf_re,
655 ErrorsValidationRawComplex::InvalidRealPart {
656 source
657 } if matches!(*source, ErrorsValidationRawReal::IsPosInfinity { .. })
658 );
659
660 let c_neg_inf_re =
661 ComplexValidated::try_new_validated(Complex::new(f64::NEG_INFINITY, 5.))
662 .unwrap_err();
663 assert_matches!(
664 c_neg_inf_re,
665 ErrorsValidationRawComplex::InvalidRealPart {
666 source
667 } if matches!(*source, ErrorsValidationRawReal::IsNegInfinity { .. })
668 );
669 }
670
671 #[test]
672 fn imag_part() {
673 let c1 = ComplexValidated::try_new_validated(Complex::new(1.23, 4.56)).unwrap();
674 assert_eq!(c1.imag_part().as_ref(), &4.56);
675
676 let c2 = ComplexValidated::try_new_validated(Complex::new(-7.89, 0.12)).unwrap();
677 assert_eq!(c2.imag_part().as_ref(), &0.12);
678
679 let c3 = ComplexValidated::try_new_validated(Complex::new(10., 0.)).unwrap();
680 assert!(c3.imag_part().is_zero());
681
682 let c_nan_im =
683 ComplexValidated::try_new_validated(Complex::new(5., f64::NAN)).unwrap_err();
684 assert_matches!(
685 c_nan_im,
686 ErrorsValidationRawComplex::InvalidImaginaryPart {
687 source
688 } if matches!(*source, ErrorsValidationRawReal::IsNaN { .. })
689 );
690
691 let c_inf_im = ComplexValidated::try_new_validated(Complex::new(5., f64::INFINITY))
692 .unwrap_err();
693 assert_matches!(
694 c_inf_im,
695 ErrorsValidationRawComplex::InvalidImaginaryPart {
696 source
697 } if matches!(*source, ErrorsValidationRawReal::IsPosInfinity { .. })
698 );
699
700 let c_neg_inf_im =
701 ComplexValidated::try_new_validated(Complex::new(5., f64::NEG_INFINITY))
702 .unwrap_err();
703 assert_matches!(
704 c_neg_inf_im,
705 ErrorsValidationRawComplex::InvalidImaginaryPart {
706 source
707 } if matches!(*source, ErrorsValidationRawReal::IsNegInfinity { .. })
708 );
709 }
710
711 #[test]
712 fn try_new_complex() {
713 let r1 = RealValidated::try_new(1.23).unwrap();
714 let i1 = RealValidated::try_new(4.56).unwrap();
715 let c1 = ComplexValidated::try_new_complex(*r1.as_ref(), *i1.as_ref()).unwrap();
716 assert_eq!(c1.real_part(), r1);
717 assert_eq!(c1.imag_part(), i1);
718
719 let r2 = RealValidated::try_new(-7.89).unwrap();
720 let i2 = RealValidated::try_new(-0.12).unwrap();
721 let c2 = ComplexValidated::try_new_complex(*r2.as_ref(), *i2.as_ref()).unwrap();
722 assert_eq!(c2.real_part(), r2);
723 assert_eq!(c2.imag_part(), i2);
724
725 let r3 = RealValidated::try_new(0.).unwrap();
726 let i3 = RealValidated::try_new(0.).unwrap();
727 let c3 = ComplexValidated::try_new_complex(*r3.as_ref(), *i3.as_ref()).unwrap();
728 assert_eq!(c3.real_part(), r3);
729 assert_eq!(c3.real_part(), i3);
730 assert!(c3.is_zero());
731
732 let c_nan_re = ComplexValidated::try_new_complex(f64::NAN, 5.).unwrap_err();
733 assert!(matches!(
734 c_nan_re,
735 ErrorsValidationRawComplex::InvalidRealPart { .. }
736 ));
737
738 let c_inf_im = ComplexValidated::try_new_complex(10., f64::INFINITY).unwrap_err();
739 assert!(matches!(
740 c_inf_im,
741 ErrorsValidationRawComplex::InvalidImaginaryPart { .. }
742 ));
743
744 let c_nan_re_inf_im =
745 ComplexValidated::try_new_complex(f64::NAN, f64::INFINITY).unwrap_err();
746 assert!(matches!(
747 c_nan_re_inf_im,
748 ErrorsValidationRawComplex::InvalidBothParts { .. }
749 ));
750 }
751
752 #[test]
753 fn try_new_pure_real() {
754 let r1 = RealValidated::try_new(1.23).unwrap();
755 let c1 = ComplexValidated::try_new_pure_real(*r1.as_ref()).unwrap();
756 assert_eq!(c1.real_part(), r1);
757 assert!(c1.imag_part().is_zero());
758
759 let c_nan = ComplexValidated::try_new_pure_real(f64::NAN).unwrap_err();
760 assert_matches!(
761 c_nan,
762 ErrorsValidationRawComplex::InvalidRealPart {
763 source
764 } if matches!(*source, ErrorsValidationRawReal::IsNaN { .. })
765 );
766 }
767
768 #[test]
769 fn try_new_pure_imaginary() {
770 let i1 = RealValidated::try_new(1.23).unwrap();
771 let c1 = ComplexValidated::try_new_pure_imaginary(*i1.as_ref()).unwrap();
772 assert!(c1.real_part().is_zero());
773 assert_eq!(c1.imag_part(), i1);
774
775 let c_nan = ComplexValidated::try_new_pure_imaginary(f64::NAN).unwrap_err();
776 assert_matches!(
777 c_nan,
778 ErrorsValidationRawComplex::InvalidImaginaryPart {
779 source
780 } if matches!(*source, ErrorsValidationRawReal::IsNaN { .. })
781 );
782 }
783
784 #[test]
785 fn add_to_real_part() {
786 let mut c = ComplexValidated::try_new_validated(Complex::new(1., 2.)).unwrap();
787 c.add_to_real_part(&RealValidated::try_new(3.).unwrap());
788 assert_eq!(c.real_part().as_ref(), &4.);
789 assert_eq!(c.imag_part().as_ref(), &2.);
790
791 c.add_to_real_part(&RealValidated::try_new(-5.).unwrap());
792 assert_eq!(c.real_part().as_ref(), &-1.);
793 assert_eq!(c.imag_part().as_ref(), &2.);
794 }
795
796 #[test]
797 fn add_to_imaginary_part() {
798 let mut c = ComplexValidated::try_new_validated(Complex::new(1., 2.)).unwrap();
799 c.add_to_imaginary_part(&RealValidated::try_new(3.).unwrap());
800 assert_eq!(c.real_part().as_ref(), &1.);
801 assert_eq!(c.imag_part().as_ref(), &5.);
802
803 c.add_to_imaginary_part(&RealValidated::try_new(-4.).unwrap());
804 assert_eq!(c.real_part().as_ref(), &1.);
805 assert_eq!(c.imag_part().as_ref(), &1.);
806 }
807
808 #[test]
809 fn multiply_real_part() {
810 let mut c = ComplexValidated::try_new_validated(Complex::new(1., 2.)).unwrap();
811 c.multiply_real_part(&RealValidated::try_new(3.).unwrap());
812 assert_eq!(c.real_part().as_ref(), &3.);
813 assert_eq!(c.imag_part().as_ref(), &2.);
814
815 c.multiply_real_part(&RealValidated::try_new(-2.).unwrap());
816 assert_eq!(c.real_part().as_ref(), &-6.);
817 assert_eq!(c.imag_part().as_ref(), &2.);
818 }
819
820 #[test]
821 fn multiply_imaginary_part() {
822 let mut c = ComplexValidated::try_new_validated(Complex::new(1., 2.)).unwrap();
823 c.multiply_imaginary_part(&RealValidated::try_new(3.).unwrap());
824 assert_eq!(c.real_part().as_ref(), &1.);
825 assert_eq!(c.imag_part().as_ref(), &6.);
826
827 c.multiply_imaginary_part(&RealValidated::try_new(-0.5).unwrap());
828 assert_eq!(c.real_part().as_ref(), &1.);
829 assert_eq!(c.imag_part().as_ref(), &-3.);
830 }
831
832 #[test]
833 fn set_real_part() {
834 let mut c = ComplexValidated::try_new_validated(Complex::new(1., 2.)).unwrap();
835 c.set_real_part(RealValidated::try_new(3.).unwrap());
836 assert_eq!(c.real_part().as_ref(), &3.);
837 assert_eq!(c.imag_part().as_ref(), &2.);
838
839 c.set_real_part(RealValidated::try_new(-4.).unwrap());
840 assert_eq!(c.real_part().as_ref(), &-4.);
841 assert_eq!(c.imag_part().as_ref(), &2.);
842 }
843
844 #[test]
845 fn set_imaginary_part() {
846 let mut c = ComplexValidated::try_new_validated(Complex::new(1., 2.)).unwrap();
847 c.set_imaginary_part(RealValidated::try_new(3.).unwrap());
848 assert_eq!(c.real_part().as_ref(), &1.);
849 assert_eq!(c.imag_part().as_ref(), &3.);
850
851 c.set_imaginary_part(RealValidated::try_new(-4.).unwrap());
852 assert_eq!(c.real_part().as_ref(), &1.);
853 assert_eq!(c.imag_part().as_ref(), &-4.);
854 }
855 }
856 }
857
858 mod mul {
859 use super::*;
860
861 mod real {
862 use super::*;
863
864 #[test]
865 fn multiply_ref() {
866 let r1 = RealValidated::try_new_validated(3.).unwrap();
867 let r2 = RealValidated::try_new_validated(4.).unwrap();
868 let result = r1 * r2;
869 assert_eq!(result, RealValidated::try_new_validated(12.).unwrap());
870 }
871 }
872
873 mod complex {
874 use super::*;
875
876 #[test]
877 fn multiply_ref() {
878 let c1 = ComplexValidated::try_new_validated(Complex::new(1., 2.)).unwrap();
879 let c2 = ComplexValidated::try_new_validated(Complex::new(3., 4.)).unwrap();
880 let result = c1 * c2;
881 assert_eq!(
882 result,
883 ComplexValidated::try_new_validated(Complex::new(-5., 10.)).unwrap()
884 ); }
886
887 #[test]
888 fn complex_times_real() {
889 let r = RealValidated::try_new_validated(2.).unwrap();
890 let c = ComplexValidated::try_new_validated(Complex::new(3., 4.)).unwrap();
891
892 let result_expected =
893 ComplexValidated::try_new_validated(Complex::new(6., 8.)).unwrap(); let result = c * r;
896 assert_eq!(&result, &result_expected);
897
898 let result = c * r;
899 assert_eq!(&result, &result_expected);
900
901 let mut result = c;
902 result *= &r;
903 assert_eq!(&result, &result_expected);
904
905 let mut result = c;
906 result *= r;
907 assert_eq!(&result, &result_expected);
908 }
909
910 #[test]
911 fn real_times_complex() {
912 let r = RealValidated::try_new_validated(2.).unwrap();
913 let c = ComplexValidated::try_new_validated(Complex::new(3., 4.)).unwrap();
914
915 let result_expected =
916 ComplexValidated::try_new_validated(Complex::new(6., 8.)).unwrap(); let result = r * c;
919 assert_eq!(&result, &result_expected);
920 }
921 }
922 }
923
924 mod arithmetic {
925 use super::*;
926
927 mod real {
928 use super::*;
929
930 #[test]
931 fn add() {
932 let r1 = RealValidated::try_new_validated(3.).unwrap();
933 let r2 = RealValidated::try_new_validated(4.).unwrap();
934
935 let expected_result = RealValidated::try_new_validated(7.).unwrap();
936
937 let result = r1.add(&r2);
938 assert_eq!(result, expected_result);
939
940 let result = r1.add(r2);
941 assert_eq!(result, expected_result);
942
943 let result = (&r1).add(r2);
944 assert_eq!(result, expected_result);
945
946 let result = (&r1).add(&r2);
947 assert_eq!(result, expected_result);
948
949 let mut result = r1;
950 result.add_assign(&r2);
951 assert_eq!(result, expected_result);
952
953 let mut result = r1;
954 result.add_assign(r2);
955 assert_eq!(result, expected_result);
956 }
957
958 #[test]
959 fn sub() {
960 let r1 = RealValidated::try_new_validated(3.).unwrap();
961 let r2 = RealValidated::try_new_validated(4.).unwrap();
962
963 let expected_result = RealValidated::try_new_validated(-1.).unwrap();
964
965 let result = r1.sub(&r2);
966 assert_eq!(result, expected_result);
967
968 let result = r1.sub(r2);
969 assert_eq!(result, expected_result);
970
971 let result = (&r1).sub(r2);
972 assert_eq!(result, expected_result);
973
974 let result = (&r1).sub(&r2);
975 assert_eq!(result, expected_result);
976
977 let mut result = r1;
978 result.sub_assign(&r2);
979 assert_eq!(result, expected_result);
980
981 let mut result = r1;
982 result.sub_assign(r2);
983 assert_eq!(result, expected_result);
984 }
985
986 #[test]
987 fn mul() {
988 let r1 = RealValidated::try_new_validated(3.).unwrap();
989 let r2 = RealValidated::try_new_validated(4.).unwrap();
990
991 let expected_result = RealValidated::try_new_validated(12.).unwrap();
992
993 let result = r1.mul(&r2);
994 assert_eq!(result, expected_result);
995
996 let result = r1.mul(r2);
997 assert_eq!(result, expected_result);
998
999 let result = (&r1).mul(r2);
1000 assert_eq!(result, expected_result);
1001
1002 let result = (&r1).mul(&r2);
1003 assert_eq!(result, expected_result);
1004
1005 let mut result = r1;
1006 result.mul_assign(&r2);
1007 assert_eq!(result, expected_result);
1008
1009 let mut result = r1;
1010 result.mul_assign(r2);
1011 assert_eq!(result, expected_result);
1012 }
1013
1014 #[test]
1015 fn div() {
1016 let r1 = RealValidated::try_new_validated(3.).unwrap();
1017 let r2 = RealValidated::try_new_validated(4.).unwrap();
1018
1019 let expected_result = RealValidated::try_new_validated(0.75).unwrap();
1020
1021 let result = r1.div(&r2);
1022 assert_eq!(result, expected_result);
1023
1024 let result = r1.div(r2);
1025 assert_eq!(result, expected_result);
1026
1027 let result = (&r1).div(r2);
1028 assert_eq!(result, expected_result);
1029
1030 let result = (&r1).div(&r2);
1031 assert_eq!(result, expected_result);
1032
1033 let mut result = r1;
1034 result.div_assign(&r2);
1035 assert_eq!(result, expected_result);
1036
1037 let mut result = r1;
1038 result.div_assign(r2);
1039 assert_eq!(result, expected_result);
1040 }
1041
1042 #[test]
1043 fn neg() {
1044 let num = RealValidated::try_new_validated(1.).unwrap();
1045 let expected = RealValidated::try_new_validated(-1.).unwrap();
1046 assert_eq!(num.neg(), expected);
1047 }
1048
1049 #[test]
1050 fn neg_assign() {
1051 let mut num = 1.;
1052 num.neg_assign();
1053 let expected = -1.;
1054 assert_eq!(&num, &expected);
1055
1056 let mut num = RealValidated::one();
1057 num.neg_assign();
1058 let expected = RealValidated::try_new_validated(-1.).unwrap();
1059 assert_eq!(&num, &expected);
1060 }
1061
1062 #[test]
1063 #[should_panic(expected = "Division failed validation")]
1064 fn div_by_zero() {
1065 let one = RealValidated::one();
1066 let zero = RealValidated::zero();
1067 let _ = one / zero;
1068 }
1069
1070 #[test]
1071 #[should_panic(expected = "Division failed validation")]
1072 fn div_assign_by_zero() {
1073 let mut num = RealValidated::one();
1074 let zero_ref = &RealValidated::zero();
1075 num /= zero_ref;
1076 }
1077
1078 #[test]
1079 fn mul_add() {
1080 let a = RealValidated::try_new(2.0).unwrap();
1081 let b = RealValidated::try_new(3.0).unwrap();
1082 let c = RealValidated::try_new(4.0).unwrap();
1083 assert_eq!(a.mul_add_ref(&b, &c), RealValidated::try_new(10.0).unwrap());
1085 }
1086 }
1087
1088 mod complex {
1089 use super::*;
1090
1091 #[test]
1092 fn add() {
1093 let r1 = ComplexValidated::try_new_validated(Complex::new(2., 3.)).unwrap();
1094 let r2 = ComplexValidated::try_new_validated(Complex::new(4., -4.)).unwrap();
1095
1096 let expected_result =
1097 ComplexValidated::try_new_validated(Complex::new(6., -1.)).unwrap();
1098
1099 let result = r1.add(&r2);
1100 assert_eq!(result, expected_result);
1101
1102 let result = r1.add(r2);
1103 assert_eq!(result, expected_result);
1104
1105 let result = (&r1).add(r2);
1106 assert_eq!(result, expected_result);
1107
1108 let result = (&r1).add(&r2);
1109 assert_eq!(result, expected_result);
1110
1111 let mut result = r1;
1112 result.add_assign(&r2);
1113 assert_eq!(result, expected_result);
1114
1115 let mut result = r1;
1116 result.add_assign(r2);
1117 assert_eq!(result, expected_result);
1118 }
1119
1120 #[test]
1121 fn sub() {
1122 let r1 = ComplexValidated::try_new_validated(Complex::new(2., 3.)).unwrap();
1123 let r2 = ComplexValidated::try_new_validated(Complex::new(4., -4.)).unwrap();
1124
1125 let expected_result =
1126 ComplexValidated::try_new_validated(Complex::new(-2., 7.)).unwrap();
1127
1128 let result = r1.sub(&r2);
1129 assert_eq!(result, expected_result);
1130
1131 let result = r1.sub(r2);
1132 assert_eq!(result, expected_result);
1133
1134 let result = (&r1).sub(r2);
1135 assert_eq!(result, expected_result);
1136
1137 let result = (&r1).sub(&r2);
1138 assert_eq!(result, expected_result);
1139
1140 let mut result = r1;
1141 result.sub_assign(&r2);
1142 assert_eq!(result, expected_result);
1143
1144 let mut result = r1;
1145 result.sub_assign(r2);
1146 assert_eq!(result, expected_result);
1147 }
1148
1149 #[test]
1150 fn mul() {
1151 let r1 = ComplexValidated::try_new_validated(Complex::new(2., 3.)).unwrap();
1152 let r2 = ComplexValidated::try_new_validated(Complex::new(4., -4.)).unwrap();
1153
1154 let expected_result =
1155 ComplexValidated::try_new_validated(Complex::new(20., 4.)).unwrap();
1156
1157 let result = r1.mul(&r2);
1158 assert_eq!(result, expected_result);
1159
1160 let result = r1.mul(r2);
1161 assert_eq!(result, expected_result);
1162
1163 let result = (&r1).mul(r2);
1164 assert_eq!(result, expected_result);
1165
1166 let result = (&r1).mul(&r2);
1167 assert_eq!(result, expected_result);
1168
1169 let mut result = r1;
1170 result.mul_assign(&r2);
1171 assert_eq!(result, expected_result);
1172
1173 let mut result = r1;
1174 result.mul_assign(r2);
1175 assert_eq!(result, expected_result);
1176 }
1177
1178 #[test]
1179 fn div() {
1180 let r1 = ComplexValidated::try_new_validated(Complex::new(2., 3.)).unwrap();
1181 let r2 = ComplexValidated::try_new_validated(Complex::new(4., -4.)).unwrap();
1182
1183 let expected_result =
1184 ComplexValidated::try_new_validated(Complex::new(-0.125, 0.625)).unwrap();
1185
1186 let result = r1.div(&r2);
1187 assert_eq!(result, expected_result);
1188
1189 let result = r1.div(r2);
1190 assert_eq!(result, expected_result);
1191
1192 let result = (&r1).div(r2);
1193 assert_eq!(result, expected_result);
1194
1195 let result = (&r1).div(&r2);
1196 assert_eq!(result, expected_result);
1197
1198 let mut result = r1;
1199 result.div_assign(&r2);
1200 assert_eq!(result, expected_result);
1201
1202 let mut result = r1;
1203 result.div_assign(r2);
1204 assert_eq!(result, expected_result);
1205 }
1206
1207 #[test]
1208 fn neg() {
1209 let v = Complex::new(1., 2.);
1210
1211 let num = ComplexValidated::try_new_validated(v).unwrap();
1212 let expected = Complex::new(-1., -2.);
1213 assert_eq!(num.neg().into_inner(), expected);
1214 }
1215
1216 #[test]
1217 fn neg_assign() {
1218 let v = Complex::new(1., 2.);
1219
1220 let mut num = ComplexValidated::try_new_validated(v).unwrap();
1221 let expected = Complex::new(-1., -2.);
1222 num.neg_assign();
1223 assert_eq!(num.as_ref(), &expected);
1224 }
1225
1226 #[test]
1227 #[should_panic(expected = "Division failed validation")]
1228 fn div_by_zero() {
1229 let one = ComplexValidated::one();
1230 let zero = ComplexValidated::zero();
1231 let _ = one / zero;
1232 }
1233
1234 #[test]
1235 #[should_panic(expected = "Division failed validation")]
1236 fn div_assign_by_zero() {
1237 let mut num = ComplexValidated::one();
1238 let zero_ref = &ComplexValidated::zero();
1239 num /= zero_ref;
1240 }
1241
1242 #[test]
1243 fn mul_add() {
1244 let ca = ComplexValidated::try_new(Complex::new(1.0, 2.0)).unwrap();
1245 let cb = ComplexValidated::try_new(Complex::new(3.0, 4.0)).unwrap();
1246 let cc = ComplexValidated::try_new(Complex::new(5.0, 6.0)).unwrap();
1247 let expected = ComplexValidated::try_new(Complex::new(0.0, 16.0)).unwrap();
1249 assert_eq!(ca.mul_add_ref(&cb, &cc), expected);
1250 }
1251 }
1252 }
1253
1254 mod real_scalar_methods {
1255 use crate::core::errors::RawRealConversionError;
1256
1257 use super::*;
1258
1259 #[test]
1260 fn test_constants() {
1261 assert_eq!(
1262 <RealValidated as Constants>::epsilon().as_ref(),
1263 &f64::EPSILON
1264 );
1265 assert_eq!(<RealValidated as Constants>::negative_one().as_ref(), &-1.0);
1266 assert_eq!(<RealValidated as Constants>::one_div_2().as_ref(), &0.5);
1267 assert_eq!(<RealValidated as Constants>::two().as_ref(), &2.0);
1268 assert_eq!(
1269 <RealValidated as Constants>::max_finite().as_ref(),
1270 &f64::MAX
1271 );
1272 assert_eq!(
1273 <RealValidated as Constants>::min_finite().as_ref(),
1274 &f64::MIN
1275 );
1276 assert_eq!(
1277 <RealValidated as Constants>::pi().as_ref(),
1278 &std::f64::consts::PI
1279 );
1280 assert_eq!(
1281 *<RealValidated as Constants>::two_pi().as_ref(),
1282 std::f64::consts::PI * 2.0
1283 );
1284 assert_eq!(
1285 <RealValidated as Constants>::pi_div_2().as_ref(),
1286 &std::f64::consts::FRAC_PI_2
1287 );
1288 assert_eq!(
1289 <RealValidated as Constants>::ln_2().as_ref(),
1290 &std::f64::consts::LN_2
1291 );
1292 assert_eq!(
1293 <RealValidated as Constants>::ln_10().as_ref(),
1294 &std::f64::consts::LN_10
1295 );
1296 assert_eq!(
1297 <RealValidated as Constants>::log10_2().as_ref(),
1298 &std::f64::consts::LOG10_2
1299 );
1300 assert_eq!(
1301 <RealValidated as Constants>::log2_10().as_ref(),
1302 &std::f64::consts::LOG2_10
1303 );
1304 assert_eq!(
1305 <RealValidated as Constants>::log2_e().as_ref(),
1306 &std::f64::consts::LOG2_E
1307 );
1308 assert_eq!(
1309 <RealValidated as Constants>::log10_e().as_ref(),
1310 &std::f64::consts::LOG10_E
1311 );
1312 assert_eq!(
1313 <RealValidated as Constants>::e().as_ref(),
1314 &std::f64::consts::E
1315 );
1316 }
1317
1318 #[test]
1319 fn round_ties_even() {
1320 let f = RealValidated::try_new(3.3).unwrap();
1321 let g = RealValidated::try_new(-3.3).unwrap();
1322 let h = RealValidated::try_new(3.5).unwrap();
1323 let i = RealValidated::try_new(4.5).unwrap();
1324 let j = RealValidated::try_new(-3.5).unwrap();
1325 let k = RealValidated::try_new(-4.5).unwrap();
1326
1327 assert_eq!(
1328 f.kernel_round_ties_even(),
1329 RealValidated::try_new(3.0).unwrap()
1330 );
1331 assert_eq!(
1332 g.kernel_round_ties_even(),
1333 RealValidated::try_new(-3.0).unwrap()
1334 );
1335 assert_eq!(
1336 h.kernel_round_ties_even(),
1337 RealValidated::try_new(4.0).unwrap()
1338 );
1339 assert_eq!(
1340 i.kernel_round_ties_even(),
1341 RealValidated::try_new(4.0).unwrap()
1342 );
1343 assert_eq!(
1344 j.kernel_round_ties_even(),
1345 RealValidated::try_new(-4.0).unwrap()
1346 );
1347 assert_eq!(
1348 k.kernel_round_ties_even(),
1349 RealValidated::try_new(-4.0).unwrap()
1350 );
1351 }
1352
1353 #[test]
1354 fn classify() {
1355 let normal = RealValidated::try_new(1.0).unwrap();
1356 assert_eq!(normal.classify(), FpCategory::Normal);
1357
1358 let zero = RealValidated::zero();
1359 assert_eq!(zero.classify(), FpCategory::Zero);
1360
1361 let subnormal_err = RealValidated::try_new(f64::MIN_POSITIVE / 2.).unwrap_err();
1364 assert!(matches!(
1365 subnormal_err,
1366 ErrorsValidationRawReal::IsSubnormal { .. }
1367 ));
1368
1369 let pos_inf_err = RealValidated::try_new(f64::INFINITY).unwrap_err();
1370 assert!(matches!(
1371 pos_inf_err,
1372 ErrorsValidationRawReal::IsPosInfinity { .. }
1373 ));
1374
1375 let neg_inf_err = RealValidated::try_new(f64::NEG_INFINITY).unwrap_err();
1376 assert!(matches!(
1377 neg_inf_err,
1378 ErrorsValidationRawReal::IsNegInfinity { .. }
1379 ));
1380
1381 let nan_err = RealValidated::try_new(f64::NAN).unwrap_err();
1382 assert!(matches!(nan_err, ErrorsValidationRawReal::IsNaN { .. }));
1383 }
1384
1385 #[test]
1386 fn try_from_f64_valid() {
1387 let val = RealValidated::try_from_f64(123.45).unwrap();
1388 assert_eq!(val.as_ref(), &123.45);
1389 }
1390
1391 #[test]
1392 fn try_from_f64_invalid() {
1393 let err = RealValidated::try_from_f64(f64::NAN).unwrap_err();
1394 assert_matches!(
1395 err,
1396 RawRealConversionError::InputValidation {
1397 source: ErrorsValidationRawReal::IsNaN { .. }
1398 }
1399 );
1400 }
1401
1402 #[test]
1403 fn rounding_and_trunc() {
1404 let val1 = RealValidated::try_new(3.7).unwrap();
1405 let val2 = RealValidated::try_new(-3.7).unwrap();
1406
1407 assert_eq!(val1.kernel_ceil(), RealValidated::try_new(4.0).unwrap());
1408 assert_eq!(val2.kernel_ceil(), RealValidated::try_new(-3.0).unwrap());
1409
1410 assert_eq!(val1.kernel_floor(), RealValidated::try_new(3.0).unwrap());
1411 assert_eq!(val2.kernel_floor(), RealValidated::try_new(-4.0).unwrap());
1412
1413 assert_eq!(val1.kernel_round(), RealValidated::try_new(4.0).unwrap());
1414 assert_eq!(val2.kernel_round(), RealValidated::try_new(-4.0).unwrap());
1415
1416 assert_eq!(val1.kernel_trunc(), RealValidated::try_new(3.0).unwrap());
1417 assert_eq!(val2.kernel_trunc(), RealValidated::try_new(-3.0).unwrap());
1418
1419 let frac1 = val1.kernel_fract();
1421 assert!((frac1.as_ref() - 0.7).abs() < 1e-9);
1422
1423 let frac2 = val2.kernel_fract();
1424 assert!((frac2.as_ref() - (-0.7)).abs() < 1e-9);
1425 }
1426
1427 #[test]
1428 fn sign_and_constants() {
1429 let pos = RealValidated::try_new(5.0).unwrap();
1430 let neg = RealValidated::try_new(-5.0).unwrap();
1431 let zero = RealValidated::zero();
1432
1433 assert!(pos.kernel_is_sign_positive());
1434 assert!(!pos.kernel_is_sign_negative());
1435
1436 assert!(!neg.kernel_is_sign_positive());
1437 assert!(neg.kernel_is_sign_negative());
1438
1439 assert!(zero.kernel_is_sign_positive()); assert!(!zero.kernel_is_sign_negative());
1441
1442 let neg_zero = RealValidated::try_new(-0.0).unwrap();
1443 assert!(!neg_zero.kernel_is_sign_positive());
1444 assert!(neg_zero.kernel_is_sign_negative());
1445
1446 assert_eq!(pos.kernel_copysign(&neg), neg);
1447 assert_eq!(neg.kernel_copysign(&pos), pos);
1448
1449 assert_eq!(
1450 RealValidated::one_div_2(),
1451 RealValidated::try_new(0.5).unwrap()
1452 );
1453 assert_eq!(RealValidated::two(), RealValidated::try_new(2.0).unwrap());
1454 assert_eq!(
1455 RealValidated::max_finite(),
1456 RealValidated::try_new(f64::MAX).unwrap()
1457 );
1458 assert_eq!(
1459 RealValidated::min_finite(),
1460 RealValidated::try_new(f64::MIN).unwrap()
1461 );
1462 }
1463
1464 #[test]
1465 fn epsilon() {
1466 let eps = RealValidated::epsilon();
1467 assert!(eps.is_finite() && eps > RealValidated::zero());
1468 let expected_eps_val = 2.0f64.pow(-52);
1469 let expected_eps = RealValidated::try_new(expected_eps_val).unwrap();
1470 assert_eq!(eps, expected_eps, "Epsilon value mismatch");
1471 }
1472
1473 #[test]
1474 fn clamp_ref() {
1475 let val = RealValidated::try_new(5.).unwrap();
1476 let min_val = RealValidated::try_new(0.).unwrap();
1477 let max_val = RealValidated::try_new(10.).unwrap();
1478
1479 assert_eq!(val.clamp_ref(&min_val, &max_val), val);
1480 assert_eq!(
1481 RealValidated::try_new(-5.)
1482 .unwrap()
1483 .clamp_ref(&min_val, &max_val),
1484 min_val
1485 );
1486 assert_eq!(
1487 RealValidated::try_new(15.)
1488 .unwrap()
1489 .clamp_ref(&min_val, &max_val),
1490 max_val
1491 );
1492 }
1493
1494 #[test]
1495 fn hypot() {
1496 let a = RealValidated::try_new(3.).unwrap();
1497 let b = RealValidated::try_new(4.).unwrap();
1498 let expected = RealValidated::try_new(5.).unwrap();
1499 assert_eq!(a.hypot(&b), expected);
1500 }
1501
1502 #[test]
1503 fn signum() {
1504 assert_eq!(
1505 RealValidated::try_new(5.).unwrap().kernel_signum(),
1506 RealValidated::one()
1507 );
1508 assert_eq!(
1509 RealValidated::try_new(-5.).unwrap().kernel_signum(),
1510 RealValidated::negative_one()
1511 );
1512 assert_eq!(RealValidated::zero().kernel_signum(), RealValidated::one());
1514 }
1515
1516 #[test]
1517 fn total_cmp() {
1518 let r1 = RealValidated::try_new(1.).unwrap();
1519 let r2 = RealValidated::try_new(2.).unwrap();
1520 assert_eq!(r1.total_cmp(&r1), Ordering::Equal);
1521 assert_eq!(r1.total_cmp(&r2), Ordering::Less);
1522 assert_eq!(r2.total_cmp(&r1), Ordering::Greater);
1523 }
1524
1525 #[test]
1526 fn mul_add_mul_mut() {
1527 let mut a = RealValidated::try_new(2.).unwrap();
1528 let b = RealValidated::try_new(3.).unwrap(); let c = RealValidated::try_new(4.).unwrap(); let d = RealValidated::try_new(5.).unwrap(); a.kernel_mul_add_mul_mut(&b, &c, &d);
1533 assert_eq!(a, RealValidated::try_new(26.).unwrap());
1534 }
1535
1536 #[test]
1537 fn mul_sub_mul_mut() {
1538 let mut a = RealValidated::try_new(10.).unwrap();
1539 let b = RealValidated::try_new(2.).unwrap(); let c = RealValidated::try_new(3.).unwrap(); let d = RealValidated::try_new(4.).unwrap(); a.kernel_mul_sub_mul_mut(&b, &c, &d);
1544 assert_eq!(a, RealValidated::try_new(8.).unwrap());
1545 }
1546 }
1547
1548 mod complex_scalar_methods {
1549 use super::*;
1550 use crate::functions::{ArgErrors, ArgInputErrors};
1551
1552 #[test]
1553 fn conjugate() {
1554 let c = ComplexValidated::try_new(Complex::new(1., 2.)).unwrap();
1555 let expected = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
1556 assert_eq!(c.conjugate(), expected);
1557
1558 let c_real = ComplexValidated::try_new_pure_real(5.).unwrap();
1559 assert_eq!(c_real.conjugate(), c_real);
1560
1561 let c_imag = ComplexValidated::try_new_pure_imaginary(3.).unwrap();
1562 let expected_imag = ComplexValidated::try_new_pure_imaginary(-3.).unwrap();
1563 assert_eq!(c_imag.conjugate(), expected_imag);
1564 }
1565
1566 #[test]
1567 fn arg_valid() {
1568 let c1 = ComplexValidated::one();
1570 assert_eq!(c1.arg(), RealValidated::zero());
1571
1572 let c2 = ComplexValidated::try_new_pure_imaginary(1.0).unwrap();
1574 let pi_div_2 = RealValidated::try_new(FRAC_PI_2).unwrap();
1575 assert_eq!(c2.arg(), pi_div_2);
1576
1577 let c3 = ComplexValidated::try_new_pure_real(-1.0).unwrap();
1579 let pi = RealValidated::try_new(PI).unwrap();
1580 assert_eq!(c3.arg(), pi);
1581
1582 let c4 = ComplexValidated::try_new(Complex::new(1.0, 1.0)).unwrap();
1584 let pi_div_4 = RealValidated::try_new(FRAC_PI_4).unwrap();
1585 assert_eq!(c4.arg(), pi_div_4);
1586 }
1587
1588 #[test]
1589 fn arg_zero() {
1590 let zero = ComplexValidated::zero();
1591 let res = zero.try_arg();
1592 assert!(matches!(
1593 res,
1594 Err(ArgErrors::Input(ArgInputErrors::Zero { .. }))
1595 ));
1596 }
1597 }
1598
1599 mod function_traits {
1600 use super::*;
1601 use crate::functions::{
1602 ATan2InputErrors, LogarithmRealErrors, LogarithmRealInputErrors,
1603 PowComplexBaseRealExponentInputErrors, PowRealBaseRealExponentInputErrors,
1604 ReciprocalInputErrors, SqrtRealInputErrors,
1605 };
1606
1607 mod min_max {
1608 use super::*;
1609
1610 #[test]
1611 fn max_valid() {
1612 let r1 = RealValidated::try_new(3.).unwrap();
1613 let r2 = RealValidated::try_new(4.).unwrap();
1614 assert_eq!(r1.max_by_ref(&r2), &r2);
1615 assert_eq!(r2.max_by_ref(&r1), &r2);
1616 }
1617
1618 #[test]
1619 fn min_valid() {
1620 let r1 = RealValidated::try_new(3.).unwrap();
1621 let r2 = RealValidated::try_new(4.).unwrap();
1622 assert_eq!(r1.min_by_ref(&r2), &r1);
1623 assert_eq!(r2.min_by_ref(&r1), &r1);
1624 }
1625 }
1626
1627 mod exp {
1628 use super::*;
1629
1630 mod real {
1631 use super::*;
1632
1633 #[test]
1634 fn exp_valid() {
1635 let exponent = RealValidated::try_new(1.).unwrap();
1636 let expected = std::f64::consts::E;
1637 assert_eq!(exponent.try_exp().unwrap().as_ref(), &expected);
1638 assert_eq!(exponent.exp().as_ref(), &expected);
1639 }
1640
1641 #[test]
1642 fn exp_m1_valid() {
1643 let exponent = RealValidated::try_new(1.).unwrap();
1644 let expected = 1.718281828459045;
1645 assert_ulps_eq!(exponent.exp_m1().as_ref(), &expected);
1646 }
1647
1648 #[test]
1649 fn exp_overflow() {
1650 let large_val = RealValidated::try_new(1.0e60).unwrap(); let res_large = large_val.try_exp();
1652 assert!(matches!(
1653 res_large,
1654 Err(ExpErrors::Output {
1655 source: ErrorsValidationRawReal::IsPosInfinity { .. }
1656 })
1657 ),);
1658 }
1659 } mod complex {
1662 use super::*;
1663
1664 #[test]
1665 fn exp_valid() {
1666 let exponent = ComplexValidated::try_new(Complex::new(0., PI)).unwrap();
1667 let expected = Complex::new(-1., 1.2246467991473532e-16);
1668 assert_eq!(exponent.try_exp().unwrap().as_ref(), &expected);
1669 assert_eq!(exponent.exp().as_ref(), &expected);
1670 }
1671 } } mod logarithm {
1675 use super::*;
1676
1677 mod real {
1678 use super::*;
1679
1680 #[test]
1681 fn ln_valid() {
1682 let e = RealValidated::one().exp();
1683 let expected = 1.0;
1684 assert_eq!(e.try_ln().unwrap().as_ref(), &expected);
1685 assert_eq!(e.ln().as_ref(), &expected);
1686 }
1687
1688 #[test]
1689 fn log10_valid() {
1690 let v = RealValidated::try_new(100.).unwrap();
1691 let expected = 2.0;
1692 assert_eq!(v.try_log10().unwrap().as_ref(), &expected);
1693 assert_eq!(v.log10().as_ref(), &expected);
1694 }
1695
1696 #[test]
1697 fn log2_valid() {
1698 let v = RealValidated::try_new(4.).unwrap();
1699 let expected = 2.0;
1700 assert_eq!(v.try_log2().unwrap().as_ref(), &expected);
1701 assert_eq!(v.log2().as_ref(), &expected);
1702 }
1703
1704 #[test]
1705 fn ln_1p_valid() {
1706 let v = RealValidated::one().exp() - RealValidated::one();
1708
1709 assert_eq!(v.ln_1p().as_ref(), &1.);
1711 }
1712
1713 #[test]
1714 fn ln_domain_errors() {
1715 let neg_val = RealValidated::try_new(-1.).unwrap();
1716 assert!(matches!(
1717 neg_val.try_ln(),
1718 Err(LogarithmRealErrors::Input(
1719 LogarithmRealInputErrors::NegativeArgument { .. }
1720 ))
1721 ));
1722
1723 let zero_val = RealValidated::zero();
1724 assert!(matches!(
1725 zero_val.try_ln(),
1726 Err(LogarithmRealErrors::Input(
1727 LogarithmRealInputErrors::ZeroArgument { .. }
1728 ))
1729 ));
1730 }
1731
1732 #[test]
1733 fn log10_domain_errors() {
1734 let neg_val = RealValidated::try_new(-1.).unwrap();
1735 assert!(matches!(
1736 neg_val.try_log10(),
1737 Err(LogarithmRealErrors::Input(
1738 LogarithmRealInputErrors::NegativeArgument { .. }
1739 ))
1740 ));
1741
1742 let zero_val = RealValidated::zero();
1743 assert!(matches!(
1744 zero_val.try_log10(),
1745 Err(LogarithmRealErrors::Input(
1746 LogarithmRealInputErrors::ZeroArgument { .. }
1747 ))
1748 ));
1749 }
1750
1751 #[test]
1752 fn log2_domain_errors() {
1753 let neg_val = RealValidated::try_new(-1.).unwrap();
1754 assert!(matches!(
1755 neg_val.try_log2(),
1756 Err(LogarithmRealErrors::Input(
1757 LogarithmRealInputErrors::NegativeArgument { .. }
1758 ))
1759 ));
1760
1761 let zero_val = RealValidated::zero();
1762 assert!(matches!(
1763 zero_val.try_log2(),
1764 Err(LogarithmRealErrors::Input(
1765 LogarithmRealInputErrors::ZeroArgument { .. }
1766 ))
1767 ));
1768 }
1769 } mod complex {
1772 use super::*;
1773
1774 #[test]
1775 fn ln_valid() {
1776 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
1777 let expected = Complex::new(0.8047189562170503, -1.1071487177940904);
1778 assert_eq!(v.try_ln().unwrap().as_ref(), &expected);
1779 assert_eq!(v.ln().as_ref(), &expected);
1780 }
1781
1782 #[test]
1783 fn log10_valid() {
1784 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
1785 let expected = Complex::new(0.3494850021680094, -0.480828578784234);
1786 assert_eq!(v.try_log10().unwrap().as_ref(), &expected);
1787 assert_eq!(v.log10().as_ref(), &expected);
1788 }
1789
1790 #[test]
1791 fn log2_valid() {
1792 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
1793 let expected = Complex::new(1.1609640474436813, -1.5972779646881088);
1794 assert_eq!(v.try_log2().unwrap().as_ref(), &expected);
1795 assert_eq!(v.log2().as_ref(), &expected);
1796 }
1797
1798 #[test]
1799 fn ln_zero() {
1800 let zero_val = ComplexValidated::zero();
1801 assert!(matches!(
1802 zero_val.try_ln(),
1803 Err(LogarithmComplexErrors::Input(
1804 LogarithmComplexInputErrors::ZeroArgument { .. }
1805 ))
1806 ));
1807 }
1808
1809 #[test]
1810 fn log10_zero() {
1811 let zero_val = ComplexValidated::zero();
1812 assert!(matches!(
1813 zero_val.try_log10(),
1814 Err(LogarithmComplexErrors::Input(
1815 LogarithmComplexInputErrors::ZeroArgument { .. }
1816 ))
1817 ));
1818 }
1819
1820 #[test]
1821 fn log2_zero() {
1822 let zero_val = ComplexValidated::zero();
1823 assert!(matches!(
1824 zero_val.try_log2(),
1825 Err(LogarithmComplexErrors::Input(
1826 LogarithmComplexInputErrors::ZeroArgument { .. }
1827 ))
1828 ));
1829 }
1830 } } mod pow {
1834 use super::*;
1835
1836 mod real_base {
1837 use super::*;
1838
1839 #[test]
1840 fn negative_base_real_exponent_error() {
1841 let base = RealValidated::try_new(-2.).unwrap();
1842 let exponent = RealValidated::try_new(0.5).unwrap();
1843 let res = base.try_pow(&exponent);
1844 assert!(matches!(
1845 res,
1846 Err(PowRealBaseRealExponentErrors::Input(
1847 PowRealBaseRealExponentInputErrors::NegativeBase { .. }
1848 ))
1849 ));
1850 }
1851
1852 #[test]
1853 fn real_base_uint_exponent_valid() {
1854 let base = RealValidated::try_new(2.).unwrap();
1855 assert_eq!(
1856 base.try_pow(3u8).unwrap(),
1857 RealValidated::try_new(8.).unwrap()
1858 );
1859 assert_eq!(
1860 base.try_pow(3u16).unwrap(),
1861 RealValidated::try_new(8.).unwrap()
1862 );
1863 assert_eq!(
1864 base.try_pow(3u32).unwrap(),
1865 RealValidated::try_new(8.).unwrap()
1866 );
1867 assert_eq!(
1868 base.try_pow(3u64).unwrap(),
1869 RealValidated::try_new(8.).unwrap()
1870 );
1871 assert_eq!(
1872 base.try_pow(3u128).unwrap(),
1873 RealValidated::try_new(8.).unwrap()
1874 );
1875 assert_eq!(
1876 base.try_pow(3usize).unwrap(),
1877 RealValidated::try_new(8.).unwrap()
1878 );
1879
1880 assert_eq!(base.pow(3u8), RealValidated::try_new(8.).unwrap());
1881 assert_eq!(base.pow(3u16), RealValidated::try_new(8.).unwrap());
1882 assert_eq!(base.pow(3u32), RealValidated::try_new(8.).unwrap());
1883 assert_eq!(base.pow(3u64), RealValidated::try_new(8.).unwrap());
1884 assert_eq!(base.pow(3u128), RealValidated::try_new(8.).unwrap());
1885 assert_eq!(base.pow(3usize), RealValidated::try_new(8.).unwrap());
1886 }
1887
1888 #[test]
1889 fn real_base_int_exponent_valid() {
1890 let base = RealValidated::try_new(2.).unwrap();
1891 assert_eq!(
1892 base.try_pow(3i8).unwrap(),
1893 RealValidated::try_new(8.).unwrap()
1894 );
1895 assert_eq!(
1896 base.try_pow(3i16).unwrap(),
1897 RealValidated::try_new(8.).unwrap()
1898 );
1899 assert_eq!(
1900 base.try_pow(3i32).unwrap(),
1901 RealValidated::try_new(8.).unwrap()
1902 );
1903 assert_eq!(
1904 base.try_pow(3i64).unwrap(),
1905 RealValidated::try_new(8.).unwrap()
1906 );
1907 assert_eq!(
1908 base.try_pow(3i128).unwrap(),
1909 RealValidated::try_new(8.).unwrap()
1910 );
1911 assert_eq!(
1912 base.try_pow(3isize).unwrap(),
1913 RealValidated::try_new(8.).unwrap()
1914 );
1915
1916 assert_eq!(base.pow(3i8), RealValidated::try_new(8.).unwrap());
1917 assert_eq!(base.pow(3i16), RealValidated::try_new(8.).unwrap());
1918 assert_eq!(base.pow(3i32), RealValidated::try_new(8.).unwrap());
1919 assert_eq!(base.pow(3i64), RealValidated::try_new(8.).unwrap());
1920 assert_eq!(base.pow(3i128), RealValidated::try_new(8.).unwrap());
1921 assert_eq!(base.pow(3isize), RealValidated::try_new(8.).unwrap());
1922 }
1923
1924 #[test]
1925 fn real_base_int_exponent_zero_neg_exp_error() {
1926 let base = RealValidated::zero();
1927 let exponent: i32 = -2;
1928 let res = base.try_pow(exponent);
1929 assert!(matches!(
1930 res,
1931 Err(PowIntExponentErrors::Input(
1932 PowIntExponentInputErrors::ZeroBaseNegativeExponent { .. }
1933 ))
1934 ));
1935 }
1936
1937 #[test]
1938 fn real_base_real_exponent_valid() {
1939 let base = RealValidated::try_new(2.).unwrap();
1940 let exponent = RealValidated::try_new(3.).unwrap();
1941 let expected = 8.;
1942 assert_eq!(base.try_pow(&exponent).unwrap().as_ref(), &expected);
1943 assert_eq!(base.pow(&exponent).as_ref(), &expected);
1944 }
1945 }
1946
1947 mod complex_base {
1948 use super::*;
1949
1950 #[test]
1951 fn complex_base_uint_exponent_valid() {
1952 let base = ComplexValidated::try_new(Complex::new(2., 3.)).unwrap();
1953 let expected_res = ComplexValidated::try_new(Complex::new(-46., 9.)).unwrap();
1954
1955 assert_eq!(&base.try_pow(3u8).unwrap(), &expected_res);
1956 assert_eq!(&base.try_pow(3u16).unwrap(), &expected_res);
1957 assert_eq!(&base.try_pow(3u32).unwrap(), &expected_res);
1958 assert_eq!(&base.try_pow(3u64).unwrap(), &expected_res);
1959 assert_eq!(&base.try_pow(3u128).unwrap(), &expected_res);
1960 assert_eq!(&base.try_pow(3usize).unwrap(), &expected_res);
1961
1962 assert_eq!(&base.pow(3u8), &expected_res);
1963 assert_eq!(&base.pow(3u16), &expected_res);
1964 assert_eq!(&base.pow(3u32), &expected_res);
1965 assert_eq!(&base.pow(3u64), &expected_res);
1966 assert_eq!(&base.pow(3u128), &expected_res);
1967 assert_eq!(&base.pow(3usize), &expected_res);
1968 }
1969
1970 #[test]
1971 fn complex_base_int_exponent_valid() {
1972 let base = ComplexValidated::try_new(Complex::new(2., 3.)).unwrap();
1973 let expected_res = ComplexValidated::try_new(Complex::new(-46., 9.)).unwrap();
1974
1975 assert_eq!(&base.try_pow(3i8).unwrap(), &expected_res);
1976 assert_eq!(&base.try_pow(3i16).unwrap(), &expected_res);
1977 assert_eq!(&base.try_pow(3i32).unwrap(), &expected_res);
1978 assert_eq!(&base.try_pow(3i64).unwrap(), &expected_res);
1979 assert_eq!(&base.try_pow(3i128).unwrap(), &expected_res);
1980 assert_eq!(&base.try_pow(3isize).unwrap(), &expected_res);
1981
1982 assert_eq!(&base.pow(3i8), &expected_res);
1983 assert_eq!(&base.pow(3i16), &expected_res);
1984 assert_eq!(&base.pow(3i32), &expected_res);
1985 assert_eq!(&base.pow(3i64), &expected_res);
1986 assert_eq!(&base.pow(3i128), &expected_res);
1987 assert_eq!(&base.pow(3isize), &expected_res);
1988 }
1989
1990 #[test]
1991 fn complex_zero_base_negative_real_exponent_error() {
1992 let base = ComplexValidated::zero();
1993 let exponent = RealValidated::try_new(-2.).unwrap();
1994 let res = base.try_pow(&exponent);
1995 assert!(matches!(
1996 res,
1997 Err(PowComplexBaseRealExponentErrors::Input(
1998 PowComplexBaseRealExponentInputErrors::ZeroBaseNegativeExponent { .. }
1999 ))
2000 ));
2001 }
2002
2003 #[test]
2004 fn complex_zero_base_zero_real_exponent() {
2005 let base = ComplexValidated::zero();
2006 let exponent = RealValidated::zero();
2007 let res = base.try_pow(&exponent).unwrap();
2008 assert_eq!(res, ComplexValidated::one());
2009 }
2010
2011 #[test]
2012 fn complex_base_int_exponent_zero_neg_exp_error() {
2013 let base = ComplexValidated::zero();
2014 let exponent: i32 = -2;
2015 let res = base.try_pow(exponent);
2016 assert!(matches!(
2017 res,
2018 Err(PowIntExponentErrors::Input(
2019 PowIntExponentInputErrors::ZeroBaseNegativeExponent { .. }
2020 ))
2021 ));
2022 }
2023
2024 #[test]
2025 fn complex_base_real_exponent_valid() {
2026 let base = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2027 let exponent = RealValidated::try_new(3.).unwrap();
2028 let expected = Complex::new(-11.000000000000004, 1.9999999999999973);
2029 assert_eq!(base.try_pow(&exponent).unwrap().as_ref(), &expected);
2030 assert_eq!(base.pow(&exponent).as_ref(), &expected);
2031 }
2032
2033 #[test]
2034 fn complex_zero_base_real_exponent_valid() {
2035 let base = ComplexValidated::zero();
2036 let exponent = RealValidated::try_new(3.).unwrap();
2037 let expected = Complex::new(0., 0.);
2038 assert_eq!(base.try_pow(&exponent).unwrap().as_ref(), &expected);
2039 assert_eq!(base.pow(&exponent).as_ref(), &expected);
2040 }
2041 }
2042 }
2043
2044 mod reciprocal {
2045 use super::*;
2046
2047 mod real {
2048 use super::*;
2049
2050 #[test]
2051 fn reciprocal_valid() {
2052 let v = RealValidated::try_new(2.).unwrap();
2053
2054 let res = v.try_reciprocal().unwrap();
2055 assert_eq!(res.into_inner(), 0.5);
2056
2057 let res = v.reciprocal();
2058 assert_eq!(res.into_inner(), 0.5);
2059 }
2060
2061 #[test]
2062 fn reciprocal_real_zero() {
2063 let zero_val = RealValidated::zero();
2064 let res = zero_val.try_reciprocal();
2065 assert!(matches!(
2066 res,
2067 Err(ReciprocalErrors::Input(
2068 ReciprocalInputErrors::DivisionByZero { .. }
2069 ))
2070 ));
2071 }
2072 }
2073
2074 mod complex {
2075 use super::*;
2076
2077 #[test]
2078 fn reciprocal_valid() {
2079 let v = ComplexValidated::try_new(Complex::new(3., 4.)).unwrap();
2080
2081 let expected = Complex::new(0.12, -0.16);
2082
2083 let res = v.try_reciprocal().unwrap();
2084 assert_eq!(res.as_ref(), &expected);
2085
2086 let res = v.reciprocal();
2087 assert_eq!(res.as_ref(), &expected);
2088 }
2089
2090 #[test]
2091 fn reciprocal_complex_zero() {
2092 let zero_val = ComplexValidated::zero();
2093 let res = zero_val.try_reciprocal();
2094 assert!(matches!(
2095 res,
2096 Err(ReciprocalErrors::Input(
2097 ReciprocalInputErrors::DivisionByZero { .. }
2098 ))
2099 ));
2100 }
2101 }
2102 } mod sqrt {
2105 use super::*;
2106
2107 mod real {
2108 use super::*;
2109
2110 #[test]
2111 fn sqrt_valid() {
2112 let v = RealValidated::try_new(9.).unwrap();
2113 assert_eq!(v.try_sqrt().unwrap().as_ref(), &3.);
2114 assert_eq!(v.sqrt().as_ref(), &3.);
2115 }
2116
2117 #[test]
2118 fn sqrt_negative_input() {
2119 let neg_val = RealValidated::try_new(-4.).unwrap();
2120 let res = neg_val.try_sqrt();
2121 assert!(matches!(
2122 res,
2123 Err(SqrtRealErrors::Input(
2124 SqrtRealInputErrors::NegativeValue { .. }
2125 ))
2126 ));
2127 }
2128 } mod complex {
2131 use super::*;
2132
2133 #[test]
2134 fn sqrt_valid() {
2135 let expected = Complex::new(1., 2.);
2136 let v = ComplexValidated::try_new(expected * expected).unwrap();
2137
2138 let expected = Complex::new(1.0000000000000002, 2.);
2139 assert_eq!(v.try_sqrt().unwrap().as_ref(), &expected);
2140 assert_eq!(v.sqrt().as_ref(), &expected);
2141 }
2142 }
2143 } mod trigonometric {
2146 use super::*;
2147
2148 mod real {
2149 use super::*;
2150
2151 #[test]
2152 fn sin_real_valid() {
2153 let v = RealValidated::pi_div_2();
2154
2155 let expected = 1.;
2156 assert_eq!(v.try_sin().unwrap().as_ref(), &expected);
2157 assert_eq!(v.sin().as_ref(), &expected);
2158 }
2159
2160 #[test]
2161 fn cos_real_valid() {
2162 let v = RealValidated::pi();
2163
2164 let expected = -1.;
2165 assert_eq!(v.try_cos().unwrap().as_ref(), &expected);
2166 assert_eq!(v.cos().as_ref(), &expected);
2167 }
2168
2169 #[test]
2170 fn tan_real_valid() {
2171 let v = RealValidated::one();
2172 let expected = 1.5574077246549023;
2173 assert_ulps_eq!(v.try_tan().unwrap().as_ref(), &expected);
2174 assert_ulps_eq!(v.tan().as_ref(), &expected);
2175 }
2176
2177 #[test]
2178 fn asin_real_valid() {
2179 let v = RealValidated::one();
2180
2181 let expected = std::f64::consts::FRAC_PI_2; assert_eq!(v.try_asin().unwrap().as_ref(), &expected);
2183 assert_eq!(v.asin().as_ref(), &expected);
2184 }
2185
2186 #[test]
2187 fn acos_real_valid() {
2188 let v = RealValidated::one();
2189
2190 let expected = 0.;
2191 assert_eq!(v.try_acos().unwrap().as_ref(), &expected);
2192 assert_eq!(v.acos().as_ref(), &expected);
2193 }
2194
2195 #[test]
2196 fn atan_real_valid() {
2197 let v = RealValidated::one();
2198
2199 let expected = std::f64::consts::FRAC_PI_4; assert_eq!(v.try_atan().unwrap().as_ref(), &expected);
2201 assert_eq!(v.atan().as_ref(), &expected);
2202 }
2203
2204 #[test]
2205 fn atan2_valid() {
2206 let one = RealValidated::one();
2207 let zero = RealValidated::zero();
2208
2209 let expected = std::f64::consts::FRAC_PI_2; assert_eq!(one.try_atan2(&zero).unwrap().as_ref(), &expected);
2211 assert_eq!(one.atan2(&zero).as_ref(), &expected);
2212
2213 let expected = 0.;
2214 assert_eq!(zero.try_atan2(&one).unwrap().as_ref(), &expected);
2215 assert_eq!(zero.atan2(&one).as_ref(), &expected);
2216
2217 let expected = std::f64::consts::FRAC_PI_4; assert_eq!(one.try_atan2(&one).unwrap().as_ref(), &expected);
2219 assert_eq!(one.atan2(&one).as_ref(), &expected);
2220 }
2221
2222 #[test]
2223 fn atan2_zero_over_zero() {
2224 let zero_val = RealValidated::zero();
2225 let res = zero_val.try_atan2(&RealValidated::zero());
2226 assert!(matches!(
2227 res,
2228 Err(ATan2Errors::Input(ATan2InputErrors::ZeroOverZero { .. }))
2229 ));
2230 }
2231
2232 #[test]
2248 fn asin_real_out_of_domain() {
2249 let val_gt_1 = RealValidated::try_new(1.5).unwrap();
2250 assert!(matches!(
2251 val_gt_1.try_asin(),
2252 Err(ASinRealErrors::Input(
2253 ASinRealInputErrors::OutOfDomain { .. }
2254 ))
2255 ));
2256 let val_lt_neg1 = RealValidated::try_new(-1.5).unwrap();
2257 assert!(matches!(
2258 val_lt_neg1.try_asin(),
2259 Err(ASinRealErrors::Input(
2260 ASinRealInputErrors::OutOfDomain { .. }
2261 ))
2262 ));
2263 }
2264
2265 #[test]
2266 fn acos_real_out_of_domain() {
2267 let val_gt_1 = RealValidated::try_new(1.5).unwrap();
2268 assert!(matches!(
2269 val_gt_1.try_acos(),
2270 Err(ACosRealErrors::Input(
2271 ACosRealInputErrors::OutOfDomain { .. }
2272 ))
2273 ));
2274 let val_lt_neg1 = RealValidated::try_new(-1.5).unwrap();
2275 assert!(matches!(
2276 val_lt_neg1.try_acos(),
2277 Err(ACosRealErrors::Input(
2278 ACosRealInputErrors::OutOfDomain { .. }
2279 ))
2280 ));
2281 }
2282 } mod complex {
2285 use super::*;
2286
2287 #[test]
2288 fn sin_complex_valid() {
2289 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2290
2291 let expected = if cfg!(target_arch = "x86_64") {
2292 Complex::new(3.165778513216168, -1.9596010414216063)
2293 } else if cfg!(target_arch = "aarch64") {
2294 Complex::new(3.165778513216168, -1.959601041421606)
2295 } else {
2296 todo!("Architecture not-tested");
2297 };
2298 assert_eq!(v.try_sin().unwrap().as_ref(), &expected);
2299 assert_eq!(v.sin().as_ref(), &expected);
2300
2301 let zero = ComplexValidated::zero();
2302 let expected = Complex::new(0., 0.);
2303 assert_eq!(zero.try_sin().unwrap().as_ref(), &expected);
2304 assert_eq!(zero.sin().as_ref(), &expected);
2305 }
2306
2307 #[test]
2308 fn cos_complex_valid() {
2309 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2310
2311 let expected = if cfg!(target_arch = "x86_64") {
2312 Complex::new(2.0327230070196656, 3.0518977991518)
2313 } else if cfg!(target_arch = "aarch64") {
2314 Complex::new(2.0327230070196656, 3.0518977991517997)
2315 } else {
2316 todo!("Architecture not-tested");
2317 };
2318 assert_eq!(v.try_cos().unwrap().as_ref(), &expected);
2319 assert_eq!(v.cos().as_ref(), &expected);
2320
2321 let zero = ComplexValidated::zero();
2322 let expected = Complex::new(1., 0.);
2323 assert_eq!(zero.try_cos().unwrap().as_ref(), &expected);
2324 assert_eq!(zero.cos().as_ref(), &expected);
2325 }
2326
2327 #[test]
2328 fn tan_complex_valid() {
2329 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2330
2331 let expected = Complex::new(0.03381282607989669, -1.0147936161466335);
2332 assert_eq!(v.try_tan().unwrap().as_ref(), &expected);
2333 assert_eq!(v.tan().as_ref(), &expected);
2334
2335 let zero = ComplexValidated::zero();
2336 let expected = Complex::new(0., 0.);
2337 assert_eq!(zero.try_tan().unwrap().as_ref(), &expected);
2338 assert_eq!(zero.tan().as_ref(), &expected);
2339 }
2340
2341 #[test]
2342 fn asin_complex_valid() {
2343 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2344
2345 let expected = Complex::new(0.42707858639247614, -1.528570919480998);
2346 assert_eq!(v.try_asin().unwrap().as_ref(), &expected);
2347 assert_eq!(v.asin().as_ref(), &expected);
2348
2349 let zero = ComplexValidated::zero();
2350 let expected = Complex::new(0., 0.);
2351 assert_eq!(zero.try_asin().unwrap().as_ref(), &expected);
2352 assert_eq!(zero.asin().as_ref(), &expected);
2353 }
2354
2355 #[test]
2356 fn acos_complex_valid() {
2357 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2358
2359 let expected = Complex::new(1.14371774040242, 1.5285709194809995);
2360 assert_eq!(v.try_acos().unwrap().as_ref(), &expected);
2361 assert_eq!(v.acos().as_ref(), &expected);
2362
2363 let one = ComplexValidated::one();
2364 let expected = Complex::new(0., 0.);
2365 assert_eq!(one.try_acos().unwrap().as_ref(), &expected);
2366 assert_eq!(one.acos().as_ref(), &expected);
2367 }
2368
2369 #[test]
2370 fn atan_complex_valid() {
2371 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2372
2373 let expected = Complex::new(1.3389725222944935, -0.4023594781085251);
2374 assert_eq!(v.try_atan().unwrap().as_ref(), &expected);
2375 assert_eq!(v.atan().as_ref(), &expected);
2376
2377 let zero = ComplexValidated::zero();
2378 let expected = Complex::new(0., 0.);
2379 assert_eq!(zero.try_atan().unwrap().as_ref(), &expected);
2380 assert_eq!(zero.atan().as_ref(), &expected);
2381 }
2382
2383 #[test]
2384 fn atan_complex_pole() {
2385 let i_val = ComplexValidated::try_new_pure_imaginary(1.).unwrap();
2387 assert!(matches!(
2388 i_val.try_atan(),
2389 Err(ATanComplexErrors::Input(
2390 ATanComplexInputErrors::ArgumentIsPole { .. }
2391 ))
2392 ));
2393
2394 let neg_i_val = ComplexValidated::try_new_pure_imaginary(-1.).unwrap();
2395 assert!(matches!(
2396 neg_i_val.try_atan(),
2397 Err(ATanComplexErrors::Input(
2398 ATanComplexInputErrors::ArgumentIsPole { .. }
2399 ))
2400 ));
2401 }
2402 } } mod hyperbolic {
2406 use super::*;
2407
2408 mod real {
2409 use super::*;
2410
2411 #[test]
2412 fn atanh_real_valid() {
2413 let v = RealValidated::zero();
2414 let expected = 0.;
2415 assert_eq!(v.try_atanh().unwrap().as_ref(), &expected);
2416 assert_eq!(v.atanh().as_ref(), &expected);
2417 }
2418
2419 #[test]
2420 fn atanh_real_out_of_domain() {
2421 let val_ge_1 = RealValidated::one(); assert!(matches!(
2423 val_ge_1.try_atanh(),
2424 Err(ATanHErrors::Input(ATanHInputErrors::OutOfDomain { .. }))
2425 ));
2426
2427 let val_le_neg1 = RealValidated::negative_one(); assert!(matches!(
2429 val_le_neg1.try_atanh(),
2430 Err(ATanHErrors::Input(ATanHInputErrors::OutOfDomain { .. }))
2431 ));
2432 }
2433
2434 #[test]
2435 fn acosh_real_valid() {
2436 let v = RealValidated::one();
2437 let expected = 0.;
2438 assert_eq!(v.try_acosh().unwrap().as_ref(), &expected);
2439 assert_eq!(v.acosh().as_ref(), &expected);
2440 }
2441
2442 #[test]
2443 fn acosh_real_out_of_domain() {
2444 let val_lt_1 = RealValidated::try_new(0.5).unwrap();
2445 assert!(matches!(
2446 val_lt_1.try_acosh(),
2447 Err(ACosHErrors::Input(ACosHInputErrors::OutOfDomain { .. }))
2448 ));
2449 }
2450
2451 #[test]
2452 fn asinh_real_valid() {
2453 let v = RealValidated::one();
2454 let expected = 0.881373587019543;
2455 assert_eq!(v.try_asinh().unwrap().as_ref(), &expected);
2456 assert_eq!(v.asinh().as_ref(), &expected);
2457 }
2458
2459 #[test]
2460 fn sinh_real_valid() {
2461 let v = RealValidated::try_new(0.881373587019543).unwrap();
2462 let expected = 1.;
2463 assert_eq!(v.try_sinh().unwrap().as_ref(), &expected);
2464 assert_eq!(v.sinh().as_ref(), &expected);
2465 }
2466
2467 #[test]
2468 fn cosh_real_valid() {
2469 let v = RealValidated::one();
2470 let expected = 1.5430806348152437;
2471 assert_eq!(v.try_cosh().unwrap().as_ref(), &expected);
2472 assert_eq!(v.cosh().as_ref(), &expected);
2473 }
2474
2475 #[test]
2476 fn tanh_real_valid() {
2477 let v = RealValidated::one();
2478 let expected = 0.7615941559557649;
2479 assert_eq!(v.try_tanh().unwrap().as_ref(), &expected);
2480 assert_eq!(v.tanh().as_ref(), &expected);
2481 }
2482 }
2483
2484 mod complex {
2485 use super::*;
2486
2487 #[test]
2488 fn sinh_valid() {
2489 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2490 let expected = Complex::new(-0.4890562590412937, -1.4031192506220405);
2491 assert_eq!(v.try_sinh().unwrap().as_ref(), &expected);
2492 assert_eq!(v.sinh().as_ref(), &expected);
2493 }
2494
2495 #[test]
2496 fn cosh_valid() {
2497 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2498 let expected = Complex::new(-0.64214812471552, -1.0686074213827783);
2499 assert_eq!(v.try_cosh().unwrap().as_ref(), &expected);
2500 assert_eq!(v.cosh().as_ref(), &expected);
2501 }
2502
2503 #[test]
2504 fn tanh_valid() {
2505 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2506 let expected = if cfg!(target_arch = "x86_64") {
2507 Complex::new(1.16673625724092, 0.24345820118572523)
2508 } else if cfg!(target_arch = "aarch64") {
2509 Complex::new(1.16673625724092, 0.24345820118572528)
2510 } else {
2511 todo!("Architecture not-tested");
2512 };
2513 assert_eq!(v.try_tanh().unwrap().as_ref(), &expected);
2514 assert_eq!(v.tanh().as_ref(), &expected);
2515 }
2516
2517 #[test]
2518 fn asinh_valid() {
2519 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2520 let expected = Complex::new(1.4693517443681852, -1.0634400235777521);
2521 Complex::new(1.4693517443681852, -1.0634400235777521);
2522 assert_eq!(v.try_asinh().unwrap().as_ref(), &expected);
2523 assert_eq!(v.asinh().as_ref(), &expected);
2524 }
2525
2526 #[test]
2527 fn acosh_valid() {
2528 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2529 let expected = Complex::new(1.528570919480998, -1.1437177404024206);
2530 assert_eq!(v.try_acosh().unwrap().as_ref(), &expected);
2531 assert_eq!(v.acosh().as_ref(), &expected);
2532 }
2533
2534 #[test]
2535 fn atanh_valid() {
2536 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2537 let expected = Complex::new(0.1732867951399864, -1.1780972450961724);
2538 assert_eq!(v.try_atanh().unwrap().as_ref(), &expected);
2539 assert_eq!(v.atanh().as_ref(), &expected);
2540 }
2541
2542 #[test]
2559 fn acosh_out_of_domain() {
2560 let val_on_branch_cut = ComplexValidated::try_new_pure_real(0.5).unwrap();
2562 assert!(matches!(
2563 val_on_branch_cut.try_acosh(),
2564 Err(ACosHErrors::Input(ACosHInputErrors::OutOfDomain { .. }))
2565 ));
2566
2567 let val_on_branch_cut_neg = ComplexValidated::try_new_pure_real(-5.).unwrap();
2568 assert!(matches!(
2569 val_on_branch_cut_neg.try_acosh(),
2570 Err(ACosHErrors::Input(ACosHInputErrors::OutOfDomain { .. }))
2571 ));
2572 }
2573
2574 #[test]
2575 fn atanh_out_of_domain() {
2576 let val_ge_1 = ComplexValidated::try_new_pure_real(1.).unwrap();
2577 assert!(matches!(
2578 val_ge_1.try_atanh(),
2579 Err(ATanHErrors::Input(ATanHInputErrors::OutOfDomain { .. }))
2580 ));
2581
2582 let val_le_neg1 = ComplexValidated::try_new_pure_real(-1.).unwrap();
2583 assert!(matches!(
2584 val_le_neg1.try_atanh(),
2585 Err(ATanHErrors::Input(ATanHInputErrors::OutOfDomain { .. }))
2586 ));
2587 }
2588 }
2589
2590 } }
2606
2607 mod summation {
2608 use super::*;
2609
2610 #[test]
2611 fn sum_real() {
2612 let values = vec![
2613 RealValidated::try_new(1.0).unwrap(),
2614 RealValidated::try_new(2.0).unwrap(),
2615 RealValidated::try_new(3.0).unwrap(),
2616 RealValidated::try_new(4.0).unwrap(),
2617 RealValidated::try_new(5.0).unwrap(),
2618 ];
2619 let sum: RealValidated = values.into_iter().sum();
2620 assert_eq!(sum, RealValidated::try_new(15.0).unwrap());
2621 }
2622
2623 #[test]
2624 fn sum_real_compensated() {
2625 let values = vec![
2627 RealValidated::try_new(1.0e100).unwrap(),
2628 RealValidated::try_new(1.0).unwrap(),
2629 RealValidated::try_new(-1.0e100).unwrap(),
2630 ];
2631 let sum: RealValidated = values.into_iter().sum();
2632 assert_eq!(sum, RealValidated::try_new(1.0).unwrap());
2634 }
2635
2636 #[test]
2637 fn sum_complex() {
2638 let values = vec![
2639 ComplexValidated::try_new(Complex::new(1.0, 2.0)).unwrap(),
2640 ComplexValidated::try_new(Complex::new(3.0, 4.0)).unwrap(),
2641 ComplexValidated::try_new(Complex::new(5.0, 6.0)).unwrap(),
2642 ];
2643 let sum: ComplexValidated = values.into_iter().sum();
2644 assert_eq!(
2645 sum,
2646 ComplexValidated::try_new(Complex::new(9.0, 12.0)).unwrap()
2647 );
2648 }
2649
2650 #[test]
2651 fn sum_complex_compensated() {
2652 let values = vec![
2653 ComplexValidated::try_new(Complex::new(1.0e100, -1.0e100)).unwrap(),
2654 ComplexValidated::try_new(Complex::new(1.0, 2.0)).unwrap(),
2655 ComplexValidated::try_new(Complex::new(-1.0e100, 1.0e100)).unwrap(),
2656 ];
2657 let sum: ComplexValidated = values.into_iter().sum();
2658 assert_eq!(
2659 sum,
2660 ComplexValidated::try_new(Complex::new(1.0, 2.0)).unwrap()
2661 );
2662 }
2663 } mod neumaier_sum {
2666 use crate::algorithms::accumulators::{Accumulator, NeumaierSum};
2667 use try_create::TryNewValidated;
2668
2669 use super::*;
2670
2671 mod real {
2672 use super::*;
2673
2674 #[test]
2675 fn new() {
2676 let neumaier = NeumaierSum::<RealValidated>::new();
2677 assert_eq!(neumaier.sum_before_compensation().as_ref(), &0.0);
2678 assert_eq!(neumaier.compensation().as_ref(), &0.0);
2679 }
2680
2681 #[test]
2682 fn add() {
2683 let mut neumaier = NeumaierSum::new();
2684 neumaier.push(RealValidated::try_new_validated(1.0).unwrap());
2685 neumaier.push(RealValidated::try_new_validated(1e-16).unwrap());
2686 neumaier.push(RealValidated::try_new_validated(-1.0).unwrap());
2687 assert_eq!(neumaier.sum_before_compensation().as_ref(), &0.0);
2688 assert_eq!(neumaier.compensation().as_ref(), &1e-16);
2689 }
2690
2691 #[test]
2692 fn sum() {
2693 let mut neumaier = NeumaierSum::new();
2694 neumaier.push(RealValidated::try_new_validated(1.0).unwrap());
2695 neumaier.push(RealValidated::try_new_validated(1e-16).unwrap());
2696 neumaier.push(RealValidated::try_new_validated(-1.0).unwrap());
2697 assert_eq!(neumaier.sum_before_compensation().as_ref(), &0.0);
2698 assert_eq!(neumaier.compensation().as_ref(), &1e-16);
2699 let sum = neumaier.result();
2700 assert_eq!(sum.as_ref(), &1e-16);
2701 println!("compensated sum = {}", sum);
2702 }
2703
2704 #[test]
2705 fn sum_big_values() {
2706 let values = [1.0, 1e100, 1.0, -1e100]
2707 .iter()
2708 .map(|&v| RealValidated::try_new_validated(v).unwrap())
2709 .collect::<Vec<_>>();
2710 let sum = values.iter().cloned().sum::<RealValidated>();
2711 assert_eq!(sum.as_ref(), &2.0);
2712
2713 let neumaier = NeumaierSum::new_sequential(values);
2714 let sum = neumaier.result();
2715 assert_eq!(sum.as_ref(), &2.0);
2716 println!("compensated sum = {}", sum);
2717 }
2718
2719 #[test]
2720 fn sum_small_values() {
2721 let values = [1.0, 1e-100, -1.0]
2722 .iter()
2723 .map(|&v| RealValidated::try_new_validated(v).unwrap())
2724 .collect::<Vec<_>>();
2725 let sum = values.iter().cloned().sum::<RealValidated>();
2726 assert_eq!(sum.as_ref(), &1e-100);
2727
2728 let neumaier = NeumaierSum::new_sequential(values);
2729 let sum = neumaier.result();
2730 assert_eq!(sum.as_ref(), &1e-100);
2731 println!("compensated sum = {}", sum);
2732 }
2733 }
2734
2735 mod complex {
2736 use super::*;
2737
2738 #[test]
2739 fn new() {
2740 let neumaier = NeumaierSum::<ComplexValidated>::new();
2741
2742 let zero = Complex::new(0.0, 0.0);
2743 assert_eq!(neumaier.sum_before_compensation().as_ref(), &zero);
2744 assert_eq!(neumaier.compensation().as_ref(), &zero);
2745 }
2746
2747 #[test]
2748 fn add() {
2749 let zero = Complex::new(0.0, 0.0);
2750 let v = Complex::new(1e-16, 2e-16);
2751
2752 let mut neumaier = NeumaierSum::new();
2753 neumaier.push(ComplexValidated::try_new_validated(Complex::new(1.0, 2.0)).unwrap());
2754 neumaier.push(ComplexValidated::try_new_validated(v).unwrap());
2755 neumaier
2756 .push(ComplexValidated::try_new_validated(Complex::new(-1.0, -2.0)).unwrap());
2757
2758 assert_eq!(neumaier.sum_before_compensation().as_ref(), &zero);
2759 assert_eq!(neumaier.compensation().as_ref(), &v);
2760 }
2761
2762 #[test]
2763 fn sum() {
2764 let zero = Complex::new(0.0, 0.0);
2765 let v = Complex::new(1e-16, 2e-16);
2766
2767 let mut neumaier = NeumaierSum::new();
2768 neumaier.push(ComplexValidated::try_new_validated(Complex::new(1.0, 2.0)).unwrap());
2769 neumaier.push(ComplexValidated::try_new_validated(v).unwrap());
2770 neumaier
2771 .push(ComplexValidated::try_new_validated(Complex::new(-1.0, -2.0)).unwrap());
2772 assert_eq!(neumaier.sum_before_compensation().as_ref(), &zero);
2773 assert_eq!(neumaier.compensation().as_ref(), &v);
2774 let sum = neumaier.result();
2775 assert_eq!(sum.as_ref(), &v);
2776 println!("compensated sum = {}", sum);
2777 }
2778
2779 #[test]
2780 fn sum_big_values() {
2781 let values = [
2782 Complex::new(1.0, 2.0),
2783 Complex::new(1e100, 2e100),
2784 Complex::new(1.0, 2.0),
2785 Complex::new(-1e100, -2e100),
2786 ]
2787 .iter()
2788 .map(|&v| ComplexValidated::try_new_validated(v).unwrap())
2789 .collect::<Vec<_>>();
2790 let sum = values.clone().into_iter().sum::<ComplexValidated>();
2791 let expected_sum = Complex::new(2., 4.);
2792 assert_eq!(sum.as_ref(), &expected_sum);
2793
2794 let neumaier = NeumaierSum::new_sequential(values);
2795 let sum = neumaier.result();
2796 assert_eq!(sum.as_ref(), &expected_sum);
2797 println!("compensated sum = {}", sum);
2798 }
2799
2800 #[test]
2801 fn sum_small_values() {
2802 let v = Complex::new(1e-100, 2e-100);
2803
2804 let values = [Complex::new(1.0, 2.0), v, Complex::new(-1.0, -2.0)]
2805 .iter()
2806 .map(|&v| ComplexValidated::try_new_validated(v).unwrap())
2807 .collect::<Vec<_>>();
2808 let sum = values.iter().cloned().sum::<ComplexValidated>();
2809 let sum_expected = v;
2810 assert_eq!(sum.as_ref(), &sum_expected);
2811
2812 let neumaier = NeumaierSum::new_sequential(values);
2813 let sum = neumaier.result();
2814 assert_eq!(sum.as_ref(), &sum_expected);
2815 println!("compensated sum = {}", sum);
2816 }
2817 }
2818 }
2819
2820 mod random {
2821 use super::*;
2822 use super::{ComplexNative64StrictFinite, RealNative64StrictFinite};
2823 use crate::{RandomSampleFromF64, new_random_vec};
2824 use rand::{SeedableRng, distr::Uniform, rngs::StdRng};
2825
2826 #[test]
2830 fn test_random_real_validated() {
2831 let seed = [42; 32];
2832 let mut rng = StdRng::from_seed(seed);
2833
2834 let random_real: RealNative64StrictFinite = rng.random();
2835
2836 assert_eq!(random_real.as_ref(), &0.23713468825474326);
2838
2839 let mut rng2 = StdRng::from_seed(seed);
2841 let random_real2: RealNative64StrictFinite = rng2.random();
2842 assert_eq!(random_real, random_real2);
2843 }
2844
2845 #[test]
2850 fn test_random_complex_validated() {
2851 let seed = [99; 32];
2852 let mut rng = StdRng::from_seed(seed);
2853
2854 let random_complex: ComplexNative64StrictFinite = rng.random();
2855
2856 let real_part = random_complex.real_part();
2859 let imag_part = random_complex.imag_part();
2860
2861 assert_eq!(real_part.as_ref(), &0.9995546882627792);
2862 assert_eq!(imag_part.as_ref(), &0.08932180682540247);
2863
2864 let mut rng2 = StdRng::from_seed(seed);
2866 let random_complex2: ComplexNative64StrictFinite = rng2.random();
2867 assert_eq!(random_complex, random_complex2);
2868 }
2869
2870 const SEED: [u8; 32] = [42; 32];
2871
2872 #[test]
2873 fn test_sample_real_validated() {
2874 let mut rng = StdRng::from_seed(SEED);
2875 let dist = Uniform::new(-10.0, 10.0).unwrap();
2876
2877 let val = RealNative64StrictFinite::sample_from(&dist, &mut rng);
2878 assert_eq!(val.as_ref(), &-5.257306234905137);
2879
2880 let mut rng2 = StdRng::from_seed(SEED);
2882 let val2 = RealNative64StrictFinite::sample_from(&dist, &mut rng2);
2883 assert_eq!(val, val2);
2884 }
2885
2886 #[test]
2887 fn test_sample_complex_validated() {
2888 let mut rng = StdRng::from_seed(SEED);
2889 let dist = Uniform::new(-10.0, 10.0).unwrap();
2890
2891 let val = ComplexNative64StrictFinite::sample_from(&dist, &mut rng);
2892 assert_eq!(val.real_part().as_ref(), &-5.257306234905137);
2893 assert_eq!(val.imag_part().as_ref(), &7.212119776268775);
2894
2895 let mut rng2 = StdRng::from_seed(SEED);
2897 let val2 = ComplexNative64StrictFinite::sample_from(&dist, &mut rng2);
2898 assert_eq!(val, val2);
2899 }
2900
2901 #[test]
2902 fn new_random_vec_real() {
2903 let mut rng = StdRng::from_seed(SEED);
2904 let dist = Uniform::new(-10.0, 10.0).unwrap();
2905 let vec: Vec<RealNative64StrictFinite> = new_random_vec(3, &dist, &mut rng);
2906 assert_eq!(vec.len(), 3);
2907 assert_eq!(vec[0].as_ref(), &-5.257306234905137);
2908 assert_eq!(vec[1].as_ref(), &7.212119776268775);
2909 assert_eq!(vec[2].as_ref(), &-4.666248990558111);
2910
2911 let mut rng2 = StdRng::from_seed(SEED);
2913 let vec2: Vec<RealNative64StrictFinite> = new_random_vec(3, &dist, &mut rng2);
2914 assert_eq!(vec, vec2);
2915 }
2916
2917 #[test]
2918 fn new_random_vec_complex() {
2919 let mut rng = StdRng::from_seed(SEED);
2920 let dist = Uniform::new(-10.0, 10.0).unwrap();
2921 let vec: Vec<ComplexNative64StrictFinite> = new_random_vec(3, &dist, &mut rng);
2922 assert_eq!(vec.len(), 3);
2923 assert_eq!(vec[0].real_part().as_ref(), &-5.257306234905137);
2924 assert_eq!(vec[0].imag_part().as_ref(), &7.212119776268775);
2925 assert_eq!(vec[1].real_part().as_ref(), &-4.666248990558111);
2926 assert_eq!(vec[1].imag_part().as_ref(), &9.66047141517383);
2927 assert_eq!(vec[2].real_part().as_ref(), &-9.04279551029691);
2928 assert_eq!(vec[2].imag_part().as_ref(), &-1.026624649331671);
2929
2930 let mut rng2 = StdRng::from_seed(SEED);
2932 let vec2: Vec<ComplexNative64StrictFinite> = new_random_vec(3, &dist, &mut rng2);
2933 assert_eq!(vec, vec2);
2934 }
2935 }
2936
2937 mod hash_map_key_usage {
2938 use crate::{
2939 backends::native::validated::{
2940 ComplexNative64StrictFinite, RealNative64StrictFinite,
2941 RealNative64StrictFiniteInDebug,
2942 },
2943 functions::Sign,
2944 };
2945 use num::Complex;
2946 use std::collections::HashMap;
2947 use try_create::TryNew;
2948
2949 #[test]
2950 fn test_native64_as_hashmap_key() {
2951 let mut map = HashMap::new();
2952 let key1 = RealNative64StrictFinite::try_new(1.0).unwrap();
2953 let key2 = RealNative64StrictFinite::try_new(2.5).unwrap();
2954
2955 map.insert(key1, "one");
2956 map.insert(key2, "two_point_five");
2957
2958 assert_eq!(
2959 map.get(&RealNative64StrictFinite::try_new(1.0).unwrap()),
2960 Some(&"one")
2961 );
2962 assert_eq!(map.len(), 2);
2963
2964 let old_value = map.insert(key1, "new_one");
2966 assert_eq!(old_value, Some("one"));
2967 assert_eq!(map.get(&key1), Some(&"new_one"));
2968 }
2969
2970 #[test]
2971 fn test_native64_debug_as_hashmap_key() {
2972 let mut map = HashMap::new();
2973 let key1 = RealNative64StrictFiniteInDebug::try_new(1.0).unwrap();
2974 let key2 = RealNative64StrictFiniteInDebug::try_new(2.5).unwrap();
2975
2976 map.insert(key1, "one_debug");
2977 map.insert(key2, "two_point_five_debug");
2978
2979 assert_eq!(
2980 map.get(&RealNative64StrictFiniteInDebug::try_new(1.0).unwrap()),
2981 Some(&"one_debug")
2982 );
2983 assert_eq!(map.len(), 2);
2984
2985 let old_value = map.insert(key1, "new_one_debug");
2987 assert_eq!(old_value, Some("one_debug"));
2988 assert_eq!(map.get(&key1), Some(&"new_one_debug"));
2989 }
2990
2991 #[test]
2992 fn test_hashmap_basic_operations() {
2993 let mut map = HashMap::new();
2994 let key1 = RealNative64StrictFinite::try_new(1.0).unwrap();
2995 let key2 = RealNative64StrictFinite::try_new(2.5).unwrap();
2996 let key3 = RealNative64StrictFinite::try_new(1.0).unwrap(); assert_eq!(map.insert(key1, "one"), None);
3000 assert_eq!(map.insert(key2, "two_point_five"), None);
3001 assert_eq!(map.len(), 2);
3002
3003 assert_eq!(map.get(&key3), Some(&"one"));
3005
3006 assert_eq!(map.insert(key3, "one_updated"), Some("one"));
3008 assert_eq!(map.len(), 2); }
3010
3011 #[test]
3012 fn test_hashset_operations() {
3013 use std::collections::HashSet;
3014 let mut set = HashSet::new();
3015
3016 let val1 = RealNative64StrictFinite::try_new(1.0).unwrap();
3017 let val2 = RealNative64StrictFinite::try_new(2.0).unwrap();
3018 let val1_duplicate = RealNative64StrictFinite::try_new(1.0).unwrap();
3019
3020 assert!(set.insert(val1));
3021 assert!(set.insert(val2));
3022 assert!(!set.insert(val1_duplicate)); assert_eq!(set.len(), 2);
3025 assert!(set.contains(&RealNative64StrictFinite::try_new(1.0).unwrap()));
3026 }
3027
3028 #[test]
3029 fn test_hash_consistency() {
3030 use std::collections::hash_map::DefaultHasher;
3031 use std::hash::{Hash, Hasher};
3032
3033 let val1 = RealNative64StrictFinite::try_new(1.234).unwrap();
3034 let val2 = RealNative64StrictFinite::try_new(1.234).unwrap();
3035
3036 let mut hasher1 = DefaultHasher::new();
3038 let mut hasher2 = DefaultHasher::new();
3039
3040 val1.hash(&mut hasher1);
3041 val2.hash(&mut hasher2);
3042
3043 assert_eq!(hasher1.finish(), hasher2.finish());
3044 assert_eq!(val1, val2); }
3046
3047 #[test]
3048 fn test_hash_signed_zero() {
3049 use std::collections::hash_map::DefaultHasher;
3050 use std::hash::{Hash, Hasher};
3051
3052 let val1 = RealNative64StrictFinite::try_new(0.0).unwrap();
3053 assert!(val1.kernel_is_sign_positive());
3054 let val2 = RealNative64StrictFinite::try_new(-0.0).unwrap();
3055 assert!(val2.kernel_is_sign_negative());
3056
3057 assert_ne!(
3059 0.0f64.to_bits(),
3060 (-0.0f64).to_bits(),
3061 "Sanity check: +0.0 and -0.0 should have different bit patterns"
3062 );
3063
3064 assert_eq!(val1, val2); let mut hasher1 = DefaultHasher::new();
3068 let mut hasher2 = DefaultHasher::new();
3069
3070 val1.hash(&mut hasher1);
3071 val2.hash(&mut hasher2);
3072
3073 assert_eq!(hasher1.finish(), hasher2.finish());
3074 }
3075
3076 #[test]
3077 fn test_complex_as_hashmap_key() {
3078 let mut map = HashMap::new();
3079 let key1 = ComplexNative64StrictFinite::try_new(Complex::new(1.0, 2.0)).unwrap();
3080 let key2 = ComplexNative64StrictFinite::try_new(Complex::new(3.0, 4.0)).unwrap();
3081
3082 map.insert(key1, "one_plus_two_i");
3083 map.insert(key2, "three_plus_four_i");
3084
3085 assert_eq!(
3086 map.get(&ComplexNative64StrictFinite::try_new(Complex::new(1.0, 2.0)).unwrap()),
3087 Some(&"one_plus_two_i")
3088 );
3089 assert_eq!(map.len(), 2);
3090
3091 let old_value = map.insert(key1, "updated_complex");
3093 assert_eq!(old_value, Some("one_plus_two_i"));
3094 assert_eq!(map.get(&key1), Some(&"updated_complex"));
3095 }
3096
3097 #[test]
3098 fn test_complex_hash_consistency() {
3099 use std::collections::hash_map::DefaultHasher;
3100 use std::hash::{Hash, Hasher};
3101
3102 let val1 = ComplexNative64StrictFinite::try_new(Complex::new(1.234, 5.678)).unwrap();
3103 let val2 = ComplexNative64StrictFinite::try_new(Complex::new(1.234, 5.678)).unwrap();
3104
3105 let mut hasher1 = DefaultHasher::new();
3107 let mut hasher2 = DefaultHasher::new();
3108
3109 val1.hash(&mut hasher1);
3110 val2.hash(&mut hasher2);
3111
3112 assert_eq!(hasher1.finish(), hasher2.finish());
3113 assert_eq!(val1, val2); }
3115
3116 #[test]
3117 fn test_complex_hash_signed_zero() {
3118 use std::collections::hash_map::DefaultHasher;
3119 use std::hash::{Hash, Hasher};
3120
3121 let val1 = ComplexNative64StrictFinite::try_new(Complex::new(0.0, 0.0)).unwrap();
3123 let val2 = ComplexNative64StrictFinite::try_new(Complex::new(-0.0, 0.0)).unwrap();
3124 let val3 = ComplexNative64StrictFinite::try_new(Complex::new(0.0, -0.0)).unwrap();
3125 let val4 = ComplexNative64StrictFinite::try_new(Complex::new(-0.0, -0.0)).unwrap();
3126
3127 assert_eq!(val1, val2);
3129 assert_eq!(val1, val3);
3130 assert_eq!(val1, val4);
3131
3132 let mut hasher1 = DefaultHasher::new();
3134 let mut hasher2 = DefaultHasher::new();
3135 let mut hasher3 = DefaultHasher::new();
3136 let mut hasher4 = DefaultHasher::new();
3137
3138 val1.hash(&mut hasher1);
3139 val2.hash(&mut hasher2);
3140 val3.hash(&mut hasher3);
3141 val4.hash(&mut hasher4);
3142
3143 let hash1 = hasher1.finish();
3144 let hash2 = hasher2.finish();
3145 let hash3 = hasher3.finish();
3146 let hash4 = hasher4.finish();
3147
3148 assert_eq!(hash1, hash2);
3149 assert_eq!(hash1, hash3);
3150 assert_eq!(hash1, hash4);
3151 }
3152
3153 #[test]
3154 fn test_complex_different_values_different_hashes() {
3155 use std::collections::hash_map::DefaultHasher;
3156 use std::hash::{Hash, Hasher};
3157
3158 let val1 = ComplexNative64StrictFinite::try_new(Complex::new(1.0, 2.0)).unwrap();
3159 let val2 = ComplexNative64StrictFinite::try_new(Complex::new(2.0, 1.0)).unwrap();
3160 let val3 = ComplexNative64StrictFinite::try_new(Complex::new(1.0, 2.001)).unwrap();
3161
3162 let mut hasher1 = DefaultHasher::new();
3164 let mut hasher2 = DefaultHasher::new();
3165 let mut hasher3 = DefaultHasher::new();
3166
3167 val1.hash(&mut hasher1);
3168 val2.hash(&mut hasher2);
3169 val3.hash(&mut hasher3);
3170
3171 let hash1 = hasher1.finish();
3172 let hash2 = hasher2.finish();
3173 let hash3 = hasher3.finish();
3174
3175 assert_ne!(val1, val2);
3177 assert_ne!(val1, val3);
3178 assert_ne!(hash1, hash2);
3179 assert_ne!(hash1, hash3);
3180 }
3181
3182 #[test]
3183 fn test_complex_hashset_operations() {
3184 use std::collections::HashSet;
3185
3186 let mut set = HashSet::new();
3187
3188 let val1 = ComplexNative64StrictFinite::try_new(Complex::new(1.0, 2.0)).unwrap();
3189 let val2 = ComplexNative64StrictFinite::try_new(Complex::new(3.0, 4.0)).unwrap();
3190 let val1_duplicate =
3191 ComplexNative64StrictFinite::try_new(Complex::new(1.0, 2.0)).unwrap();
3192
3193 assert!(set.insert(val1));
3194 assert!(set.insert(val2));
3195 assert!(!set.insert(val1_duplicate)); assert_eq!(set.len(), 2);
3198 assert!(
3199 set.contains(
3200 &ComplexNative64StrictFinite::try_new(Complex::new(1.0, 2.0)).unwrap()
3201 )
3202 );
3203 }
3204 }
3205
3206 mod test_truncate_to_usize {
3207 use super::*;
3208 use crate::core::errors::ErrorsRawRealToInteger;
3209
3210 #[test]
3211 fn test_positive_integers() {
3212 let value = RealNative64StrictFinite::try_new(42.0).unwrap();
3214 assert_eq!(value.truncate_to_usize().unwrap(), 42);
3215
3216 let value = RealNative64StrictFinite::try_new(1.0).unwrap();
3217 assert_eq!(value.truncate_to_usize().unwrap(), 1);
3218
3219 let value = RealNative64StrictFinite::try_new(100.0).unwrap();
3220 assert_eq!(value.truncate_to_usize().unwrap(), 100);
3221 }
3222
3223 #[test]
3224 fn test_positive_fractionals_truncate() {
3225 let value = RealNative64StrictFinite::try_new(42.9).unwrap();
3227 assert_eq!(value.truncate_to_usize().unwrap(), 42);
3228
3229 let value = RealNative64StrictFinite::try_new(3.7).unwrap();
3230 assert_eq!(value.truncate_to_usize().unwrap(), 3);
3231
3232 let value = RealNative64StrictFinite::try_new(0.9).unwrap();
3233 assert_eq!(value.truncate_to_usize().unwrap(), 0);
3234
3235 let value = RealNative64StrictFinite::try_new(99.999).unwrap();
3236 assert_eq!(value.truncate_to_usize().unwrap(), 99);
3237 }
3238
3239 #[test]
3240 fn test_zero_cases() {
3241 let value = RealNative64StrictFinite::try_new(0.0).unwrap();
3243 assert_eq!(value.truncate_to_usize().unwrap(), 0);
3244
3245 let value = RealNative64StrictFinite::try_new(0.1).unwrap();
3247 assert_eq!(value.truncate_to_usize().unwrap(), 0);
3248
3249 let value = RealNative64StrictFinite::try_new(0.5).unwrap();
3250 assert_eq!(value.truncate_to_usize().unwrap(), 0);
3251 }
3252
3253 #[test]
3254 fn test_large_valid_values() {
3255 let value = RealNative64StrictFinite::try_new(1_000_000.7).unwrap();
3257 assert_eq!(value.truncate_to_usize().unwrap(), 1_000_000);
3258
3259 let value = RealNative64StrictFinite::try_new(1_000_000_000.0).unwrap();
3260 assert_eq!(value.truncate_to_usize().unwrap(), 1_000_000_000);
3261
3262 let max_safe = (usize::MAX as f64) - 2048.0; let value = RealNative64StrictFinite::try_new(max_safe).unwrap();
3265 let result = value.truncate_to_usize().unwrap();
3266 assert!(result < usize::MAX);
3267 }
3268
3269 #[test]
3270 fn test_negative_values_error() {
3271 let value = RealNative64StrictFinite::try_new(-1.0).unwrap();
3273 let result = value.truncate_to_usize();
3274 assert!(matches!(
3275 result,
3276 Err(ErrorsRawRealToInteger::OutOfRange { .. })
3277 ));
3278
3279 let value = RealNative64StrictFinite::try_new(-10.5).unwrap();
3280 let result = value.truncate_to_usize();
3281 assert!(matches!(
3282 result,
3283 Err(ErrorsRawRealToInteger::OutOfRange { .. })
3284 ));
3285
3286 let value = RealNative64StrictFinite::try_new(-0.1).unwrap();
3287 let result = value.truncate_to_usize();
3288 assert!(matches!(result, Ok(0)));
3289
3290 let value = RealNative64StrictFinite::try_new(-1000.0).unwrap();
3291 let result = value.truncate_to_usize();
3292 assert!(matches!(
3293 result,
3294 Err(ErrorsRawRealToInteger::OutOfRange { .. })
3295 ));
3296 }
3297
3298 #[test]
3299 fn test_too_large_values_error() {
3300 let too_large = (usize::MAX as f64) * 2.0;
3302 let value = RealNative64StrictFinite::try_new(too_large).unwrap();
3303 let result = value.truncate_to_usize();
3304 assert!(matches!(
3305 result,
3306 Err(ErrorsRawRealToInteger::OutOfRange { .. })
3307 ));
3308
3309 let value = RealNative64StrictFinite::try_new(1e20).unwrap();
3310 let result = value.truncate_to_usize();
3311 assert!(matches!(
3312 result,
3313 Err(ErrorsRawRealToInteger::OutOfRange { .. })
3314 ));
3315 }
3316
3317 #[test]
3318 fn test_edge_cases() {
3319 let value = RealNative64StrictFinite::try_new(f64::EPSILON).unwrap();
3323 assert_eq!(value.truncate_to_usize().unwrap(), 0);
3324
3325 let value = RealNative64StrictFinite::try_new(1.0 - f64::EPSILON).unwrap();
3327 assert_eq!(value.truncate_to_usize().unwrap(), 0);
3328
3329 let value = RealNative64StrictFinite::try_new(1.0 + f64::EPSILON).unwrap();
3331 assert_eq!(value.truncate_to_usize().unwrap(), 1);
3332 }
3333
3334 #[test]
3335 fn test_truncation_behavior() {
3336 let test_cases = [
3338 (2.1, 2),
3339 (2.5, 2), (2.9, 2),
3341 (3.0, 3),
3342 (3.1, 3),
3343 (99.999, 99),
3344 ];
3345
3346 for (input, expected) in test_cases {
3347 let value = RealNative64StrictFinite::try_new(input)
3348 .unwrap()
3349 .truncate_to_usize()
3350 .unwrap();
3351 assert_eq!(
3352 value, expected,
3353 "Failed for input {}: expected {}, got {:?}",
3354 input, expected, value
3355 );
3356 }
3357 }
3358
3359 #[test]
3360 fn test_error_details() {
3361 let value = RealNative64StrictFinite::try_new(-5.0).unwrap();
3365 if let Err(ErrorsRawRealToInteger::OutOfRange {
3366 value: err_val,
3367 min,
3368 max,
3369 ..
3370 }) = value.truncate_to_usize()
3371 {
3372 assert_eq!(err_val, -5.0);
3373 assert_eq!(min, usize::MIN);
3374 assert_eq!(max, usize::MAX);
3375 } else {
3376 panic!("Expected OutOfRange error for negative value");
3377 }
3378
3379 let large_value = 1e20;
3381 let value = RealNative64StrictFinite::try_new(large_value).unwrap();
3382 if let Err(ErrorsRawRealToInteger::OutOfRange {
3383 value: err_val,
3384 min,
3385 max,
3386 ..
3387 }) = value.truncate_to_usize()
3388 {
3389 assert_eq!(err_val, large_value);
3390 assert_eq!(min, usize::MIN);
3391 assert_eq!(max, usize::MAX);
3392 } else {
3393 panic!("Expected OutOfRange error for large value");
3394 }
3395 }
3396
3397 #[test]
3398 fn test_practical_usage_scenario() {
3399 fn create_vector_with_calculated_size<T: Default + Clone>(
3401 size_float: RealNative64StrictFinite,
3402 ) -> Result<Vec<T>, Box<dyn std::error::Error>> {
3403 let size = size_float.truncate_to_usize()?;
3404 Ok(vec![T::default(); size])
3405 }
3406
3407 let calculated_size = RealNative64StrictFinite::try_new(10.7).unwrap();
3409 let vec: Vec<i32> = create_vector_with_calculated_size(calculated_size).unwrap();
3410 assert_eq!(vec.len(), 10); let negative_size = RealNative64StrictFinite::try_new(-5.0).unwrap();
3414 let result: Result<Vec<i32>, _> = create_vector_with_calculated_size(negative_size);
3415 assert!(result.is_err());
3416
3417 let huge_size = RealNative64StrictFinite::try_new(1e20).unwrap();
3419 let result: Result<Vec<i32>, _> = create_vector_with_calculated_size(huge_size);
3420 assert!(result.is_err());
3421 }
3422
3423 #[test]
3424 fn test_consistency_with_f64_behavior() {
3425 let test_values = [0.0, 1.0, 2.5, 42.9, 100.0, 0.1, 0.9];
3427
3428 for &val in &test_values {
3429 let validated = RealNative64StrictFinite::try_new(val).unwrap();
3430 let result = validated.truncate_to_usize().unwrap();
3431
3432 let expected = val.trunc() as usize;
3434 assert_eq!(result, expected, "Mismatch for value {}", val);
3435 }
3436 }
3437 }
3438
3439 mod bytemuck_conversions {
3440 use super::*;
3441 use bytemuck::checked::{CheckedCastError, try_from_bytes};
3442
3443 mod real_strict_finite {
3444 use super::*;
3445
3446 #[test]
3447 fn valid_value_from_bytes() {
3448 let value = 42.0_f64;
3449 let bytes = value.to_ne_bytes();
3450
3451 let result: Result<&RealNative64StrictFinite, CheckedCastError> =
3452 try_from_bytes(&bytes);
3453 assert!(result.is_ok());
3454 assert_eq!(*result.unwrap().as_ref(), 42.0);
3455 }
3456
3457 #[test]
3458 fn valid_value_try_cast() {
3459 let value = 42.0_f64;
3460 let bytes = value.to_ne_bytes();
3461 let result: Result<&RealNative64StrictFinite, CheckedCastError> =
3462 try_from_bytes(&bytes);
3463 assert!(result.is_ok());
3464 assert_eq!(*result.unwrap().as_ref(), 42.0);
3465 }
3466
3467 #[test]
3468 fn zero_from_bytes() {
3469 let value = 0.0_f64;
3470 let bytes = value.to_ne_bytes();
3471
3472 let result: Result<&RealNative64StrictFinite, CheckedCastError> =
3473 try_from_bytes(&bytes);
3474 assert!(result.is_ok());
3475 assert_eq!(*result.unwrap().as_ref(), 0.0);
3476 }
3477
3478 #[test]
3479 fn negative_zero_from_bytes() {
3480 let value = -0.0_f64;
3481 let bytes = value.to_ne_bytes();
3482
3483 let result: Result<&RealNative64StrictFinite, CheckedCastError> =
3484 try_from_bytes(&bytes);
3485 assert!(result.is_ok());
3486 assert_eq!(*result.unwrap().as_ref(), -0.0);
3487 }
3488
3489 #[test]
3490 fn max_value_from_bytes() {
3491 let value = f64::MAX;
3492 let bytes = value.to_ne_bytes();
3493
3494 let result: Result<&RealNative64StrictFinite, CheckedCastError> =
3495 try_from_bytes(&bytes);
3496 assert!(result.is_ok());
3497 assert_eq!(*result.unwrap().as_ref(), f64::MAX);
3498 }
3499
3500 #[test]
3501 fn min_value_from_bytes() {
3502 let value = f64::MIN;
3503 let bytes = value.to_ne_bytes();
3504
3505 let result: Result<&RealNative64StrictFinite, CheckedCastError> =
3506 try_from_bytes(&bytes);
3507 assert!(result.is_ok());
3508 assert_eq!(*result.unwrap().as_ref(), f64::MIN);
3509 }
3510
3511 #[test]
3512 fn nan_from_bytes_fails() {
3513 let value = f64::NAN;
3514 let bytes = value.to_ne_bytes();
3515
3516 let result: Result<&RealNative64StrictFinite, CheckedCastError> =
3517 try_from_bytes(&bytes);
3518 assert!(result.is_err());
3519 assert!(matches!(result, Err(CheckedCastError::InvalidBitPattern)));
3520 }
3521
3522 #[test]
3523 fn nan_try_cast_fails() {
3524 let value = f64::NAN;
3525 let bytes = value.to_ne_bytes();
3526 let result: Result<&RealNative64StrictFinite, CheckedCastError> =
3527 try_from_bytes(&bytes);
3528 assert!(result.is_err());
3529 assert!(matches!(result, Err(CheckedCastError::InvalidBitPattern)));
3530 }
3531
3532 #[test]
3533 fn infinity_from_bytes_fails() {
3534 let value = f64::INFINITY;
3535 let bytes = value.to_ne_bytes();
3536
3537 let result: Result<&RealNative64StrictFinite, CheckedCastError> =
3538 try_from_bytes(&bytes);
3539 assert!(result.is_err());
3540 assert!(matches!(result, Err(CheckedCastError::InvalidBitPattern)));
3541 }
3542
3543 #[test]
3544 fn neg_infinity_from_bytes_fails() {
3545 let value = f64::NEG_INFINITY;
3546 let bytes = value.to_ne_bytes();
3547
3548 let result: Result<&RealNative64StrictFinite, CheckedCastError> =
3549 try_from_bytes(&bytes);
3550 assert!(result.is_err());
3551 assert!(matches!(result, Err(CheckedCastError::InvalidBitPattern)));
3552 }
3553
3554 #[test]
3555 fn subnormal_from_bytes_fails() {
3556 let value = f64::MIN_POSITIVE / 2.0; let bytes = value.to_ne_bytes();
3558
3559 let result: Result<&RealNative64StrictFinite, CheckedCastError> =
3560 try_from_bytes(&bytes);
3561 assert!(result.is_err());
3562 assert!(matches!(result, Err(CheckedCastError::InvalidBitPattern)));
3563 }
3564
3565 #[test]
3566 fn round_trip_conversion() {
3567 let original = RealNative64StrictFinite::try_new(123.456).unwrap();
3568 let as_f64 = *original.as_ref();
3569 let bytes = as_f64.to_ne_bytes();
3570
3571 let from_bytes: &RealNative64StrictFinite = try_from_bytes(&bytes).unwrap();
3572 assert_eq!(original, *from_bytes);
3573 }
3574
3575 #[test]
3576 fn vec_conversion() {
3577 let values = vec![
3578 RealNative64StrictFinite::try_new(1.0).unwrap(),
3579 RealNative64StrictFinite::try_new(2.0).unwrap(),
3580 RealNative64StrictFinite::try_new(3.0).unwrap(),
3581 RealNative64StrictFinite::try_new(4.0).unwrap(),
3582 ];
3583
3584 let bytes = bytemuck::cast_slice::<RealNative64StrictFinite, u8>(&values);
3586
3587 let result: Result<&[RealNative64StrictFinite], CheckedCastError> =
3589 bytemuck::checked::try_cast_slice(bytes);
3590 assert!(result.is_ok());
3591
3592 let validated_slice = result.unwrap();
3593 assert_eq!(validated_slice.len(), 4);
3594 assert_eq!(*validated_slice[0].as_ref(), 1.0);
3595 assert_eq!(*validated_slice[3].as_ref(), 4.0);
3596 }
3597
3598 #[test]
3599 fn direct_f64_slice_with_invalid_values() {
3600 let mut bytes = Vec::new();
3602 bytes.extend_from_slice(&1.0_f64.to_ne_bytes());
3603 bytes.extend_from_slice(&f64::NAN.to_ne_bytes());
3604 bytes.extend_from_slice(&3.0_f64.to_ne_bytes());
3605
3606 let result: Result<&[RealNative64StrictFinite], CheckedCastError> =
3608 bytemuck::checked::try_cast_slice(&bytes);
3609 assert!(result.is_err());
3610 }
3611 }
3612
3613 mod vec_conversions {
3614 use super::*;
3615 use try_create::TryNew;
3616
3617 #[test]
3618 fn vec_f64_to_validated_all_valid() {
3619 let f64_vec = [1.0, 2.5, -3.7, 0.0, 42.0];
3621
3622 let validated_vec: Result<Vec<RealNative64StrictFinite>, _> = f64_vec
3624 .iter()
3625 .map(|&x| RealNative64StrictFinite::try_new(x))
3626 .collect();
3627
3628 assert!(validated_vec.is_ok());
3629 let validated_vec = validated_vec.unwrap();
3630
3631 assert_eq!(validated_vec.len(), 5);
3633
3634 assert_eq!(*validated_vec[0].as_ref(), 1.0);
3636 assert_eq!(*validated_vec[1].as_ref(), 2.5);
3637 assert_eq!(*validated_vec[2].as_ref(), -3.7);
3638 assert_eq!(*validated_vec[3].as_ref(), 0.0);
3639 assert_eq!(*validated_vec[4].as_ref(), 42.0);
3640 }
3641
3642 #[test]
3643 fn vec_f64_to_validated_with_nan() {
3644 let f64_vec = [1.0, 2.5, f64::NAN, 0.0, 42.0];
3646
3647 let validated_vec: Result<Vec<RealNative64StrictFinite>, _> = f64_vec
3649 .iter()
3650 .map(|&x| RealNative64StrictFinite::try_new(x))
3651 .collect();
3652
3653 assert!(validated_vec.is_err());
3654 }
3655
3656 #[test]
3657 fn vec_f64_to_validated_with_infinity() {
3658 let f64_vec = [1.0, f64::INFINITY, 3.0];
3660
3661 let validated_vec: Result<Vec<RealNative64StrictFinite>, _> = f64_vec
3663 .iter()
3664 .map(|&x| RealNative64StrictFinite::try_new(x))
3665 .collect();
3666
3667 assert!(validated_vec.is_err());
3668 }
3669
3670 #[test]
3671 fn vec_f64_to_validated_with_subnormal() {
3672 let subnormal = f64::MIN_POSITIVE / 2.0;
3674 let f64_vec = [1.0, subnormal, 3.0];
3675
3676 let validated_vec: Result<Vec<RealNative64StrictFinite>, _> = f64_vec
3678 .iter()
3679 .map(|&x| RealNative64StrictFinite::try_new(x))
3680 .collect();
3681
3682 assert!(validated_vec.is_err());
3683 }
3684
3685 #[test]
3686 fn vec_validated_to_f64() {
3687 let validated_vec = [
3689 RealNative64StrictFinite::try_new(1.0).unwrap(),
3690 RealNative64StrictFinite::try_new(2.5).unwrap(),
3691 RealNative64StrictFinite::try_new(-3.7).unwrap(),
3692 RealNative64StrictFinite::try_new(0.0).unwrap(),
3693 RealNative64StrictFinite::try_new(42.0).unwrap(),
3694 ];
3695
3696 let f64_vec: Vec<f64> = validated_vec.iter().map(|x| *x.as_ref()).collect();
3698
3699 assert_eq!(f64_vec.len(), 5);
3701
3702 assert_eq!(f64_vec[0], 1.0);
3704 assert_eq!(f64_vec[1], 2.5);
3705 assert_eq!(f64_vec[2], -3.7);
3706 assert_eq!(f64_vec[3], 0.0);
3707 assert_eq!(f64_vec[4], 42.0);
3708 }
3709
3710 #[test]
3711 fn vec_round_trip_conversion() {
3712 let original_f64 = vec![1.0, 2.5, -3.7, 0.0, 42.0, -999.123];
3714
3715 let validated_vec: Vec<RealNative64StrictFinite> = original_f64
3717 .iter()
3718 .map(|&x| RealNative64StrictFinite::try_new(x).unwrap())
3719 .collect();
3720
3721 let final_f64: Vec<f64> = validated_vec.iter().map(|x| *x.as_ref()).collect();
3723
3724 let slice_f64 =
3725 bytemuck::cast_slice::<RealNative64StrictFinite, f64>(&validated_vec);
3726 assert_eq!(slice_f64, &original_f64);
3727
3728 assert_eq!(original_f64, final_f64);
3730 }
3731
3732 #[test]
3733 fn vec_empty() {
3734 let f64_vec: Vec<f64> = vec![];
3736
3737 let validated_vec: Result<Vec<RealNative64StrictFinite>, _> = f64_vec
3739 .iter()
3740 .map(|&x| RealNative64StrictFinite::try_new(x))
3741 .collect();
3742
3743 assert!(validated_vec.is_ok());
3744 assert_eq!(validated_vec.unwrap().len(), 0);
3745 }
3746
3747 #[test]
3748 fn vec_large_values() {
3749 let f64_vec = vec![f64::MAX, f64::MIN, f64::MIN_POSITIVE, -f64::MIN_POSITIVE];
3751
3752 let validated_vec: Result<Vec<RealNative64StrictFinite>, _> = f64_vec
3754 .iter()
3755 .map(|&x| RealNative64StrictFinite::try_new(x))
3756 .collect();
3757
3758 assert!(validated_vec.is_ok());
3759 let validated_vec = validated_vec.unwrap();
3760
3761 let f64_back: Vec<f64> = validated_vec.iter().map(|x| *x.as_ref()).collect();
3763
3764 assert_eq!(f64_vec, f64_back);
3765 }
3766
3767 #[test]
3768 fn vec_with_zeros() {
3769 let f64_vec = [0.0, -0.0, 1.0, -1.0];
3771
3772 let validated_vec: Result<Vec<RealNative64StrictFinite>, _> = f64_vec
3773 .iter()
3774 .map(|&x| RealNative64StrictFinite::try_new(x))
3775 .collect();
3776
3777 assert!(validated_vec.is_ok());
3778 let validated_vec = validated_vec.unwrap();
3779
3780 assert_eq!(*validated_vec[0].as_ref(), 0.0);
3781 assert_eq!(*validated_vec[1].as_ref(), -0.0);
3782 }
3783
3784 #[test]
3785 fn vec_using_from_iter() {
3786 let f64_vec = [1.0, 2.0, 3.0, 4.0, 5.0];
3788
3789 let validated_vec: Vec<RealNative64StrictFinite> = f64_vec
3791 .iter()
3792 .filter_map(|&x| RealNative64StrictFinite::try_new(x).ok())
3793 .collect();
3794
3795 assert_eq!(validated_vec.len(), 5);
3796 }
3797
3798 #[test]
3799 fn vec_conversion_preserves_order() {
3800 let f64_vec: Vec<f64> = (0..100).map(|i| i as f64 * 0.1).collect();
3802
3803 let validated_vec: Vec<RealNative64StrictFinite> = f64_vec
3804 .iter()
3805 .map(|&x| RealNative64StrictFinite::try_new(x).unwrap())
3806 .collect();
3807
3808 for (i, val) in validated_vec.iter().enumerate() {
3810 assert_eq!(*val.as_ref(), i as f64 * 0.1);
3811 }
3812 }
3813
3814 #[test]
3815 fn vec_partial_conversion_with_find() {
3816 let f64_vec = [1.0, 2.0, f64::NAN, 4.0, 5.0];
3818
3819 let (invalid_idx, _) = f64_vec
3821 .iter()
3822 .enumerate()
3823 .find(|(_, x)| RealNative64StrictFinite::try_new(**x).is_err())
3824 .expect("Should find invalid value");
3825
3826 assert_eq!(invalid_idx, 2);
3827 }
3828
3829 #[test]
3830 fn vec_consume_and_convert() {
3831 let f64_vec = vec![1.0, 2.0, 3.0];
3833
3834 let validated_vec: Result<Vec<RealNative64StrictFinite>, _> = f64_vec
3835 .into_iter()
3836 .map(RealNative64StrictFinite::try_new)
3837 .collect();
3838
3839 assert!(validated_vec.is_ok());
3840 assert_eq!(validated_vec.unwrap().len(), 3);
3841
3842 }
3844
3845 #[test]
3846 fn vec_validated_to_f64_with_try_cast_vec() {
3847 use bytemuck::allocation::try_cast_vec;
3848
3849 let validated_vec: Vec<RealNative64StrictFinite> = vec![
3851 RealNative64StrictFinite::try_new(1.0).unwrap(),
3852 RealNative64StrictFinite::try_new(2.5).unwrap(),
3853 RealNative64StrictFinite::try_new(-3.7).unwrap(),
3854 RealNative64StrictFinite::try_new(0.0).unwrap(),
3855 RealNative64StrictFinite::try_new(42.0).unwrap(),
3856 ];
3857
3858 let f64_vec_result: Result<Vec<f64>, _> = try_cast_vec(validated_vec);
3860
3861 assert!(
3866 f64_vec_result.is_ok(),
3867 "try_cast_vec should work for Vec<RealNative64StrictFinite> -> Vec<f64>"
3868 );
3869
3870 let f64_vec = f64_vec_result.unwrap();
3871 assert_eq!(f64_vec.len(), 5);
3872 assert_eq!(f64_vec[0], 1.0);
3873 assert_eq!(f64_vec[1], 2.5);
3874 assert_eq!(f64_vec[2], -3.7);
3875 assert_eq!(f64_vec[3], 0.0);
3876 assert_eq!(f64_vec[4], 42.0);
3877 }
3878
3879 #[test]
3880 fn vec_f64_to_validated_try_cast_vec_fails() {
3881 let f64_vec = [1.0, 2.5, -3.7, 0.0, 42.0];
3883
3884 let validated_vec: Result<Vec<RealNative64StrictFinite>, _> = f64_vec
3893 .iter()
3894 .map(|&x| RealNative64StrictFinite::try_new(x))
3895 .collect();
3896
3897 assert!(validated_vec.is_ok());
3898 assert_eq!(validated_vec.unwrap().len(), 5);
3899 }
3900 }
3901
3902 mod real_strict_finite_in_debug {
3903 use super::*;
3904
3905 #[test]
3906 fn valid_value_from_bytes() {
3907 let value = 42.0_f64;
3908 let bytes = value.to_ne_bytes();
3909
3910 let result: Result<&RealNative64StrictFiniteInDebug, CheckedCastError> =
3911 try_from_bytes(&bytes);
3912 assert!(result.is_ok());
3913 assert_eq!(*result.unwrap().as_ref(), 42.0);
3914 }
3915
3916 #[test]
3917 fn nan_from_bytes() {
3918 let value = f64::NAN;
3919 let bytes = value.to_ne_bytes();
3920
3921 let result: Result<&RealNative64StrictFiniteInDebug, CheckedCastError> =
3922 try_from_bytes(&bytes);
3923
3924 #[cfg(debug_assertions)]
3925 {
3926 assert!(result.is_err());
3928 assert!(matches!(result, Err(CheckedCastError::InvalidBitPattern)));
3929 }
3930
3931 #[cfg(not(debug_assertions))]
3932 {
3933 assert!(result.is_ok());
3937 }
3938 }
3939
3940 #[test]
3941 fn infinity_from_bytes() {
3942 let value = f64::INFINITY;
3943 let bytes = value.to_ne_bytes();
3944
3945 let result: Result<&RealNative64StrictFiniteInDebug, CheckedCastError> =
3946 try_from_bytes(&bytes);
3947
3948 #[cfg(debug_assertions)]
3949 {
3950 assert!(result.is_err());
3951 }
3952
3953 #[cfg(not(debug_assertions))]
3954 {
3955 assert!(result.is_ok());
3956 }
3957 }
3958
3959 #[test]
3960 fn round_trip_with_valid_value() {
3961 let original = RealNative64StrictFiniteInDebug::try_new(123.456).unwrap();
3962 let as_f64 = *original.as_ref();
3963 let bytes = as_f64.to_ne_bytes();
3964
3965 let from_bytes: &RealNative64StrictFiniteInDebug = try_from_bytes(&bytes).unwrap();
3966 assert_eq!(original, *from_bytes);
3967 }
3968 }
3969
3970 #[test]
3971 fn alignment_check() {
3972 use std::mem;
3973
3974 assert_eq!(
3976 mem::align_of::<RealNative64StrictFinite>(),
3977 mem::align_of::<f64>()
3978 );
3979
3980 assert_eq!(
3982 mem::size_of::<RealNative64StrictFinite>(),
3983 mem::size_of::<f64>()
3984 );
3985 }
3986 }
3987
3988 mod copy_trait_tests {
3993 use super::*;
3994
3995 mod real_copy {
3996 use super::*;
3997
3998 #[test]
3999 fn real_is_copy() {
4000 fn assert_copy<T: Copy>() {}
4002 assert_copy::<RealNative64StrictFinite>();
4003 assert_copy::<RealNative64StrictFiniteInDebug>();
4004 }
4005
4006 #[test]
4007 fn real_copy_semantics() {
4008 let x = RealNative64StrictFinite::try_new(3.).unwrap();
4009 let y = x; let z = x; assert_eq!(x, y);
4012 assert_eq!(x, z);
4013 }
4014
4015 #[test]
4016 fn real_copy_in_function_call() {
4017 fn takes_by_value(val: RealNative64StrictFinite) -> f64 {
4018 *val.as_ref()
4019 }
4020
4021 let x = RealNative64StrictFinite::try_new(42.0).unwrap();
4022 let result1 = takes_by_value(x);
4023 let result2 = takes_by_value(x); assert_eq!(result1, 42.0);
4025 assert_eq!(result2, 42.0);
4026 }
4027
4028 #[test]
4029 fn real_copy_in_loop() {
4030 let x = RealNative64StrictFinite::try_new(1.0).unwrap();
4031 let mut sum = RealNative64StrictFinite::zero();
4032
4033 for _ in 0..5 {
4034 sum += x; }
4036
4037 assert_eq!(*sum.as_ref(), 5.0);
4038 assert_eq!(*x.as_ref(), 1.0); }
4040
4041 #[test]
4042 fn real_copy_with_arithmetic() {
4043 let a = RealNative64StrictFinite::try_new(2.0).unwrap();
4044 let b = RealNative64StrictFinite::try_new(3.0).unwrap();
4045
4046 let sum = a + b;
4048 let diff = a - b;
4049 let prod = a * b;
4050 let quot = a / b;
4051
4052 assert_eq!(*a.as_ref(), 2.0);
4054 assert_eq!(*b.as_ref(), 3.0);
4055 assert_eq!(*sum.as_ref(), 5.0);
4056 assert_eq!(*diff.as_ref(), -1.0);
4057 assert_eq!(*prod.as_ref(), 6.0);
4058 assert!((quot.as_ref() - 2.0 / 3.0).abs() < 1e-10);
4059 }
4060 }
4061
4062 mod complex_copy {
4063 use super::*;
4064
4065 #[test]
4066 fn complex_is_copy() {
4067 fn assert_copy<T: Copy>() {}
4069 assert_copy::<ComplexNative64StrictFinite>();
4070 assert_copy::<ComplexNative64StrictFiniteInDebug>();
4071 }
4072
4073 #[test]
4074 fn complex_copy_semantics() {
4075 let z = ComplexNative64StrictFinite::try_new(Complex::new(1.0, 2.0)).unwrap();
4076 let w = z; let v = z; assert_eq!(z, w);
4079 assert_eq!(z, v);
4080 }
4081
4082 #[test]
4083 fn complex_copy_in_function_call() {
4084 fn takes_by_value(val: ComplexNative64StrictFinite) -> Complex<f64> {
4085 val.into_inner()
4086 }
4087
4088 let z = ComplexNative64StrictFinite::try_new(Complex::new(3.0, 4.0)).unwrap();
4089 let result1 = takes_by_value(z);
4090 let result2 = takes_by_value(z); assert_eq!(result1, Complex::new(3.0, 4.0));
4092 assert_eq!(result2, Complex::new(3.0, 4.0));
4093 }
4094
4095 #[test]
4096 fn complex_copy_with_arithmetic() {
4097 let a = ComplexNative64StrictFinite::try_new(Complex::new(1.0, 2.0)).unwrap();
4098 let b = ComplexNative64StrictFinite::try_new(Complex::new(3.0, 4.0)).unwrap();
4099
4100 let sum = a + b;
4102 let diff = a - b;
4103 let prod = a * b;
4104
4105 assert_eq!(a.into_inner(), Complex::new(1.0, 2.0));
4107 assert_eq!(b.into_inner(), Complex::new(3.0, 4.0));
4108 assert_eq!(sum.into_inner(), Complex::new(4.0, 6.0));
4109 assert_eq!(diff.into_inner(), Complex::new(-2.0, -2.0));
4110 assert_eq!(prod.into_inner(), Complex::new(-5.0, 10.0));
4112 }
4113
4114 #[test]
4115 fn complex_copy_in_loop() {
4116 let z = ComplexNative64StrictFinite::try_new(Complex::new(1.0, 1.0)).unwrap();
4117 let mut sum = ComplexNative64StrictFinite::zero();
4118
4119 for _ in 0..3 {
4120 sum += z; }
4122
4123 assert_eq!(sum.into_inner(), Complex::new(3.0, 3.0));
4124 assert_eq!(z.into_inner(), Complex::new(1.0, 1.0)); }
4126 }
4127
4128 mod mixed_copy {
4129 use super::*;
4130
4131 #[test]
4132 fn real_and_complex_copy_in_expression() {
4133 let r = RealNative64StrictFinite::try_new(2.0).unwrap();
4134 let z = ComplexNative64StrictFinite::try_new(Complex::new(1.0, 1.0)).unwrap();
4135
4136 let result1 = z * r;
4138 let result2 = z * r;
4139
4140 assert_eq!(*r.as_ref(), 2.0);
4142 assert_eq!(z.into_inner(), Complex::new(1.0, 1.0));
4143 assert_eq!(result1.into_inner(), Complex::new(2.0, 2.0));
4144 assert_eq!(result2.into_inner(), Complex::new(2.0, 2.0));
4145 }
4146 }
4147 }
4148}