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