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