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