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