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