1#![deny(rustdoc::broken_intra_doc_links)]
2
3use crate::kernels::{
77 ComplexValidated, NumKernelStrictFinite, NumKernelStrictFiniteInDebug, RealValidated,
78};
79
80pub type Native64StrictFinite = NumKernelStrictFinite<f64, 53>;
90pub type Native64StrictFiniteInDebug = NumKernelStrictFiniteInDebug<f64, 53>;
103pub type RealNative64StrictFinite = RealValidated<Native64StrictFinite>;
113
114pub type ComplexNative64StrictFinite = ComplexValidated<Native64StrictFinite>;
121pub type RealNative64StrictFiniteInDebug = RealValidated<Native64StrictFiniteInDebug>;
131
132pub type ComplexNative64StrictFiniteInDebug = ComplexValidated<Native64StrictFiniteInDebug>;
139#[cfg(test)]
154mod tests {
155 use super::*;
156 use crate::{
157 Clamp, ComplexScalarConstructors, ComplexScalarGetParts, ComplexScalarMutateParts,
158 ComplexScalarSetParts, Constants, ExpM1, FpChecks, Hypot, Ln1p, MulAddRef, NegAssign,
159 RealScalar, Rounding, Sign, TotalCmp,
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, Pow,
166 PowComplexBaseRealExponentErrors, PowIntExponentErrors, PowIntExponentInputErrors,
167 PowRealBaseRealExponentErrors, Reciprocal, ReciprocalErrors, Sin, SinH, Sqrt,
168 SqrtRealErrors, Tan, TanH,
169 },
170 validation::{ErrorsTryFromf64, ErrorsValidationRawComplex, ErrorsValidationRawReal},
171 };
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, New, 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::new(1.23);
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::new(v);
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() {
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(&min_val, &max_val), val);
1241 assert_eq!(
1242 RealValidated::try_new(-5.)
1243 .unwrap()
1244 .clamp(&min_val, &max_val),
1245 min_val
1246 );
1247 assert_eq!(
1248 RealValidated::try_new(15.)
1249 .unwrap()
1250 .clamp(&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(&r2), &r2);
1378 assert_eq!(r2.max(&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(&r2), &r1);
1386 assert_eq!(r2.min(&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 = if cfg!(target_arch = "x86_64") {
1408 1.718281828459045
1409 } else if cfg!(target_arch = "aarch64") {
1410 1.7182818284590453
1411 } else {
1412 todo!("Not implemented for this architecture");
1413 };
1414 assert_eq!(exponent.exp_m1().as_ref(), &expected);
1415 }
1416
1417 #[test]
1418 fn exp_overflow() {
1419 let large_val = RealValidated::try_new(1.0e60).unwrap(); let res_large = large_val.try_exp();
1421 assert!(matches!(
1422 res_large,
1423 Err(ExpErrors::Output {
1424 source: ErrorsValidationRawReal::IsPosInfinity { .. }
1425 })
1426 ),);
1427 }
1428 } mod complex {
1431 use super::*;
1432
1433 #[test]
1434 fn exp_valid() {
1435 let exponent = ComplexValidated::try_new(Complex::new(0., PI)).unwrap();
1436 let expected = Complex::new(-1., 1.2246467991473532e-16);
1437 assert_eq!(exponent.try_exp().unwrap().as_ref(), &expected);
1438 assert_eq!(exponent.exp().as_ref(), &expected);
1439 }
1440 } } mod logarithm {
1444 use super::*;
1445
1446 mod real {
1447 use super::*;
1448
1449 #[test]
1450 fn ln_valid() {
1451 let e = RealValidated::one().exp();
1452 let expected = 1.0;
1453 assert_eq!(e.try_ln().unwrap().as_ref(), &expected);
1454 assert_eq!(e.ln().as_ref(), &expected);
1455 }
1456
1457 #[test]
1458 fn log10_valid() {
1459 let v = RealValidated::try_new(100.).unwrap();
1460 let expected = 2.0;
1461 assert_eq!(v.try_log10().unwrap().as_ref(), &expected);
1462 assert_eq!(v.log10().as_ref(), &expected);
1463 }
1464
1465 #[test]
1466 fn log2_valid() {
1467 let v = RealValidated::try_new(4.).unwrap();
1468 let expected = 2.0;
1469 assert_eq!(v.try_log2().unwrap().as_ref(), &expected);
1470 assert_eq!(v.log2().as_ref(), &expected);
1471 }
1472
1473 #[test]
1474 fn ln_1p_valid() {
1475 let v = RealValidated::one().exp() - RealValidated::one();
1477
1478 assert_eq!(v.ln_1p().as_ref(), &1.);
1480 }
1481
1482 #[test]
1483 fn ln_domain_errors() {
1484 let neg_val = RealValidated::try_new(-1.).unwrap();
1485 assert!(matches!(
1486 neg_val.try_ln(),
1487 Err(LogarithmRealErrors::Input {
1488 source: LogarithmRealInputErrors::NegativeArgument { .. }
1489 })
1490 ));
1491
1492 let zero_val = RealValidated::zero();
1493 assert!(matches!(
1494 zero_val.try_ln(),
1495 Err(LogarithmRealErrors::Input {
1496 source: LogarithmRealInputErrors::ZeroArgument { .. }
1497 })
1498 ));
1499 }
1500
1501 #[test]
1502 fn log10_domain_errors() {
1503 let neg_val = RealValidated::try_new(-1.).unwrap();
1504 assert!(matches!(
1505 neg_val.try_log10(),
1506 Err(LogarithmRealErrors::Input {
1507 source: LogarithmRealInputErrors::NegativeArgument { .. }
1508 })
1509 ));
1510
1511 let zero_val = RealValidated::zero();
1512 assert!(matches!(
1513 zero_val.try_log10(),
1514 Err(LogarithmRealErrors::Input {
1515 source: LogarithmRealInputErrors::ZeroArgument { .. }
1516 })
1517 ));
1518 }
1519
1520 #[test]
1521 fn log2_domain_errors() {
1522 let neg_val = RealValidated::try_new(-1.).unwrap();
1523 assert!(matches!(
1524 neg_val.try_log2(),
1525 Err(LogarithmRealErrors::Input {
1526 source: LogarithmRealInputErrors::NegativeArgument { .. }
1527 })
1528 ));
1529
1530 let zero_val = RealValidated::zero();
1531 assert!(matches!(
1532 zero_val.try_log2(),
1533 Err(LogarithmRealErrors::Input {
1534 source: LogarithmRealInputErrors::ZeroArgument { .. }
1535 })
1536 ));
1537 }
1538 } mod complex {
1541 use super::*;
1542
1543 #[test]
1544 fn ln_valid() {
1545 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
1546 let expected = Complex::new(0.8047189562170503, -1.1071487177940904);
1547 assert_eq!(v.try_ln().unwrap().as_ref(), &expected);
1548 assert_eq!(v.ln().as_ref(), &expected);
1549 }
1550
1551 #[test]
1552 fn log10_valid() {
1553 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
1554 let expected = Complex::new(0.3494850021680094, -0.480828578784234);
1555 assert_eq!(v.try_log10().unwrap().as_ref(), &expected);
1556 assert_eq!(v.log10().as_ref(), &expected);
1557 }
1558
1559 #[test]
1560 fn log2_valid() {
1561 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
1562 let expected = Complex::new(1.1609640474436813, -1.5972779646881088);
1563 assert_eq!(v.try_log2().unwrap().as_ref(), &expected);
1564 assert_eq!(v.log2().as_ref(), &expected);
1565 }
1566
1567 #[test]
1568 fn ln_zero() {
1569 let zero_val = ComplexValidated::zero();
1570 assert!(matches!(
1571 zero_val.try_ln(),
1572 Err(LogarithmComplexErrors::Input {
1573 source: LogarithmComplexInputErrors::ZeroArgument { .. }
1574 })
1575 ));
1576 }
1577
1578 #[test]
1579 fn log10_zero() {
1580 let zero_val = ComplexValidated::zero();
1581 assert!(matches!(
1582 zero_val.try_log10(),
1583 Err(LogarithmComplexErrors::Input {
1584 source: LogarithmComplexInputErrors::ZeroArgument { .. }
1585 })
1586 ));
1587 }
1588
1589 #[test]
1590 fn log2_zero() {
1591 let zero_val = ComplexValidated::zero();
1592 assert!(matches!(
1593 zero_val.try_log2(),
1594 Err(LogarithmComplexErrors::Input {
1595 source: LogarithmComplexInputErrors::ZeroArgument { .. }
1596 })
1597 ));
1598 }
1599 } } mod pow {
1603 use super::*;
1604
1605 mod real_base {
1606 use super::*;
1607
1608 #[test]
1609 fn negative_base_real_exponent_error() {
1610 let base = RealValidated::try_new(-2.).unwrap();
1611 let exponent = RealValidated::try_new(0.5).unwrap();
1612 let res = base.try_pow(&exponent);
1613 assert!(matches!(
1614 res,
1615 Err(PowRealBaseRealExponentErrors::Input {
1616 source: PowRealBaseRealExponentInputErrors::NegativeBase { .. }
1617 })
1618 ));
1619 }
1620
1621 #[test]
1622 fn real_base_uint_exponent_valid() {
1623 let base = RealValidated::try_new(2.).unwrap();
1624 assert_eq!(
1625 base.try_pow(3u8).unwrap(),
1626 RealValidated::try_new(8.).unwrap()
1627 );
1628 assert_eq!(
1629 base.try_pow(3u16).unwrap(),
1630 RealValidated::try_new(8.).unwrap()
1631 );
1632 assert_eq!(
1633 base.try_pow(3u32).unwrap(),
1634 RealValidated::try_new(8.).unwrap()
1635 );
1636 assert_eq!(
1637 base.try_pow(3u64).unwrap(),
1638 RealValidated::try_new(8.).unwrap()
1639 );
1640 assert_eq!(
1641 base.try_pow(3u128).unwrap(),
1642 RealValidated::try_new(8.).unwrap()
1643 );
1644 assert_eq!(
1645 base.try_pow(3usize).unwrap(),
1646 RealValidated::try_new(8.).unwrap()
1647 );
1648
1649 assert_eq!(base.pow(3u8), RealValidated::try_new(8.).unwrap());
1650 assert_eq!(base.pow(3u16), RealValidated::try_new(8.).unwrap());
1651 assert_eq!(base.pow(3u32), RealValidated::try_new(8.).unwrap());
1652 assert_eq!(base.pow(3u64), RealValidated::try_new(8.).unwrap());
1653 assert_eq!(base.pow(3u128), RealValidated::try_new(8.).unwrap());
1654 assert_eq!(base.pow(3usize), RealValidated::try_new(8.).unwrap());
1655 }
1656
1657 #[test]
1658 fn real_base_int_exponent_valid() {
1659 let base = RealValidated::try_new(2.).unwrap();
1660 assert_eq!(
1661 base.try_pow(3i8).unwrap(),
1662 RealValidated::try_new(8.).unwrap()
1663 );
1664 assert_eq!(
1665 base.try_pow(3i16).unwrap(),
1666 RealValidated::try_new(8.).unwrap()
1667 );
1668 assert_eq!(
1669 base.try_pow(3i32).unwrap(),
1670 RealValidated::try_new(8.).unwrap()
1671 );
1672 assert_eq!(
1673 base.try_pow(3i64).unwrap(),
1674 RealValidated::try_new(8.).unwrap()
1675 );
1676 assert_eq!(
1677 base.try_pow(3i128).unwrap(),
1678 RealValidated::try_new(8.).unwrap()
1679 );
1680 assert_eq!(
1681 base.try_pow(3isize).unwrap(),
1682 RealValidated::try_new(8.).unwrap()
1683 );
1684
1685 assert_eq!(base.pow(3i8), RealValidated::try_new(8.).unwrap());
1686 assert_eq!(base.pow(3i16), RealValidated::try_new(8.).unwrap());
1687 assert_eq!(base.pow(3i32), RealValidated::try_new(8.).unwrap());
1688 assert_eq!(base.pow(3i64), RealValidated::try_new(8.).unwrap());
1689 assert_eq!(base.pow(3i128), RealValidated::try_new(8.).unwrap());
1690 assert_eq!(base.pow(3isize), RealValidated::try_new(8.).unwrap());
1691 }
1692
1693 #[test]
1694 fn real_base_int_exponent_zero_neg_exp_error() {
1695 let base = RealValidated::zero();
1696 let exponent: i32 = -2;
1697 let res = base.try_pow(exponent);
1698 assert!(matches!(
1699 res,
1700 Err(PowIntExponentErrors::Input {
1701 source: PowIntExponentInputErrors::ZeroBaseNegativeExponent { .. }
1702 })
1703 ));
1704 }
1705
1706 #[test]
1707 fn real_base_real_exponent_valid() {
1708 let base = RealValidated::try_new(2.).unwrap();
1709 let exponent = RealValidated::try_new(3.).unwrap();
1710 let expected = 8.;
1711 assert_eq!(base.try_pow(&exponent).unwrap().as_ref(), &expected);
1712 assert_eq!(base.pow(&exponent).as_ref(), &expected);
1713 }
1714 }
1715
1716 mod complex_base {
1717 use super::*;
1718
1719 #[test]
1720 fn complex_base_uint_exponent_valid() {
1721 let base = ComplexValidated::try_new(Complex::new(2., 3.)).unwrap();
1722 let expected_res = ComplexValidated::try_new(Complex::new(-46., 9.)).unwrap();
1723
1724 assert_eq!(&base.try_pow(3u8).unwrap(), &expected_res);
1725 assert_eq!(&base.try_pow(3u16).unwrap(), &expected_res);
1726 assert_eq!(&base.try_pow(3u32).unwrap(), &expected_res);
1727 assert_eq!(&base.try_pow(3u64).unwrap(), &expected_res);
1728 assert_eq!(&base.try_pow(3u128).unwrap(), &expected_res);
1729 assert_eq!(&base.try_pow(3usize).unwrap(), &expected_res);
1730
1731 assert_eq!(&base.pow(3u8), &expected_res);
1732 assert_eq!(&base.pow(3u16), &expected_res);
1733 assert_eq!(&base.pow(3u32), &expected_res);
1734 assert_eq!(&base.pow(3u64), &expected_res);
1735 assert_eq!(&base.pow(3u128), &expected_res);
1736 assert_eq!(&base.pow(3usize), &expected_res);
1737 }
1738
1739 #[test]
1740 fn complex_base_int_exponent_valid() {
1741 let base = ComplexValidated::try_new(Complex::new(2., 3.)).unwrap();
1742 let expected_res = ComplexValidated::try_new(Complex::new(-46., 9.)).unwrap();
1743
1744 assert_eq!(&base.try_pow(3i8).unwrap(), &expected_res);
1745 assert_eq!(&base.try_pow(3i16).unwrap(), &expected_res);
1746 assert_eq!(&base.try_pow(3i32).unwrap(), &expected_res);
1747 assert_eq!(&base.try_pow(3i64).unwrap(), &expected_res);
1748 assert_eq!(&base.try_pow(3i128).unwrap(), &expected_res);
1749 assert_eq!(&base.try_pow(3isize).unwrap(), &expected_res);
1750
1751 assert_eq!(&base.pow(3i8), &expected_res);
1752 assert_eq!(&base.pow(3i16), &expected_res);
1753 assert_eq!(&base.pow(3i32), &expected_res);
1754 assert_eq!(&base.pow(3i64), &expected_res);
1755 assert_eq!(&base.pow(3i128), &expected_res);
1756 assert_eq!(&base.pow(3isize), &expected_res);
1757 }
1758
1759 #[test]
1760 fn complex_zero_base_negative_real_exponent_error() {
1761 let base = ComplexValidated::zero();
1762 let exponent = RealValidated::try_new(-2.).unwrap();
1763 let res = base.try_pow(&exponent);
1764 assert!(matches!(
1765 res,
1766 Err(PowComplexBaseRealExponentErrors::Input {
1767 source:
1768 PowComplexBaseRealExponentInputErrors::ZeroBaseNegativeExponent { .. }
1769 })
1770 ));
1771 }
1772
1773 #[test]
1774 fn complex_zero_base_zero_real_exponent() {
1775 let base = ComplexValidated::zero();
1776 let exponent = RealValidated::zero();
1777 let res = base.try_pow(&exponent).unwrap();
1778 assert_eq!(res, ComplexValidated::one());
1779 }
1780
1781 #[test]
1782 fn complex_base_int_exponent_zero_neg_exp_error() {
1783 let base = ComplexValidated::zero();
1784 let exponent: i32 = -2;
1785 let res = base.try_pow(exponent);
1786 assert!(matches!(
1787 res,
1788 Err(PowIntExponentErrors::Input {
1789 source: PowIntExponentInputErrors::ZeroBaseNegativeExponent { .. }
1790 })
1791 ));
1792 }
1793
1794 #[test]
1795 fn complex_base_real_exponent_valid() {
1796 let base = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
1797 let exponent = RealValidated::try_new(3.).unwrap();
1798 let expected = Complex::new(-11.000000000000004, 1.9999999999999973);
1799 assert_eq!(base.try_pow(&exponent).unwrap().as_ref(), &expected);
1800 assert_eq!(base.pow(&exponent).as_ref(), &expected);
1801 }
1802
1803 #[test]
1804 fn complex_zero_base_real_exponent_valid() {
1805 let base = ComplexValidated::zero();
1806 let exponent = RealValidated::try_new(3.).unwrap();
1807 let expected = Complex::new(0., 0.);
1808 assert_eq!(base.try_pow(&exponent).unwrap().as_ref(), &expected);
1809 assert_eq!(base.pow(&exponent).as_ref(), &expected);
1810 }
1811 }
1812 }
1813
1814 mod reciprocal {
1815 use super::*;
1816
1817 mod real {
1818 use super::*;
1819
1820 #[test]
1821 fn reciprocal_valid() {
1822 let v = RealValidated::try_new(2.).unwrap();
1823
1824 let res = v.try_reciprocal().unwrap();
1825 assert_eq!(res.into_inner(), 0.5);
1826
1827 let res = v.reciprocal();
1828 assert_eq!(res.into_inner(), 0.5);
1829 }
1830
1831 #[test]
1832 fn reciprocal_real_zero() {
1833 let zero_val = RealValidated::zero();
1834 let res = zero_val.try_reciprocal();
1835 assert!(matches!(
1836 res,
1837 Err(ReciprocalErrors::Input {
1838 source: ReciprocalInputErrors::DivisionByZero { .. }
1839 })
1840 ));
1841 }
1842 }
1843
1844 mod complex {
1845 use super::*;
1846
1847 #[test]
1848 fn reciprocal_valid() {
1849 let v = ComplexValidated::try_new(Complex::new(3., 4.)).unwrap();
1850
1851 let expected = Complex::new(0.12, -0.16);
1852
1853 let res = v.try_reciprocal().unwrap();
1854 assert_eq!(res.as_ref(), &expected);
1855
1856 let res = v.reciprocal();
1857 assert_eq!(res.as_ref(), &expected);
1858 }
1859
1860 #[test]
1861 fn reciprocal_complex_zero() {
1862 let zero_val = ComplexValidated::zero();
1863 let res = zero_val.try_reciprocal();
1864 assert!(matches!(
1865 res,
1866 Err(ReciprocalErrors::Input {
1867 source: ReciprocalInputErrors::DivisionByZero { .. }
1868 })
1869 ));
1870 }
1871 }
1872 } mod sqrt {
1875 use super::*;
1876
1877 mod real {
1878 use super::*;
1879
1880 #[test]
1881 fn sqrt_valid() {
1882 let v = RealValidated::try_new(9.).unwrap();
1883 assert_eq!(v.try_sqrt().unwrap().as_ref(), &3.);
1884 assert_eq!(v.sqrt().as_ref(), &3.);
1885 }
1886
1887 #[test]
1888 fn sqrt_negative_input() {
1889 let neg_val = RealValidated::try_new(-4.).unwrap();
1890 let res = neg_val.try_sqrt();
1891 assert!(matches!(
1892 res,
1893 Err(SqrtRealErrors::Input {
1894 source: SqrtRealInputErrors::NegativeValue { .. }
1895 })
1896 ));
1897 }
1898 } mod complex {
1901 use super::*;
1902
1903 #[test]
1904 fn sqrt_valid() {
1905 let expected = Complex::new(1., 2.);
1906 let v = ComplexValidated::try_new(expected * expected).unwrap();
1907
1908 let expected = Complex::new(1.0000000000000002, 2.);
1909 assert_eq!(v.try_sqrt().unwrap().as_ref(), &expected);
1910 assert_eq!(v.sqrt().as_ref(), &expected);
1911 }
1912 }
1913 } mod trigonometric {
1916 use super::*;
1917
1918 mod real {
1919 use super::*;
1920
1921 #[test]
1922 fn sin_real_valid() {
1923 let v = RealValidated::pi_div_2();
1924
1925 let expected = 1.;
1926 assert_eq!(v.try_sin().unwrap().as_ref(), &expected);
1927 assert_eq!(v.sin().as_ref(), &expected);
1928 }
1929
1930 #[test]
1931 fn cos_real_valid() {
1932 let v = RealValidated::pi();
1933
1934 let expected = -1.;
1935 assert_eq!(v.try_cos().unwrap().as_ref(), &expected);
1936 assert_eq!(v.cos().as_ref(), &expected);
1937 }
1938
1939 #[test]
1940 fn tan_real_valid() {
1941 let v = RealValidated::one();
1942
1943 let expected = if cfg!(target_arch = "x86_64") {
1944 1.5574077246549023
1945 } else if cfg!(target_arch = "aarch64") {
1946 1.557407724654902
1947 } else {
1948 todo!("Implement for other architectures");
1949 };
1950 assert_eq!(v.try_tan().unwrap().as_ref(), &expected);
1951 assert_eq!(v.tan().as_ref(), &expected);
1952 }
1953
1954 #[test]
1955 fn asin_real_valid() {
1956 let v = RealValidated::one();
1957
1958 let expected = std::f64::consts::FRAC_PI_2; assert_eq!(v.try_asin().unwrap().as_ref(), &expected);
1960 assert_eq!(v.asin().as_ref(), &expected);
1961 }
1962
1963 #[test]
1964 fn acos_real_valid() {
1965 let v = RealValidated::one();
1966
1967 let expected = 0.;
1968 assert_eq!(v.try_acos().unwrap().as_ref(), &expected);
1969 assert_eq!(v.acos().as_ref(), &expected);
1970 }
1971
1972 #[test]
1973 fn atan_real_valid() {
1974 let v = RealValidated::one();
1975
1976 let expected = std::f64::consts::FRAC_PI_4; assert_eq!(v.try_atan().unwrap().as_ref(), &expected);
1978 assert_eq!(v.atan().as_ref(), &expected);
1979 }
1980
1981 #[test]
1982 fn atan2_valid() {
1983 let one = RealValidated::one();
1984 let zero = RealValidated::zero();
1985
1986 let expected = std::f64::consts::FRAC_PI_2; assert_eq!(one.try_atan2(&zero).unwrap().as_ref(), &expected);
1988 assert_eq!(one.atan2(&zero).as_ref(), &expected);
1989
1990 let expected = 0.;
1991 assert_eq!(zero.try_atan2(&one).unwrap().as_ref(), &expected);
1992 assert_eq!(zero.atan2(&one).as_ref(), &expected);
1993
1994 let expected = std::f64::consts::FRAC_PI_4; assert_eq!(one.try_atan2(&one).unwrap().as_ref(), &expected);
1996 assert_eq!(one.atan2(&one).as_ref(), &expected);
1997 }
1998
1999 #[test]
2000 fn atan2_zero_over_zero() {
2001 let zero_val = RealValidated::zero();
2002 let res = zero_val.try_atan2(&RealValidated::zero());
2003 assert!(matches!(
2004 res,
2005 Err(ATan2Errors::Input {
2006 source: ATan2InputErrors::ZeroOverZero { .. }
2007 })
2008 ));
2009 }
2010
2011 #[test]
2029 fn asin_real_out_of_domain() {
2030 let val_gt_1 = RealValidated::try_new(1.5).unwrap();
2031 assert!(matches!(
2032 val_gt_1.try_asin(),
2033 Err(ASinRealErrors::Input {
2034 source: ASinRealInputErrors::OutOfDomain { .. }
2035 })
2036 ));
2037 let val_lt_neg1 = RealValidated::try_new(-1.5).unwrap();
2038 assert!(matches!(
2039 val_lt_neg1.try_asin(),
2040 Err(ASinRealErrors::Input {
2041 source: ASinRealInputErrors::OutOfDomain { .. }
2042 })
2043 ));
2044 }
2045
2046 #[test]
2047 fn acos_real_out_of_domain() {
2048 let val_gt_1 = RealValidated::try_new(1.5).unwrap();
2049 assert!(matches!(
2050 val_gt_1.try_acos(),
2051 Err(ACosRealErrors::Input {
2052 source: ACosRealInputErrors::OutOfDomain { .. }
2053 })
2054 ));
2055 let val_lt_neg1 = RealValidated::try_new(-1.5).unwrap();
2056 assert!(matches!(
2057 val_lt_neg1.try_acos(),
2058 Err(ACosRealErrors::Input {
2059 source: ACosRealInputErrors::OutOfDomain { .. }
2060 })
2061 ));
2062 }
2063 } mod complex {
2066 use super::*;
2067
2068 #[test]
2069 fn sin_complex_valid() {
2070 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2071
2072 let expected = if cfg!(target_arch = "x86_64") {
2073 Complex::new(3.165778513216168, -1.9596010414216063)
2074 } else if cfg!(target_arch = "aarch64") {
2075 Complex::new(3.165778513216168, -1.959601041421606)
2076 } else {
2077 todo!("Implement for other architectures");
2078 };
2079 assert_eq!(v.try_sin().unwrap().as_ref(), &expected);
2080 assert_eq!(v.sin().as_ref(), &expected);
2081
2082 let zero = ComplexValidated::zero();
2083 let expected = Complex::new(0., 0.);
2084 assert_eq!(zero.try_sin().unwrap().as_ref(), &expected);
2085 assert_eq!(zero.sin().as_ref(), &expected);
2086 }
2087
2088 #[test]
2089 fn cos_complex_valid() {
2090 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2091
2092 let expected = if cfg!(target_arch = "x86_64") {
2093 Complex::new(2.0327230070196656, 3.0518977991518)
2094 } else if cfg!(target_arch = "aarch64") {
2095 Complex::new(2.0327230070196656, 3.0518977991517997)
2096 } else {
2097 todo!("Implement for other architectures");
2098 };
2099 assert_eq!(v.try_cos().unwrap().as_ref(), &expected);
2100 assert_eq!(v.cos().as_ref(), &expected);
2101
2102 let zero = ComplexValidated::zero();
2103 let expected = Complex::new(1., 0.);
2104 assert_eq!(zero.try_cos().unwrap().as_ref(), &expected);
2105 assert_eq!(zero.cos().as_ref(), &expected);
2106 }
2107
2108 #[test]
2109 fn tan_complex_valid() {
2110 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2111
2112 let expected = Complex::new(0.03381282607989669, -1.0147936161466335);
2113 assert_eq!(v.try_tan().unwrap().as_ref(), &expected);
2114 assert_eq!(v.tan().as_ref(), &expected);
2115
2116 let zero = ComplexValidated::zero();
2117 let expected = Complex::new(0., 0.);
2118 assert_eq!(zero.try_tan().unwrap().as_ref(), &expected);
2119 assert_eq!(zero.tan().as_ref(), &expected);
2120 }
2121
2122 #[test]
2123 fn asin_complex_valid() {
2124 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2125
2126 let expected = Complex::new(0.42707858639247614, -1.528570919480998);
2127 assert_eq!(v.try_asin().unwrap().as_ref(), &expected);
2128 assert_eq!(v.asin().as_ref(), &expected);
2129
2130 let zero = ComplexValidated::zero();
2131 let expected = Complex::new(0., 0.);
2132 assert_eq!(zero.try_asin().unwrap().as_ref(), &expected);
2133 assert_eq!(zero.asin().as_ref(), &expected);
2134 }
2135
2136 #[test]
2137 fn acos_complex_valid() {
2138 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2139
2140 let expected = Complex::new(1.14371774040242, 1.5285709194809995);
2141 assert_eq!(v.try_acos().unwrap().as_ref(), &expected);
2142 assert_eq!(v.acos().as_ref(), &expected);
2143
2144 let one = ComplexValidated::one();
2145 let expected = Complex::new(0., 0.);
2146 assert_eq!(one.try_acos().unwrap().as_ref(), &expected);
2147 assert_eq!(one.acos().as_ref(), &expected);
2148 }
2149
2150 #[test]
2151 fn atan_complex_valid() {
2152 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2153
2154 let expected = Complex::new(1.3389725222944935, -0.4023594781085251);
2155 assert_eq!(v.try_atan().unwrap().as_ref(), &expected);
2156 assert_eq!(v.atan().as_ref(), &expected);
2157
2158 let zero = ComplexValidated::zero();
2159 let expected = Complex::new(0., 0.);
2160 assert_eq!(zero.try_atan().unwrap().as_ref(), &expected);
2161 assert_eq!(zero.atan().as_ref(), &expected);
2162 }
2163
2164 #[test]
2165 fn atan_complex_pole() {
2166 let i_val = ComplexValidated::try_new_pure_imaginary(1.).unwrap();
2168 assert!(matches!(
2169 i_val.try_atan(),
2170 Err(ATanComplexErrors::Input {
2171 source: ATanComplexInputErrors::ArgumentIsPole { .. }
2172 })
2173 ));
2174
2175 let neg_i_val = ComplexValidated::try_new_pure_imaginary(-1.).unwrap();
2176 assert!(matches!(
2177 neg_i_val.try_atan(),
2178 Err(ATanComplexErrors::Input {
2179 source: ATanComplexInputErrors::ArgumentIsPole { .. }
2180 })
2181 ));
2182 }
2183 } } mod hyperbolic {
2187 use super::*;
2188
2189 mod real {
2190 use super::*;
2191
2192 #[test]
2193 fn atanh_real_valid() {
2194 let v = RealValidated::zero();
2195 let expected = 0.;
2196 assert_eq!(v.try_atanh().unwrap().as_ref(), &expected);
2197 assert_eq!(v.atanh().as_ref(), &expected);
2198 }
2199
2200 #[test]
2201 fn atanh_real_out_of_domain() {
2202 let val_ge_1 = RealValidated::one(); assert!(matches!(
2204 val_ge_1.try_atanh(),
2205 Err(ATanHErrors::Input {
2206 source: ATanHInputErrors::OutOfDomain { .. }
2207 })
2208 ));
2209
2210 let val_le_neg1 = RealValidated::negative_one(); assert!(matches!(
2212 val_le_neg1.try_atanh(),
2213 Err(ATanHErrors::Input {
2214 source: ATanHInputErrors::OutOfDomain { .. }
2215 })
2216 ));
2217 }
2218
2219 #[test]
2220 fn acosh_real_valid() {
2221 let v = RealValidated::one();
2222 let expected = 0.;
2223 assert_eq!(v.try_acosh().unwrap().as_ref(), &expected);
2224 assert_eq!(v.acosh().as_ref(), &expected);
2225 }
2226
2227 #[test]
2228 fn acosh_real_out_of_domain() {
2229 let val_lt_1 = RealValidated::try_new(0.5).unwrap();
2230 assert!(matches!(
2231 val_lt_1.try_acosh(),
2232 Err(ACosHErrors::Input {
2233 source: ACosHInputErrors::OutOfDomain { .. }
2234 })
2235 ));
2236 }
2237
2238 #[test]
2239 fn asinh_real_valid() {
2240 let v = RealValidated::one();
2241 let expected = 0.881373587019543;
2242 assert_eq!(v.try_asinh().unwrap().as_ref(), &expected);
2243 assert_eq!(v.asinh().as_ref(), &expected);
2244 }
2245
2246 #[test]
2247 fn sinh_real_valid() {
2248 let v = RealValidated::try_new(0.881373587019543).unwrap();
2249 let expected = 1.;
2250 assert_eq!(v.try_sinh().unwrap().as_ref(), &expected);
2251 assert_eq!(v.sinh().as_ref(), &expected);
2252 }
2253
2254 #[test]
2255 fn cosh_real_valid() {
2256 let v = RealValidated::one();
2257 let expected = 1.5430806348152437;
2258 assert_eq!(v.try_cosh().unwrap().as_ref(), &expected);
2259 assert_eq!(v.cosh().as_ref(), &expected);
2260 }
2261
2262 #[test]
2263 fn tanh_real_valid() {
2264 let v = RealValidated::one();
2265 let expected = 0.7615941559557649;
2266 assert_eq!(v.try_tanh().unwrap().as_ref(), &expected);
2267 assert_eq!(v.tanh().as_ref(), &expected);
2268 }
2269 }
2270
2271 mod complex {
2272 use super::*;
2273
2274 #[test]
2275 fn sinh_valid() {
2276 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2277 let expected = Complex::new(-0.4890562590412937, -1.4031192506220405);
2278 assert_eq!(v.try_sinh().unwrap().as_ref(), &expected);
2279 assert_eq!(v.sinh().as_ref(), &expected);
2280 }
2281
2282 #[test]
2283 fn cosh_valid() {
2284 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2285 let expected = Complex::new(-0.64214812471552, -1.0686074213827783);
2286 assert_eq!(v.try_cosh().unwrap().as_ref(), &expected);
2287 assert_eq!(v.cosh().as_ref(), &expected);
2288 }
2289
2290 #[test]
2291 fn tanh_valid() {
2292 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2293 let expected = if cfg!(target_arch = "x86_64") {
2294 Complex::new(1.16673625724092, 0.24345820118572523)
2295 } else if cfg!(target_arch = "aarch64") {
2296 Complex::new(1.16673625724092, 0.24345820118572528)
2297 } else {
2298 todo!("Missing target architecture!");
2299 };
2300 assert_eq!(v.try_tanh().unwrap().as_ref(), &expected);
2301 assert_eq!(v.tanh().as_ref(), &expected);
2302 }
2303
2304 #[test]
2305 fn asinh_valid() {
2306 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2307 let expected = Complex::new(1.4693517443681852, -1.0634400235777521);
2308 Complex::new(1.4693517443681852, -1.0634400235777521);
2309 assert_eq!(v.try_asinh().unwrap().as_ref(), &expected);
2310 assert_eq!(v.asinh().as_ref(), &expected);
2311 }
2312
2313 #[test]
2314 fn acosh_valid() {
2315 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2316 let expected = Complex::new(1.528570919480998, -1.1437177404024206);
2317 assert_eq!(v.try_acosh().unwrap().as_ref(), &expected);
2318 assert_eq!(v.acosh().as_ref(), &expected);
2319 }
2320
2321 #[test]
2322 fn atanh_valid() {
2323 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2324 let expected = Complex::new(0.1732867951399864, -1.1780972450961724);
2325 assert_eq!(v.try_atanh().unwrap().as_ref(), &expected);
2326 assert_eq!(v.atanh().as_ref(), &expected);
2327 }
2328
2329 #[test]
2348 fn acosh_out_of_domain() {
2349 let val_on_branch_cut = ComplexValidated::try_new_pure_real(0.5).unwrap();
2351 assert!(matches!(
2352 val_on_branch_cut.try_acosh(),
2353 Err(ACosHErrors::Input {
2354 source: ACosHInputErrors::OutOfDomain { .. }
2355 })
2356 ));
2357
2358 let val_on_branch_cut_neg = ComplexValidated::try_new_pure_real(-5.).unwrap();
2359 assert!(matches!(
2360 val_on_branch_cut_neg.try_acosh(),
2361 Err(ACosHErrors::Input {
2362 source: ACosHInputErrors::OutOfDomain { .. }
2363 })
2364 ));
2365 }
2366
2367 #[test]
2368 fn atanh_out_of_domain() {
2369 let val_ge_1 = ComplexValidated::try_new_pure_real(1.).unwrap();
2370 assert!(matches!(
2371 val_ge_1.try_atanh(),
2372 Err(ATanHErrors::Input {
2373 source: ATanHInputErrors::OutOfDomain { .. }
2374 })
2375 ));
2376
2377 let val_le_neg1 = ComplexValidated::try_new_pure_real(-1.).unwrap();
2378 assert!(matches!(
2379 val_le_neg1.try_atanh(),
2380 Err(ATanHErrors::Input {
2381 source: ATanHInputErrors::OutOfDomain { .. }
2382 })
2383 ));
2384 }
2385 }
2386
2387 } }
2405
2406 mod summation {
2407 use super::*;
2408
2409 #[test]
2410 fn sum_real() {
2411 let values = vec![
2412 RealValidated::try_new(1.0).unwrap(),
2413 RealValidated::try_new(2.0).unwrap(),
2414 RealValidated::try_new(3.0).unwrap(),
2415 RealValidated::try_new(4.0).unwrap(),
2416 RealValidated::try_new(5.0).unwrap(),
2417 ];
2418 let sum: RealValidated = values.into_iter().sum();
2419 assert_eq!(sum, RealValidated::try_new(15.0).unwrap());
2420 }
2421
2422 #[test]
2423 fn sum_real_compensated() {
2424 let values = vec![
2426 RealValidated::try_new(1.0e100).unwrap(),
2427 RealValidated::try_new(1.0).unwrap(),
2428 RealValidated::try_new(-1.0e100).unwrap(),
2429 ];
2430 let sum: RealValidated = values.into_iter().sum();
2431 assert_eq!(sum, RealValidated::try_new(1.0).unwrap());
2433 }
2434
2435 #[test]
2436 fn sum_complex() {
2437 let values = vec![
2438 ComplexValidated::try_new(Complex::new(1.0, 2.0)).unwrap(),
2439 ComplexValidated::try_new(Complex::new(3.0, 4.0)).unwrap(),
2440 ComplexValidated::try_new(Complex::new(5.0, 6.0)).unwrap(),
2441 ];
2442 let sum: ComplexValidated = values.into_iter().sum();
2443 assert_eq!(
2444 sum,
2445 ComplexValidated::try_new(Complex::new(9.0, 12.0)).unwrap()
2446 );
2447 }
2448
2449 #[test]
2450 fn sum_complex_compensated() {
2451 let values = vec![
2452 ComplexValidated::try_new(Complex::new(1.0e100, -1.0e100)).unwrap(),
2453 ComplexValidated::try_new(Complex::new(1.0, 2.0)).unwrap(),
2454 ComplexValidated::try_new(Complex::new(-1.0e100, 1.0e100)).unwrap(),
2455 ];
2456 let sum: ComplexValidated = values.into_iter().sum();
2457 assert_eq!(
2458 sum,
2459 ComplexValidated::try_new(Complex::new(1.0, 2.0)).unwrap()
2460 );
2461 }
2462 } mod neumaier_sum {
2465 use crate::neumaier_compensated_sum::NeumaierSum;
2466 use try_create::TryNewValidated;
2467
2468 use super::*;
2469
2470 mod real {
2471 use super::*;
2472
2473 #[test]
2474 fn new() {
2475 let neumaier = NeumaierSum::new(RealValidated::try_new_validated(1.0).unwrap());
2476 assert_eq!(neumaier.sum_before_compensation(), &1.0);
2477 assert_eq!(neumaier.compensation(), &0.0);
2478 }
2479
2480 #[test]
2481 fn zero() {
2482 let neumaier = NeumaierSum::<RealValidated>::zero();
2483 assert_eq!(neumaier.sum_before_compensation(), &0.0);
2484 assert_eq!(neumaier.compensation(), &0.0);
2485 }
2486
2487 #[test]
2488 fn add() {
2489 let mut neumaier = NeumaierSum::zero();
2490 neumaier.add(RealValidated::try_new_validated(1.0).unwrap());
2491 neumaier.add(RealValidated::try_new_validated(1e-16).unwrap());
2492 neumaier.add(RealValidated::try_new_validated(-1.0).unwrap());
2493 assert_eq!(neumaier.sum_before_compensation(), &0.0);
2494 assert_eq!(neumaier.compensation(), &1e-16);
2495 }
2496
2497 #[test]
2498 fn sum() {
2499 let mut neumaier = NeumaierSum::zero();
2500 neumaier.add(RealValidated::try_new_validated(1.0).unwrap());
2501 neumaier.add(RealValidated::try_new_validated(1e-16).unwrap());
2502 neumaier.add(RealValidated::try_new_validated(-1.0).unwrap());
2503 assert_eq!(neumaier.sum_before_compensation(), &0.0);
2504 assert_eq!(neumaier.compensation(), &1e-16);
2505 assert_eq!(neumaier.sum().as_ref(), &1e-16);
2506 println!("compensated sum = {}", neumaier.sum());
2507 }
2508
2509 #[test]
2510 fn reset() {
2511 let mut neumaier = NeumaierSum::zero();
2512 neumaier.add(RealValidated::try_new_validated(1.0).unwrap());
2513 neumaier.add(RealValidated::try_new_validated(1e-16).unwrap());
2514 assert_eq!(neumaier.sum_before_compensation(), &1.0);
2515 assert_eq!(neumaier.compensation(), &1e-16);
2516
2517 neumaier.reset();
2518 assert_eq!(neumaier.sum_before_compensation(), &0.0);
2519 assert_eq!(neumaier.compensation(), &0.0);
2520 }
2521
2522 #[test]
2523 fn sum_big_values() {
2524 let values = [1.0, 1e100, 1.0, -1e100]
2525 .iter()
2526 .map(|&v| RealValidated::try_new_validated(v).unwrap())
2527 .collect::<Vec<_>>();
2528 let sum = values.iter().cloned().sum::<RealValidated>();
2529 assert_eq!(sum, 2.0);
2530
2531 let neumaier = NeumaierSum::new_sequential(values);
2532 assert_eq!(neumaier.sum(), 2.0);
2533 println!("compensated sum = {}", neumaier.sum());
2534 }
2535
2536 #[test]
2537 fn sum_small_values() {
2538 let values = [1.0, 1e-100, -1.0]
2539 .iter()
2540 .map(|&v| RealValidated::try_new_validated(v).unwrap())
2541 .collect::<Vec<_>>();
2542 let sum = values.iter().cloned().sum::<RealValidated>();
2543 assert_eq!(sum, 1e-100);
2544
2545 let neumaier = NeumaierSum::new_sequential(values);
2546 assert_eq!(neumaier.sum(), 1e-100);
2547 println!("compensated sum = {}", neumaier.sum());
2548 }
2549 }
2550
2551 mod complex {
2552 use super::*;
2553
2554 #[test]
2555 fn new() {
2556 let neumaier = NeumaierSum::new(
2557 ComplexValidated::try_new_validated(Complex::new(1.0, 2.0)).unwrap(),
2558 );
2559 assert_eq!(
2560 neumaier.sum_before_compensation().as_ref(),
2561 &Complex::new(1.0, 2.0)
2562 );
2563 assert_eq!(neumaier.compensation().as_ref(), &Complex::new(0.0, 0.0));
2564 }
2565
2566 #[test]
2567 fn zero() {
2568 let neumaier = NeumaierSum::<ComplexValidated>::zero();
2569
2570 let zero = Complex::new(0.0, 0.0);
2571 assert_eq!(neumaier.sum_before_compensation().as_ref(), &zero);
2572 assert_eq!(neumaier.compensation().as_ref(), &zero);
2573 }
2574
2575 #[test]
2576 fn add() {
2577 let zero = Complex::new(0.0, 0.0);
2578 let v = Complex::new(1e-16, 2e-16);
2579
2580 let mut neumaier = NeumaierSum::zero();
2581 neumaier.add(ComplexValidated::try_new_validated(Complex::new(1.0, 2.0)).unwrap());
2582 neumaier.add(ComplexValidated::try_new_validated(v).unwrap());
2583 neumaier
2584 .add(ComplexValidated::try_new_validated(Complex::new(-1.0, -2.0)).unwrap());
2585
2586 assert_eq!(neumaier.sum_before_compensation().as_ref(), &zero);
2587 assert_eq!(neumaier.compensation().as_ref(), &v);
2588 }
2589
2590 #[test]
2591 fn sum() {
2592 let zero = Complex::new(0.0, 0.0);
2593 let v = Complex::new(1e-16, 2e-16);
2594
2595 let mut neumaier = NeumaierSum::zero();
2596 neumaier.add(ComplexValidated::try_new_validated(Complex::new(1.0, 2.0)).unwrap());
2597 neumaier.add(ComplexValidated::try_new_validated(v).unwrap());
2598 neumaier
2599 .add(ComplexValidated::try_new_validated(Complex::new(-1.0, -2.0)).unwrap());
2600 assert_eq!(neumaier.sum_before_compensation().as_ref(), &zero);
2601 assert_eq!(neumaier.compensation().as_ref(), &v);
2602 assert_eq!(neumaier.sum().as_ref(), &v);
2603 println!("compensated sum = {}", neumaier.sum());
2604 }
2605
2606 #[test]
2607 fn reset() {
2608 let zero = Complex::new(0.0, 0.0);
2609 let a = Complex::new(1.0, 2.0);
2610 let v = Complex::new(1e-16, 2e-16);
2611
2612 let mut neumaier = NeumaierSum::zero();
2613 neumaier.add(ComplexValidated::try_new_validated(a).unwrap());
2614 neumaier.add(ComplexValidated::try_new_validated(v).unwrap());
2615 assert_eq!(neumaier.sum_before_compensation().as_ref(), &a);
2616 assert_eq!(neumaier.compensation().as_ref(), &v);
2617
2618 neumaier.reset();
2619 assert_eq!(neumaier.sum_before_compensation().as_ref(), &zero);
2620 assert_eq!(neumaier.compensation().as_ref(), &zero);
2621 }
2622
2623 #[test]
2624 fn sum_big_values() {
2625 let values = [
2626 Complex::new(1.0, 2.0),
2627 Complex::new(1e100, 2e100),
2628 Complex::new(1.0, 2.0),
2629 Complex::new(-1e100, -2e100),
2630 ]
2631 .iter()
2632 .map(|&v| ComplexValidated::try_new_validated(v).unwrap())
2633 .collect::<Vec<_>>();
2634 let sum = values.clone().into_iter().sum::<ComplexValidated>();
2635 let expected_sum = Complex::new(2., 4.);
2636 assert_eq!(sum.as_ref(), &expected_sum);
2637
2638 let neumaier = NeumaierSum::new_sequential(values);
2639 assert_eq!(neumaier.sum().as_ref(), &expected_sum);
2640 println!("compensated sum = {}", neumaier.sum());
2641 }
2642
2643 #[test]
2644 fn sum_small_values() {
2645 let v = Complex::new(1e-100, 2e-100);
2646
2647 let values = [Complex::new(1.0, 2.0), v, Complex::new(-1.0, -2.0)]
2648 .iter()
2649 .map(|&v| ComplexValidated::try_new_validated(v).unwrap())
2650 .collect::<Vec<_>>();
2651 let sum = values.iter().cloned().sum::<ComplexValidated>();
2652 let sum_expected = v;
2653 assert_eq!(sum.as_ref(), &sum_expected);
2654
2655 let neumaier = NeumaierSum::new_sequential(values);
2656 assert_eq!(neumaier.sum().as_ref(), &sum_expected);
2657 println!("compensated sum = {}", neumaier.sum());
2658 }
2659 }
2660 }
2661
2662 mod random {
2663 use super::*;
2664 use crate::{
2665 RandomSampleFromF64,
2666 kernels::native64_validated::{ComplexNative64StrictFinite, RealNative64StrictFinite},
2667 new_random_vec,
2668 };
2669 use rand::{Rng, SeedableRng, distr::Uniform, rngs::StdRng};
2670
2671 #[test]
2675 fn test_random_real_validated() {
2676 let seed = [42; 32];
2677 let mut rng = StdRng::from_seed(seed);
2678
2679 let random_real: RealNative64StrictFinite = rng.random();
2680
2681 assert_eq!(random_real, 0.23713468825474326);
2683
2684 let mut rng2 = StdRng::from_seed(seed);
2686 let random_real2: RealNative64StrictFinite = rng2.random();
2687 assert_eq!(random_real, random_real2);
2688 }
2689
2690 #[test]
2695 fn test_random_complex_validated() {
2696 let seed = [99; 32];
2697 let mut rng = StdRng::from_seed(seed);
2698
2699 let random_complex: ComplexNative64StrictFinite = rng.random();
2700
2701 let real_part = random_complex.real_part();
2704 let imag_part = random_complex.imag_part();
2705
2706 assert_eq!(real_part, 0.9995546882627792);
2707 assert_eq!(imag_part, 0.08932180682540247);
2708
2709 let mut rng2 = StdRng::from_seed(seed);
2711 let random_complex2: ComplexNative64StrictFinite = rng2.random();
2712 assert_eq!(random_complex, random_complex2);
2713 }
2714
2715 const SEED: [u8; 32] = [42; 32];
2716
2717 #[test]
2718 fn test_sample_real_validated() {
2719 let mut rng = StdRng::from_seed(SEED);
2720 let dist = Uniform::new(-10.0, 10.0).unwrap();
2721
2722 let val = RealNative64StrictFinite::sample_from(&dist, &mut rng);
2723 assert_eq!(val, -5.257306234905137);
2724
2725 let mut rng2 = StdRng::from_seed(SEED);
2727 let val2 = RealNative64StrictFinite::sample_from(&dist, &mut rng2);
2728 assert_eq!(val, val2);
2729 }
2730
2731 #[test]
2732 fn test_sample_complex_validated() {
2733 let mut rng = StdRng::from_seed(SEED);
2734 let dist = Uniform::new(-10.0, 10.0).unwrap();
2735
2736 let val = ComplexNative64StrictFinite::sample_from(&dist, &mut rng);
2737 assert_eq!(val.real_part(), -5.257306234905137);
2738 assert_eq!(val.imag_part(), 7.212119776268775);
2739
2740 let mut rng2 = StdRng::from_seed(SEED);
2742 let val2 = ComplexNative64StrictFinite::sample_from(&dist, &mut rng2);
2743 assert_eq!(val, val2);
2744 }
2745
2746 #[test]
2747 fn new_random_vec_real() {
2748 let mut rng = StdRng::from_seed(SEED);
2749 let dist = Uniform::new(-10.0, 10.0).unwrap();
2750 let vec: Vec<RealNative64StrictFinite> = new_random_vec(3, &dist, &mut rng);
2751 assert_eq!(vec.len(), 3);
2752 assert_eq!(vec[0], -5.257306234905137);
2753 assert_eq!(vec[1], 7.212119776268775);
2754 assert_eq!(vec[2], -4.666248990558111);
2755
2756 let mut rng2 = StdRng::from_seed(SEED);
2758 let vec2: Vec<RealNative64StrictFinite> = new_random_vec(3, &dist, &mut rng2);
2759 assert_eq!(vec, vec2);
2760 }
2761
2762 #[test]
2763 fn new_random_vec_complex() {
2764 let mut rng = StdRng::from_seed(SEED);
2765 let dist = Uniform::new(-10.0, 10.0).unwrap();
2766 let vec: Vec<ComplexNative64StrictFinite> = new_random_vec(3, &dist, &mut rng);
2767 assert_eq!(vec.len(), 3);
2768 assert_eq!(vec[0].real_part(), -5.257306234905137);
2769 assert_eq!(vec[0].imag_part(), 7.212119776268775);
2770 assert_eq!(vec[1].real_part(), -4.666248990558111);
2771 assert_eq!(vec[1].imag_part(), 9.66047141517383);
2772 assert_eq!(vec[2].real_part(), -9.04279551029691);
2773 assert_eq!(vec[2].imag_part(), -1.026624649331671);
2774
2775 let mut rng2 = StdRng::from_seed(SEED);
2777 let vec2: Vec<ComplexNative64StrictFinite> = new_random_vec(3, &dist, &mut rng2);
2778 assert_eq!(vec, vec2);
2779 }
2780 }
2781
2782 mod hash_map_key_usage {
2783 use crate::{
2784 functions::Sign,
2785 kernels::native64_validated::{
2786 ComplexNative64StrictFinite, RealNative64StrictFinite,
2787 RealNative64StrictFiniteInDebug,
2788 },
2789 };
2790 use num::Complex;
2791 use std::collections::HashMap;
2792 use try_create::TryNew;
2793
2794 #[test]
2795 fn test_native64_as_hashmap_key() {
2796 let mut map = HashMap::new();
2797 let key1 = RealNative64StrictFinite::try_new(1.0).unwrap();
2798 let key2 = RealNative64StrictFinite::try_new(2.5).unwrap();
2799
2800 map.insert(key1, "one");
2801 map.insert(key2, "two_point_five");
2802
2803 assert_eq!(
2804 map.get(&RealNative64StrictFinite::try_new(1.0).unwrap()),
2805 Some(&"one")
2806 );
2807 assert_eq!(map.len(), 2);
2808
2809 let old_value = map.insert(key1, "new_one");
2811 assert_eq!(old_value, Some("one"));
2812 assert_eq!(map.get(&key1), Some(&"new_one"));
2813 }
2814
2815 #[test]
2816 fn test_native64_debug_as_hashmap_key() {
2817 let mut map = HashMap::new();
2818 let key1 = RealNative64StrictFiniteInDebug::try_new(1.0).unwrap();
2819 let key2 = RealNative64StrictFiniteInDebug::try_new(2.5).unwrap();
2820
2821 map.insert(key1, "one_debug");
2822 map.insert(key2, "two_point_five_debug");
2823
2824 assert_eq!(
2825 map.get(&RealNative64StrictFiniteInDebug::try_new(1.0).unwrap()),
2826 Some(&"one_debug")
2827 );
2828 assert_eq!(map.len(), 2);
2829
2830 let old_value = map.insert(key1, "new_one_debug");
2832 assert_eq!(old_value, Some("one_debug"));
2833 assert_eq!(map.get(&key1), Some(&"new_one_debug"));
2834 }
2835
2836 #[test]
2837 fn test_hashmap_basic_operations() {
2838 let mut map = HashMap::new();
2839 let key1 = RealNative64StrictFinite::try_new(1.0).unwrap();
2840 let key2 = RealNative64StrictFinite::try_new(2.5).unwrap();
2841 let key3 = RealNative64StrictFinite::try_new(1.0).unwrap(); assert_eq!(map.insert(key1, "one"), None);
2845 assert_eq!(map.insert(key2, "two_point_five"), None);
2846 assert_eq!(map.len(), 2);
2847
2848 assert_eq!(map.get(&key3), Some(&"one"));
2850
2851 assert_eq!(map.insert(key3, "one_updated"), Some("one"));
2853 assert_eq!(map.len(), 2); }
2855
2856 #[test]
2857 fn test_hashset_operations() {
2858 use std::collections::HashSet;
2859 let mut set = HashSet::new();
2860
2861 let val1 = RealNative64StrictFinite::try_new(1.0).unwrap();
2862 let val2 = RealNative64StrictFinite::try_new(2.0).unwrap();
2863 let val1_duplicate = RealNative64StrictFinite::try_new(1.0).unwrap();
2864
2865 assert!(set.insert(val1));
2866 assert!(set.insert(val2));
2867 assert!(!set.insert(val1_duplicate)); assert_eq!(set.len(), 2);
2870 assert!(set.contains(&RealNative64StrictFinite::try_new(1.0).unwrap()));
2871 }
2872
2873 #[test]
2874 fn test_hash_consistency() {
2875 use std::collections::hash_map::DefaultHasher;
2876 use std::hash::{Hash, Hasher};
2877
2878 let val1 = RealNative64StrictFinite::try_new(1.234).unwrap();
2879 let val2 = RealNative64StrictFinite::try_new(1.234).unwrap();
2880
2881 let mut hasher1 = DefaultHasher::new();
2883 let mut hasher2 = DefaultHasher::new();
2884
2885 val1.hash(&mut hasher1);
2886 val2.hash(&mut hasher2);
2887
2888 assert_eq!(hasher1.finish(), hasher2.finish());
2889 assert_eq!(val1, val2); }
2891
2892 #[test]
2893 fn test_hash_signed_zero() {
2894 use std::collections::hash_map::DefaultHasher;
2895 use std::hash::{Hash, Hasher};
2896
2897 let val1 = RealNative64StrictFinite::try_new(0.0).unwrap();
2898 assert!(val1.kernel_is_sign_positive());
2899 let val2 = RealNative64StrictFinite::try_new(-0.0).unwrap();
2900 assert!(val2.kernel_is_sign_negative());
2901
2902 assert_ne!(
2904 0.0f64.to_bits(),
2905 (-0.0f64).to_bits(),
2906 "Sanity check: +0.0 and -0.0 should have different bit patterns"
2907 );
2908
2909 assert_eq!(val1, val2); let mut hasher1 = DefaultHasher::new();
2913 let mut hasher2 = DefaultHasher::new();
2914
2915 val1.hash(&mut hasher1);
2916 val2.hash(&mut hasher2);
2917
2918 assert_eq!(hasher1.finish(), hasher2.finish());
2919 }
2920
2921 #[test]
2922 fn test_complex_as_hashmap_key() {
2923 let mut map = HashMap::new();
2924 let key1 = ComplexNative64StrictFinite::try_new(Complex::new(1.0, 2.0)).unwrap();
2925 let key2 = ComplexNative64StrictFinite::try_new(Complex::new(3.0, 4.0)).unwrap();
2926
2927 map.insert(key1, "one_plus_two_i");
2928 map.insert(key2, "three_plus_four_i");
2929
2930 assert_eq!(
2931 map.get(&ComplexNative64StrictFinite::try_new(Complex::new(1.0, 2.0)).unwrap()),
2932 Some(&"one_plus_two_i")
2933 );
2934 assert_eq!(map.len(), 2);
2935
2936 let old_value = map.insert(key1, "updated_complex");
2938 assert_eq!(old_value, Some("one_plus_two_i"));
2939 assert_eq!(map.get(&key1), Some(&"updated_complex"));
2940 }
2941
2942 #[test]
2943 fn test_complex_hash_consistency() {
2944 use std::collections::hash_map::DefaultHasher;
2945 use std::hash::{Hash, Hasher};
2946
2947 let val1 = ComplexNative64StrictFinite::try_new(Complex::new(1.234, 5.678)).unwrap();
2948 let val2 = ComplexNative64StrictFinite::try_new(Complex::new(1.234, 5.678)).unwrap();
2949
2950 let mut hasher1 = DefaultHasher::new();
2952 let mut hasher2 = DefaultHasher::new();
2953
2954 val1.hash(&mut hasher1);
2955 val2.hash(&mut hasher2);
2956
2957 assert_eq!(hasher1.finish(), hasher2.finish());
2958 assert_eq!(val1, val2); }
2960
2961 #[test]
2962 fn test_complex_hash_signed_zero() {
2963 use std::collections::hash_map::DefaultHasher;
2964 use std::hash::{Hash, Hasher};
2965
2966 let val1 = ComplexNative64StrictFinite::try_new(Complex::new(0.0, 0.0)).unwrap();
2968 let val2 = ComplexNative64StrictFinite::try_new(Complex::new(-0.0, 0.0)).unwrap();
2969 let val3 = ComplexNative64StrictFinite::try_new(Complex::new(0.0, -0.0)).unwrap();
2970 let val4 = ComplexNative64StrictFinite::try_new(Complex::new(-0.0, -0.0)).unwrap();
2971
2972 assert_eq!(val1, val2);
2974 assert_eq!(val1, val3);
2975 assert_eq!(val1, val4);
2976
2977 let mut hasher1 = DefaultHasher::new();
2979 let mut hasher2 = DefaultHasher::new();
2980 let mut hasher3 = DefaultHasher::new();
2981 let mut hasher4 = DefaultHasher::new();
2982
2983 val1.hash(&mut hasher1);
2984 val2.hash(&mut hasher2);
2985 val3.hash(&mut hasher3);
2986 val4.hash(&mut hasher4);
2987
2988 let hash1 = hasher1.finish();
2989 let hash2 = hasher2.finish();
2990 let hash3 = hasher3.finish();
2991 let hash4 = hasher4.finish();
2992
2993 assert_eq!(hash1, hash2);
2994 assert_eq!(hash1, hash3);
2995 assert_eq!(hash1, hash4);
2996 }
2997
2998 #[test]
2999 fn test_complex_different_values_different_hashes() {
3000 use std::collections::hash_map::DefaultHasher;
3001 use std::hash::{Hash, Hasher};
3002
3003 let val1 = ComplexNative64StrictFinite::try_new(Complex::new(1.0, 2.0)).unwrap();
3004 let val2 = ComplexNative64StrictFinite::try_new(Complex::new(2.0, 1.0)).unwrap();
3005 let val3 = ComplexNative64StrictFinite::try_new(Complex::new(1.0, 2.001)).unwrap();
3006
3007 let mut hasher1 = DefaultHasher::new();
3009 let mut hasher2 = DefaultHasher::new();
3010 let mut hasher3 = DefaultHasher::new();
3011
3012 val1.hash(&mut hasher1);
3013 val2.hash(&mut hasher2);
3014 val3.hash(&mut hasher3);
3015
3016 let hash1 = hasher1.finish();
3017 let hash2 = hasher2.finish();
3018 let hash3 = hasher3.finish();
3019
3020 assert_ne!(val1, val2);
3022 assert_ne!(val1, val3);
3023 assert_ne!(hash1, hash2);
3024 assert_ne!(hash1, hash3);
3025 }
3026
3027 #[test]
3028 fn test_complex_hashset_operations() {
3029 use std::collections::HashSet;
3030
3031 let mut set = HashSet::new();
3032
3033 let val1 = ComplexNative64StrictFinite::try_new(Complex::new(1.0, 2.0)).unwrap();
3034 let val2 = ComplexNative64StrictFinite::try_new(Complex::new(3.0, 4.0)).unwrap();
3035 let val1_duplicate =
3036 ComplexNative64StrictFinite::try_new(Complex::new(1.0, 2.0)).unwrap();
3037
3038 assert!(set.insert(val1));
3039 assert!(set.insert(val2));
3040 assert!(!set.insert(val1_duplicate)); assert_eq!(set.len(), 2);
3043 assert!(
3044 set.contains(
3045 &ComplexNative64StrictFinite::try_new(Complex::new(1.0, 2.0)).unwrap()
3046 )
3047 );
3048 }
3049 }
3050
3051 mod test_truncate_to_usize {
3052 use super::*;
3053 use crate::validation::ErrorsRawRealToInteger;
3054
3055 #[test]
3056 fn test_positive_integers() {
3057 let value = RealNative64StrictFinite::try_new(42.0).unwrap();
3059 assert_eq!(value.truncate_to_usize().unwrap(), 42);
3060
3061 let value = RealNative64StrictFinite::try_new(1.0).unwrap();
3062 assert_eq!(value.truncate_to_usize().unwrap(), 1);
3063
3064 let value = RealNative64StrictFinite::try_new(100.0).unwrap();
3065 assert_eq!(value.truncate_to_usize().unwrap(), 100);
3066 }
3067
3068 #[test]
3069 fn test_positive_fractionals_truncate() {
3070 let value = RealNative64StrictFinite::try_new(42.9).unwrap();
3072 assert_eq!(value.truncate_to_usize().unwrap(), 42);
3073
3074 let value = RealNative64StrictFinite::try_new(3.7).unwrap();
3075 assert_eq!(value.truncate_to_usize().unwrap(), 3);
3076
3077 let value = RealNative64StrictFinite::try_new(0.9).unwrap();
3078 assert_eq!(value.truncate_to_usize().unwrap(), 0);
3079
3080 let value = RealNative64StrictFinite::try_new(99.999).unwrap();
3081 assert_eq!(value.truncate_to_usize().unwrap(), 99);
3082 }
3083
3084 #[test]
3085 fn test_zero_cases() {
3086 let value = RealNative64StrictFinite::try_new(0.0).unwrap();
3088 assert_eq!(value.truncate_to_usize().unwrap(), 0);
3089
3090 let value = RealNative64StrictFinite::try_new(0.1).unwrap();
3092 assert_eq!(value.truncate_to_usize().unwrap(), 0);
3093
3094 let value = RealNative64StrictFinite::try_new(0.5).unwrap();
3095 assert_eq!(value.truncate_to_usize().unwrap(), 0);
3096 }
3097
3098 #[test]
3099 fn test_large_valid_values() {
3100 let value = RealNative64StrictFinite::try_new(1_000_000.7).unwrap();
3102 assert_eq!(value.truncate_to_usize().unwrap(), 1_000_000);
3103
3104 let value = RealNative64StrictFinite::try_new(1_000_000_000.0).unwrap();
3105 assert_eq!(value.truncate_to_usize().unwrap(), 1_000_000_000);
3106
3107 let max_safe = (usize::MAX as f64) - 2048.0; let value = RealNative64StrictFinite::try_new(max_safe).unwrap();
3110 let result = value.truncate_to_usize().unwrap();
3111 assert!(result < usize::MAX);
3112 }
3113
3114 #[test]
3115 fn test_negative_values_error() {
3116 let value = RealNative64StrictFinite::try_new(-1.0).unwrap();
3118 let result = value.truncate_to_usize();
3119 assert!(matches!(
3120 result,
3121 Err(ErrorsRawRealToInteger::OutOfRange { .. })
3122 ));
3123
3124 let value = RealNative64StrictFinite::try_new(-10.5).unwrap();
3125 let result = value.truncate_to_usize();
3126 assert!(matches!(
3127 result,
3128 Err(ErrorsRawRealToInteger::OutOfRange { .. })
3129 ));
3130
3131 let value = RealNative64StrictFinite::try_new(-0.1).unwrap();
3132 let result = value.truncate_to_usize();
3133 assert!(matches!(result, Ok(0)));
3134
3135 let value = RealNative64StrictFinite::try_new(-1000.0).unwrap();
3136 let result = value.truncate_to_usize();
3137 assert!(matches!(
3138 result,
3139 Err(ErrorsRawRealToInteger::OutOfRange { .. })
3140 ));
3141 }
3142
3143 #[test]
3144 fn test_too_large_values_error() {
3145 let too_large = (usize::MAX as f64) * 2.0;
3147 let value = RealNative64StrictFinite::try_new(too_large).unwrap();
3148 let result = value.truncate_to_usize();
3149 assert!(matches!(
3150 result,
3151 Err(ErrorsRawRealToInteger::OutOfRange { .. })
3152 ));
3153
3154 let value = RealNative64StrictFinite::try_new(1e20).unwrap();
3155 let result = value.truncate_to_usize();
3156 assert!(matches!(
3157 result,
3158 Err(ErrorsRawRealToInteger::OutOfRange { .. })
3159 ));
3160 }
3161
3162 #[test]
3163 fn test_edge_cases() {
3164 let value = RealNative64StrictFinite::try_new(f64::EPSILON).unwrap();
3168 assert_eq!(value.truncate_to_usize().unwrap(), 0);
3169
3170 let value = RealNative64StrictFinite::try_new(1.0 - f64::EPSILON).unwrap();
3172 assert_eq!(value.truncate_to_usize().unwrap(), 0);
3173
3174 let value = RealNative64StrictFinite::try_new(1.0 + f64::EPSILON).unwrap();
3176 assert_eq!(value.truncate_to_usize().unwrap(), 1);
3177 }
3178
3179 #[test]
3180 fn test_truncation_behavior() {
3181 let test_cases = [
3183 (2.1, 2),
3184 (2.5, 2), (2.9, 2),
3186 (3.0, 3),
3187 (3.1, 3),
3188 (99.999, 99),
3189 ];
3190
3191 for (input, expected) in test_cases {
3192 let value = RealNative64StrictFinite::try_new(input)
3193 .unwrap()
3194 .truncate_to_usize()
3195 .unwrap();
3196 assert_eq!(
3197 value, expected,
3198 "Failed for input {}: expected {}, got {:?}",
3199 input, expected, value
3200 );
3201 }
3202 }
3203
3204 #[test]
3205 fn test_error_details() {
3206 let value = RealNative64StrictFinite::try_new(-5.0).unwrap();
3210 if let Err(ErrorsRawRealToInteger::OutOfRange {
3211 value: err_val,
3212 min,
3213 max,
3214 ..
3215 }) = value.truncate_to_usize()
3216 {
3217 assert_eq!(err_val, -5.0);
3218 assert_eq!(min, usize::MIN);
3219 assert_eq!(max, usize::MAX);
3220 } else {
3221 panic!("Expected OutOfRange error for negative value");
3222 }
3223
3224 let large_value = 1e20;
3226 let value = RealNative64StrictFinite::try_new(large_value).unwrap();
3227 if let Err(ErrorsRawRealToInteger::OutOfRange {
3228 value: err_val,
3229 min,
3230 max,
3231 ..
3232 }) = value.truncate_to_usize()
3233 {
3234 assert_eq!(err_val, large_value);
3235 assert_eq!(min, usize::MIN);
3236 assert_eq!(max, usize::MAX);
3237 } else {
3238 panic!("Expected OutOfRange error for large value");
3239 }
3240 }
3241
3242 #[test]
3243 fn test_practical_usage_scenario() {
3244 fn create_vector_with_calculated_size<T: Default + Clone>(
3246 size_float: RealNative64StrictFinite,
3247 ) -> Result<Vec<T>, Box<dyn std::error::Error>> {
3248 let size = size_float.truncate_to_usize()?;
3249 Ok(vec![T::default(); size])
3250 }
3251
3252 let calculated_size = RealNative64StrictFinite::try_new(10.7).unwrap();
3254 let vec: Vec<i32> = create_vector_with_calculated_size(calculated_size).unwrap();
3255 assert_eq!(vec.len(), 10); let negative_size = RealNative64StrictFinite::try_new(-5.0).unwrap();
3259 let result: Result<Vec<i32>, _> = create_vector_with_calculated_size(negative_size);
3260 assert!(result.is_err());
3261
3262 let huge_size = RealNative64StrictFinite::try_new(1e20).unwrap();
3264 let result: Result<Vec<i32>, _> = create_vector_with_calculated_size(huge_size);
3265 assert!(result.is_err());
3266 }
3267
3268 #[test]
3269 fn test_consistency_with_f64_behavior() {
3270 let test_values = [0.0, 1.0, 2.5, 42.9, 100.0, 0.1, 0.9];
3272
3273 for &val in &test_values {
3274 let validated = RealNative64StrictFinite::try_new(val).unwrap();
3275 let result = validated.truncate_to_usize().unwrap();
3276
3277 let expected = val.trunc() as usize;
3279 assert_eq!(result, expected, "Mismatch for value {}", val);
3280 }
3281 }
3282 }
3283
3284 mod bytemuck_conversions {
3285 use super::*;
3286 use bytemuck::checked::{CheckedCastError, try_from_bytes};
3287
3288 mod real_strict_finite {
3289 use super::*;
3290
3291 #[test]
3292 fn valid_value_from_bytes() {
3293 let value = 42.0_f64;
3294 let bytes = value.to_ne_bytes();
3295
3296 let result: Result<&RealNative64StrictFinite, CheckedCastError> =
3297 try_from_bytes(&bytes);
3298 assert!(result.is_ok());
3299 assert_eq!(*result.unwrap().as_ref(), 42.0);
3300 }
3301
3302 #[test]
3303 fn valid_value_try_cast() {
3304 let value = 42.0_f64;
3305 let bytes = value.to_ne_bytes();
3306 let result: Result<&RealNative64StrictFinite, CheckedCastError> =
3307 try_from_bytes(&bytes);
3308 assert!(result.is_ok());
3309 assert_eq!(*result.unwrap().as_ref(), 42.0);
3310 }
3311
3312 #[test]
3313 fn zero_from_bytes() {
3314 let value = 0.0_f64;
3315 let bytes = value.to_ne_bytes();
3316
3317 let result: Result<&RealNative64StrictFinite, CheckedCastError> =
3318 try_from_bytes(&bytes);
3319 assert!(result.is_ok());
3320 assert_eq!(*result.unwrap().as_ref(), 0.0);
3321 }
3322
3323 #[test]
3324 fn negative_zero_from_bytes() {
3325 let value = -0.0_f64;
3326 let bytes = value.to_ne_bytes();
3327
3328 let result: Result<&RealNative64StrictFinite, CheckedCastError> =
3329 try_from_bytes(&bytes);
3330 assert!(result.is_ok());
3331 assert_eq!(*result.unwrap().as_ref(), -0.0);
3332 }
3333
3334 #[test]
3335 fn max_value_from_bytes() {
3336 let value = f64::MAX;
3337 let bytes = value.to_ne_bytes();
3338
3339 let result: Result<&RealNative64StrictFinite, CheckedCastError> =
3340 try_from_bytes(&bytes);
3341 assert!(result.is_ok());
3342 assert_eq!(*result.unwrap().as_ref(), f64::MAX);
3343 }
3344
3345 #[test]
3346 fn min_value_from_bytes() {
3347 let value = f64::MIN;
3348 let bytes = value.to_ne_bytes();
3349
3350 let result: Result<&RealNative64StrictFinite, CheckedCastError> =
3351 try_from_bytes(&bytes);
3352 assert!(result.is_ok());
3353 assert_eq!(*result.unwrap().as_ref(), f64::MIN);
3354 }
3355
3356 #[test]
3357 fn nan_from_bytes_fails() {
3358 let value = f64::NAN;
3359 let bytes = value.to_ne_bytes();
3360
3361 let result: Result<&RealNative64StrictFinite, CheckedCastError> =
3362 try_from_bytes(&bytes);
3363 assert!(result.is_err());
3364 assert!(matches!(result, Err(CheckedCastError::InvalidBitPattern)));
3365 }
3366
3367 #[test]
3368 fn nan_try_cast_fails() {
3369 let value = f64::NAN;
3370 let bytes = value.to_ne_bytes();
3371 let result: Result<&RealNative64StrictFinite, CheckedCastError> =
3372 try_from_bytes(&bytes);
3373 assert!(result.is_err());
3374 assert!(matches!(result, Err(CheckedCastError::InvalidBitPattern)));
3375 }
3376
3377 #[test]
3378 fn infinity_from_bytes_fails() {
3379 let value = f64::INFINITY;
3380 let bytes = value.to_ne_bytes();
3381
3382 let result: Result<&RealNative64StrictFinite, CheckedCastError> =
3383 try_from_bytes(&bytes);
3384 assert!(result.is_err());
3385 assert!(matches!(result, Err(CheckedCastError::InvalidBitPattern)));
3386 }
3387
3388 #[test]
3389 fn neg_infinity_from_bytes_fails() {
3390 let value = f64::NEG_INFINITY;
3391 let bytes = value.to_ne_bytes();
3392
3393 let result: Result<&RealNative64StrictFinite, CheckedCastError> =
3394 try_from_bytes(&bytes);
3395 assert!(result.is_err());
3396 assert!(matches!(result, Err(CheckedCastError::InvalidBitPattern)));
3397 }
3398
3399 #[test]
3400 fn subnormal_from_bytes_fails() {
3401 let value = f64::MIN_POSITIVE / 2.0; let bytes = value.to_ne_bytes();
3403
3404 let result: Result<&RealNative64StrictFinite, CheckedCastError> =
3405 try_from_bytes(&bytes);
3406 assert!(result.is_err());
3407 assert!(matches!(result, Err(CheckedCastError::InvalidBitPattern)));
3408 }
3409
3410 #[test]
3411 fn round_trip_conversion() {
3412 let original = RealNative64StrictFinite::try_new(123.456).unwrap();
3413 let as_f64 = *original.as_ref();
3414 let bytes = as_f64.to_ne_bytes();
3415
3416 let from_bytes: &RealNative64StrictFinite = try_from_bytes(&bytes).unwrap();
3417 assert_eq!(original, *from_bytes);
3418 }
3419
3420 #[test]
3421 fn vec_conversion() {
3422 let values = vec![
3423 RealNative64StrictFinite::try_new(1.0).unwrap(),
3424 RealNative64StrictFinite::try_new(2.0).unwrap(),
3425 RealNative64StrictFinite::try_new(3.0).unwrap(),
3426 RealNative64StrictFinite::try_new(4.0).unwrap(),
3427 ];
3428
3429 let bytes = bytemuck::cast_slice::<RealNative64StrictFinite, u8>(&values);
3431
3432 let result: Result<&[RealNative64StrictFinite], CheckedCastError> =
3434 bytemuck::checked::try_cast_slice(bytes);
3435 assert!(result.is_ok());
3436
3437 let validated_slice = result.unwrap();
3438 assert_eq!(validated_slice.len(), 4);
3439 assert_eq!(*validated_slice[0].as_ref(), 1.0);
3440 assert_eq!(*validated_slice[3].as_ref(), 4.0);
3441 }
3442
3443 #[test]
3444 fn direct_f64_slice_with_invalid_values() {
3445 let mut bytes = Vec::new();
3447 bytes.extend_from_slice(&1.0_f64.to_ne_bytes());
3448 bytes.extend_from_slice(&f64::NAN.to_ne_bytes());
3449 bytes.extend_from_slice(&3.0_f64.to_ne_bytes());
3450
3451 let result: Result<&[RealNative64StrictFinite], CheckedCastError> =
3453 bytemuck::checked::try_cast_slice(&bytes);
3454 assert!(result.is_err());
3455 }
3456 }
3457
3458 mod vec_conversions {
3459 use super::*;
3460 use try_create::TryNew;
3461
3462 #[test]
3463 fn vec_f64_to_validated_all_valid() {
3464 let f64_vec = [1.0, 2.5, -3.7, 0.0, 42.0];
3466
3467 let validated_vec: Result<Vec<RealNative64StrictFinite>, _> = f64_vec
3469 .iter()
3470 .map(|&x| RealNative64StrictFinite::try_new(x))
3471 .collect();
3472
3473 assert!(validated_vec.is_ok());
3474 let validated_vec = validated_vec.unwrap();
3475
3476 assert_eq!(validated_vec.len(), 5);
3478
3479 assert_eq!(*validated_vec[0].as_ref(), 1.0);
3481 assert_eq!(*validated_vec[1].as_ref(), 2.5);
3482 assert_eq!(*validated_vec[2].as_ref(), -3.7);
3483 assert_eq!(*validated_vec[3].as_ref(), 0.0);
3484 assert_eq!(*validated_vec[4].as_ref(), 42.0);
3485 }
3486
3487 #[test]
3488 fn vec_f64_to_validated_with_nan() {
3489 let f64_vec = [1.0, 2.5, f64::NAN, 0.0, 42.0];
3491
3492 let validated_vec: Result<Vec<RealNative64StrictFinite>, _> = f64_vec
3494 .iter()
3495 .map(|&x| RealNative64StrictFinite::try_new(x))
3496 .collect();
3497
3498 assert!(validated_vec.is_err());
3499 }
3500
3501 #[test]
3502 fn vec_f64_to_validated_with_infinity() {
3503 let f64_vec = [1.0, f64::INFINITY, 3.0];
3505
3506 let validated_vec: Result<Vec<RealNative64StrictFinite>, _> = f64_vec
3508 .iter()
3509 .map(|&x| RealNative64StrictFinite::try_new(x))
3510 .collect();
3511
3512 assert!(validated_vec.is_err());
3513 }
3514
3515 #[test]
3516 fn vec_f64_to_validated_with_subnormal() {
3517 let subnormal = f64::MIN_POSITIVE / 2.0;
3519 let f64_vec = [1.0, subnormal, 3.0];
3520
3521 let validated_vec: Result<Vec<RealNative64StrictFinite>, _> = f64_vec
3523 .iter()
3524 .map(|&x| RealNative64StrictFinite::try_new(x))
3525 .collect();
3526
3527 assert!(validated_vec.is_err());
3528 }
3529
3530 #[test]
3531 fn vec_validated_to_f64() {
3532 let validated_vec = [
3534 RealNative64StrictFinite::try_new(1.0).unwrap(),
3535 RealNative64StrictFinite::try_new(2.5).unwrap(),
3536 RealNative64StrictFinite::try_new(-3.7).unwrap(),
3537 RealNative64StrictFinite::try_new(0.0).unwrap(),
3538 RealNative64StrictFinite::try_new(42.0).unwrap(),
3539 ];
3540
3541 let f64_vec: Vec<f64> = validated_vec.iter().map(|x| *x.as_ref()).collect();
3543
3544 assert_eq!(f64_vec.len(), 5);
3546
3547 assert_eq!(f64_vec[0], 1.0);
3549 assert_eq!(f64_vec[1], 2.5);
3550 assert_eq!(f64_vec[2], -3.7);
3551 assert_eq!(f64_vec[3], 0.0);
3552 assert_eq!(f64_vec[4], 42.0);
3553 }
3554
3555 #[test]
3556 fn vec_round_trip_conversion() {
3557 let original_f64 = vec![1.0, 2.5, -3.7, 0.0, 42.0, -999.123];
3559
3560 let validated_vec: Vec<RealNative64StrictFinite> = original_f64
3562 .iter()
3563 .map(|&x| RealNative64StrictFinite::try_new(x).unwrap())
3564 .collect();
3565
3566 let final_f64: Vec<f64> = validated_vec.iter().map(|x| *x.as_ref()).collect();
3568
3569 let slice_f64 =
3570 bytemuck::cast_slice::<RealNative64StrictFinite, f64>(&validated_vec);
3571 assert_eq!(slice_f64, &original_f64);
3572
3573 assert_eq!(original_f64, final_f64);
3575 }
3576
3577 #[test]
3578 fn vec_empty() {
3579 let f64_vec: Vec<f64> = vec![];
3581
3582 let validated_vec: Result<Vec<RealNative64StrictFinite>, _> = f64_vec
3584 .iter()
3585 .map(|&x| RealNative64StrictFinite::try_new(x))
3586 .collect();
3587
3588 assert!(validated_vec.is_ok());
3589 assert_eq!(validated_vec.unwrap().len(), 0);
3590 }
3591
3592 #[test]
3593 fn vec_large_values() {
3594 let f64_vec = vec![f64::MAX, f64::MIN, f64::MIN_POSITIVE, -f64::MIN_POSITIVE];
3596
3597 let validated_vec: Result<Vec<RealNative64StrictFinite>, _> = f64_vec
3599 .iter()
3600 .map(|&x| RealNative64StrictFinite::try_new(x))
3601 .collect();
3602
3603 assert!(validated_vec.is_ok());
3604 let validated_vec = validated_vec.unwrap();
3605
3606 let f64_back: Vec<f64> = validated_vec.iter().map(|x| *x.as_ref()).collect();
3608
3609 assert_eq!(f64_vec, f64_back);
3610 }
3611
3612 #[test]
3613 fn vec_with_zeros() {
3614 let f64_vec = [0.0, -0.0, 1.0, -1.0];
3616
3617 let validated_vec: Result<Vec<RealNative64StrictFinite>, _> = f64_vec
3618 .iter()
3619 .map(|&x| RealNative64StrictFinite::try_new(x))
3620 .collect();
3621
3622 assert!(validated_vec.is_ok());
3623 let validated_vec = validated_vec.unwrap();
3624
3625 assert_eq!(*validated_vec[0].as_ref(), 0.0);
3626 assert_eq!(*validated_vec[1].as_ref(), -0.0);
3627 }
3628
3629 #[test]
3630 fn vec_using_from_iter() {
3631 let f64_vec = [1.0, 2.0, 3.0, 4.0, 5.0];
3633
3634 let validated_vec: Vec<RealNative64StrictFinite> = f64_vec
3636 .iter()
3637 .filter_map(|&x| RealNative64StrictFinite::try_new(x).ok())
3638 .collect();
3639
3640 assert_eq!(validated_vec.len(), 5);
3641 }
3642
3643 #[test]
3644 fn vec_conversion_preserves_order() {
3645 let f64_vec: Vec<f64> = (0..100).map(|i| i as f64 * 0.1).collect();
3647
3648 let validated_vec: Vec<RealNative64StrictFinite> = f64_vec
3649 .iter()
3650 .map(|&x| RealNative64StrictFinite::try_new(x).unwrap())
3651 .collect();
3652
3653 for (i, val) in validated_vec.iter().enumerate() {
3655 assert_eq!(*val.as_ref(), i as f64 * 0.1);
3656 }
3657 }
3658
3659 #[test]
3660 fn vec_partial_conversion_with_find() {
3661 let f64_vec = [1.0, 2.0, f64::NAN, 4.0, 5.0];
3663
3664 let (invalid_idx, _) = f64_vec
3666 .iter()
3667 .enumerate()
3668 .find(|(_, x)| RealNative64StrictFinite::try_new(**x).is_err())
3669 .expect("Should find invalid value");
3670
3671 assert_eq!(invalid_idx, 2);
3672 }
3673
3674 #[test]
3675 fn vec_consume_and_convert() {
3676 let f64_vec = vec![1.0, 2.0, 3.0];
3678
3679 let validated_vec: Result<Vec<RealNative64StrictFinite>, _> = f64_vec
3680 .into_iter()
3681 .map(RealNative64StrictFinite::try_new)
3682 .collect();
3683
3684 assert!(validated_vec.is_ok());
3685 assert_eq!(validated_vec.unwrap().len(), 3);
3686
3687 }
3689
3690 #[test]
3691 fn vec_validated_to_f64_with_try_cast_vec() {
3692 use bytemuck::allocation::try_cast_vec;
3693
3694 let validated_vec: Vec<RealNative64StrictFinite> = vec![
3696 RealNative64StrictFinite::try_new(1.0).unwrap(),
3697 RealNative64StrictFinite::try_new(2.5).unwrap(),
3698 RealNative64StrictFinite::try_new(-3.7).unwrap(),
3699 RealNative64StrictFinite::try_new(0.0).unwrap(),
3700 RealNative64StrictFinite::try_new(42.0).unwrap(),
3701 ];
3702
3703 let f64_vec_result: Result<Vec<f64>, _> = try_cast_vec(validated_vec);
3705
3706 assert!(
3711 f64_vec_result.is_ok(),
3712 "try_cast_vec should work for Vec<RealNative64StrictFinite> -> Vec<f64>"
3713 );
3714
3715 let f64_vec = f64_vec_result.unwrap();
3716 assert_eq!(f64_vec.len(), 5);
3717 assert_eq!(f64_vec[0], 1.0);
3718 assert_eq!(f64_vec[1], 2.5);
3719 assert_eq!(f64_vec[2], -3.7);
3720 assert_eq!(f64_vec[3], 0.0);
3721 assert_eq!(f64_vec[4], 42.0);
3722 }
3723
3724 #[test]
3725 fn vec_f64_to_validated_try_cast_vec_fails() {
3726 let f64_vec = [1.0, 2.5, -3.7, 0.0, 42.0];
3728
3729 let validated_vec: Result<Vec<RealNative64StrictFinite>, _> = f64_vec
3738 .iter()
3739 .map(|&x| RealNative64StrictFinite::try_new(x))
3740 .collect();
3741
3742 assert!(validated_vec.is_ok());
3743 assert_eq!(validated_vec.unwrap().len(), 5);
3744 }
3745 }
3746
3747 mod real_strict_finite_in_debug {
3748 use super::*;
3749
3750 #[test]
3751 fn valid_value_from_bytes() {
3752 let value = 42.0_f64;
3753 let bytes = value.to_ne_bytes();
3754
3755 let result: Result<&RealNative64StrictFiniteInDebug, CheckedCastError> =
3756 try_from_bytes(&bytes);
3757 assert!(result.is_ok());
3758 assert_eq!(*result.unwrap().as_ref(), 42.0);
3759 }
3760
3761 #[test]
3762 fn nan_from_bytes() {
3763 let value = f64::NAN;
3764 let bytes = value.to_ne_bytes();
3765
3766 let result: Result<&RealNative64StrictFiniteInDebug, CheckedCastError> =
3767 try_from_bytes(&bytes);
3768
3769 #[cfg(debug_assertions)]
3770 {
3771 assert!(result.is_err());
3773 assert!(matches!(result, Err(CheckedCastError::InvalidBitPattern)));
3774 }
3775
3776 #[cfg(not(debug_assertions))]
3777 {
3778 assert!(result.is_ok());
3782 }
3783 }
3784
3785 #[test]
3786 fn infinity_from_bytes() {
3787 let value = f64::INFINITY;
3788 let bytes = value.to_ne_bytes();
3789
3790 let result: Result<&RealNative64StrictFiniteInDebug, CheckedCastError> =
3791 try_from_bytes(&bytes);
3792
3793 #[cfg(debug_assertions)]
3794 {
3795 assert!(result.is_err());
3796 }
3797
3798 #[cfg(not(debug_assertions))]
3799 {
3800 assert!(result.is_ok());
3801 }
3802 }
3803
3804 #[test]
3805 fn round_trip_with_valid_value() {
3806 let original = RealNative64StrictFiniteInDebug::try_new(123.456).unwrap();
3807 let as_f64 = *original.as_ref();
3808 let bytes = as_f64.to_ne_bytes();
3809
3810 let from_bytes: &RealNative64StrictFiniteInDebug = try_from_bytes(&bytes).unwrap();
3811 assert_eq!(original, *from_bytes);
3812 }
3813 }
3814
3815 #[test]
3816 fn alignment_check() {
3817 use std::mem;
3818
3819 assert_eq!(
3821 mem::align_of::<RealNative64StrictFinite>(),
3822 mem::align_of::<f64>()
3823 );
3824
3825 assert_eq!(
3827 mem::size_of::<RealNative64StrictFinite>(),
3828 mem::size_of::<f64>()
3829 );
3830 }
3831 }
3832
3833 mod copy_trait_tests {
3838 use super::*;
3839
3840 mod real_copy {
3841 use super::*;
3842
3843 #[test]
3844 fn real_is_copy() {
3845 fn assert_copy<T: Copy>() {}
3847 assert_copy::<RealNative64StrictFinite>();
3848 assert_copy::<RealNative64StrictFiniteInDebug>();
3849 }
3850
3851 #[test]
3852 fn real_copy_semantics() {
3853 let x = RealNative64StrictFinite::try_new(3.).unwrap();
3854 let y = x; let z = x; assert_eq!(x, y);
3857 assert_eq!(x, z);
3858 }
3859
3860 #[test]
3861 fn real_copy_in_function_call() {
3862 fn takes_by_value(val: RealNative64StrictFinite) -> f64 {
3863 *val.as_ref()
3864 }
3865
3866 let x = RealNative64StrictFinite::try_new(42.0).unwrap();
3867 let result1 = takes_by_value(x);
3868 let result2 = takes_by_value(x); assert_eq!(result1, 42.0);
3870 assert_eq!(result2, 42.0);
3871 }
3872
3873 #[test]
3874 fn real_copy_in_loop() {
3875 let x = RealNative64StrictFinite::try_new(1.0).unwrap();
3876 let mut sum = RealNative64StrictFinite::zero();
3877
3878 for _ in 0..5 {
3879 sum += x; }
3881
3882 assert_eq!(*sum.as_ref(), 5.0);
3883 assert_eq!(*x.as_ref(), 1.0); }
3885
3886 #[test]
3887 fn real_copy_with_arithmetic() {
3888 let a = RealNative64StrictFinite::try_new(2.0).unwrap();
3889 let b = RealNative64StrictFinite::try_new(3.0).unwrap();
3890
3891 let sum = a + b;
3893 let diff = a - b;
3894 let prod = a * b;
3895 let quot = a / b;
3896
3897 assert_eq!(*a.as_ref(), 2.0);
3899 assert_eq!(*b.as_ref(), 3.0);
3900 assert_eq!(*sum.as_ref(), 5.0);
3901 assert_eq!(*diff.as_ref(), -1.0);
3902 assert_eq!(*prod.as_ref(), 6.0);
3903 assert!((quot.as_ref() - 2.0 / 3.0).abs() < 1e-10);
3904 }
3905 }
3906
3907 mod complex_copy {
3908 use super::*;
3909
3910 #[test]
3911 fn complex_is_copy() {
3912 fn assert_copy<T: Copy>() {}
3914 assert_copy::<ComplexNative64StrictFinite>();
3915 assert_copy::<ComplexNative64StrictFiniteInDebug>();
3916 }
3917
3918 #[test]
3919 fn complex_copy_semantics() {
3920 let z = ComplexNative64StrictFinite::try_new(Complex::new(1.0, 2.0)).unwrap();
3921 let w = z; let v = z; assert_eq!(z, w);
3924 assert_eq!(z, v);
3925 }
3926
3927 #[test]
3928 fn complex_copy_in_function_call() {
3929 fn takes_by_value(val: ComplexNative64StrictFinite) -> Complex<f64> {
3930 val.into_inner()
3931 }
3932
3933 let z = ComplexNative64StrictFinite::try_new(Complex::new(3.0, 4.0)).unwrap();
3934 let result1 = takes_by_value(z);
3935 let result2 = takes_by_value(z); assert_eq!(result1, Complex::new(3.0, 4.0));
3937 assert_eq!(result2, Complex::new(3.0, 4.0));
3938 }
3939
3940 #[test]
3941 fn complex_copy_with_arithmetic() {
3942 let a = ComplexNative64StrictFinite::try_new(Complex::new(1.0, 2.0)).unwrap();
3943 let b = ComplexNative64StrictFinite::try_new(Complex::new(3.0, 4.0)).unwrap();
3944
3945 let sum = a + b;
3947 let diff = a - b;
3948 let prod = a * b;
3949
3950 assert_eq!(a.into_inner(), Complex::new(1.0, 2.0));
3952 assert_eq!(b.into_inner(), Complex::new(3.0, 4.0));
3953 assert_eq!(sum.into_inner(), Complex::new(4.0, 6.0));
3954 assert_eq!(diff.into_inner(), Complex::new(-2.0, -2.0));
3955 assert_eq!(prod.into_inner(), Complex::new(-5.0, 10.0));
3957 }
3958
3959 #[test]
3960 fn complex_copy_in_loop() {
3961 let z = ComplexNative64StrictFinite::try_new(Complex::new(1.0, 1.0)).unwrap();
3962 let mut sum = ComplexNative64StrictFinite::zero();
3963
3964 for _ in 0..3 {
3965 sum += z; }
3967
3968 assert_eq!(sum.into_inner(), Complex::new(3.0, 3.0));
3969 assert_eq!(z.into_inner(), Complex::new(1.0, 1.0)); }
3971 }
3972
3973 mod mixed_copy {
3974 use super::*;
3975
3976 #[test]
3977 fn real_and_complex_copy_in_expression() {
3978 let r = RealNative64StrictFinite::try_new(2.0).unwrap();
3979 let z = ComplexNative64StrictFinite::try_new(Complex::new(1.0, 1.0)).unwrap();
3980
3981 let result1 = z * r;
3983 let result2 = z * r;
3984
3985 assert_eq!(*r.as_ref(), 2.0);
3987 assert_eq!(z.into_inner(), Complex::new(1.0, 1.0));
3988 assert_eq!(result1.into_inner(), Complex::new(2.0, 2.0));
3989 assert_eq!(result2.into_inner(), Complex::new(2.0, 2.0));
3990 }
3991 }
3992 }
3993}