1#![deny(rustdoc::broken_intra_doc_links)]
2
3use crate::kernels::{
45 ComplexValidated, NumKernelStrictFinite, NumKernelStrictFiniteInDebug, RealValidated,
46};
47
48pub type Native64StrictFinite = NumKernelStrictFinite<f64, 53>;
58pub type Native64StrictFiniteInDebug = NumKernelStrictFiniteInDebug<f64, 53>;
71pub type RealNative64StrictFinite = RealValidated<Native64StrictFinite>;
81
82pub type ComplexNative64StrictFinite = ComplexValidated<Native64StrictFinite>;
89pub type RealNative64StrictFiniteInDebug = RealValidated<Native64StrictFiniteInDebug>;
99
100pub type ComplexNative64StrictFiniteInDebug = ComplexValidated<Native64StrictFiniteInDebug>;
107#[cfg(test)]
122mod tests {
123 use super::*;
124 use crate::{
125 Clamp, ComplexScalarConstructors, ComplexScalarGetParts, ComplexScalarMutateParts,
126 ComplexScalarSetParts, Constants, ExpM1, FpChecks, Hypot, Ln1p, MulAddRef, NegAssign,
127 RealScalar, Rounding, Sign, TotalCmp,
128 functions::{
129 ACos, ACosH, ACosHErrors, ACosHInputErrors, ACosRealErrors, ACosRealInputErrors, ASin,
130 ASinH, ASinRealErrors, ASinRealInputErrors, ATan, ATan2, ATan2Errors,
131 ATanComplexErrors, ATanComplexInputErrors, ATanH, ATanHErrors, ATanHInputErrors, Abs,
132 Arg, Classify, Conjugate, Cos, CosH, Exp, ExpErrors, Ln, Log2, Log10,
133 LogarithmComplexErrors, LogarithmComplexInputErrors, Max, Min, Pow,
134 PowComplexBaseRealExponentErrors, PowIntExponentErrors, PowIntExponentInputErrors,
135 PowRealBaseRealExponentErrors, Reciprocal, ReciprocalErrors, Sin, SinH, Sqrt,
136 SqrtRealErrors, Tan, TanH,
137 },
138 validation::{ErrorsTryFromf64, ErrorsValidationRawComplex, ErrorsValidationRawReal},
139 };
140 use num::{Complex, One, Zero};
141 use std::{
142 cmp::Ordering,
143 f64::consts::*,
144 num::FpCategory,
145 ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
146 };
147 use try_create::{IntoInner, New, TryNew, TryNewValidated};
148
149 type RealValidated = RealNative64StrictFinite;
150 type ComplexValidated = ComplexNative64StrictFinite;
151
152 mod fp_checks {
153 use super::*;
154
155 #[test]
156 fn is_finite() {
157 let real = RealValidated::try_new(1.).unwrap();
158 assert!(real.is_finite());
159
160 let real = RealValidated::try_new(f64::INFINITY);
161 assert!(real.is_err());
162
163 let complex = ComplexValidated::try_new(Complex::new(1., 1.)).unwrap();
164 assert!(complex.is_finite());
165
166 let complex = ComplexValidated::try_new(Complex::new(f64::INFINITY, 1.));
167 assert!(complex.is_err());
168 }
169
170 #[test]
171 fn is_infinite() {
172 let real = RealValidated::try_new(1.).unwrap();
173 assert!(!real.is_infinite());
174
175 let real = RealValidated::try_new(f64::INFINITY);
176 assert!(real.is_err());
177
178 let complex = ComplexValidated::try_new(Complex::new(1., 1.)).unwrap();
179 assert!(!complex.is_infinite());
180
181 let complex = ComplexValidated::try_new(Complex::new(f64::INFINITY, 1.));
182 assert!(complex.is_err());
183 }
184
185 #[test]
186 fn is_nan() {
187 let real = RealValidated::try_new(1.).unwrap();
188 assert!(!real.is_nan());
189
190 let real = RealValidated::try_new(f64::NAN);
191 assert!(matches!(real, Err(ErrorsValidationRawReal::IsNaN { .. })));
192
193 let complex = ComplexValidated::try_new(Complex::new(1., 1.)).unwrap();
194 assert!(!complex.is_nan());
195
196 let complex = ComplexValidated::try_new(Complex::new(f64::NAN, 1.));
197 assert!(matches!(
198 complex,
199 Err(ErrorsValidationRawComplex::InvalidRealPart {
200 source: ErrorsValidationRawReal::IsNaN { .. }
201 })
202 ));
203 }
204
205 #[test]
206 fn is_normal() {
207 let real = RealValidated::try_new(1.).unwrap();
208 assert!(real.is_normal());
209
210 let real = RealValidated::try_new(0.).unwrap();
211 assert!(!real.is_normal());
212
213 let complex = ComplexValidated::try_new(Complex::new(1., 1.)).unwrap();
214 assert!(complex.is_normal());
215
216 let complex = ComplexValidated::try_new(Complex::new(0., 0.)).unwrap();
217 assert!(!complex.is_normal());
218 }
219 }
220
221 mod abs {
222 use super::*;
223
224 mod real {
225 use super::*;
226
227 #[test]
228 fn abs_valid() {
229 let value = RealValidated::try_new(-4.).unwrap();
230
231 let expected_result = RealValidated::try_new(4.).unwrap();
232 assert_eq!(value.clone().try_abs().unwrap(), expected_result);
233 assert_eq!(value.abs(), expected_result);
234 }
235
236 #[test]
237 fn abs_zero() {
238 let value = RealValidated::try_new(0.).unwrap();
239
240 let expected_result = RealValidated::try_new(0.).unwrap();
241 assert_eq!(value.clone().try_abs().unwrap(), expected_result);
242 assert_eq!(value.abs(), expected_result);
243 }
244
245 }
269
270 mod complex {
271 use super::*;
272
273 #[test]
274 fn abs_valid() {
275 let value = ComplexValidated::try_new(Complex::new(3., 4.)).unwrap();
276
277 let expected_result = RealValidated::try_new(5.).unwrap();
278 assert_eq!(value.clone().try_abs().unwrap(), expected_result);
279 assert_eq!(value.abs(), expected_result);
280 }
281
282 #[test]
283 fn abs_zero() {
284 let value = ComplexValidated::try_new(Complex::new(0., 0.)).unwrap();
285
286 let expected_result = RealValidated::try_new(0.).unwrap();
287 assert_eq!(value.clone().try_abs().unwrap(), expected_result);
288 assert_eq!(value.abs(), expected_result);
289 }
290 }
324 }
325
326 mod builders {
327 use super::*;
328
329 mod real {
330 use super::*;
331
332 #[test]
333 fn into_inner() {
334 let value = RealValidated::try_new(1.23).unwrap();
335 assert_eq!(value.into_inner(), 1.23);
336 }
337
338 #[test]
339 fn new() {
340 let value = RealValidated::new(1.23);
341 assert_eq!(value, 1.23);
342 }
343
344 #[test]
345 fn try_new_nan() {
346 let err = RealValidated::try_new(f64::NAN).unwrap_err();
347 assert!(matches!(err, ErrorsValidationRawReal::IsNaN { .. }));
348 }
349
350 #[test]
351 fn try_new_pos_infinity() {
352 let err = RealValidated::try_new(f64::INFINITY).unwrap_err();
353 assert!(matches!(err, ErrorsValidationRawReal::IsPosInfinity { .. }));
354 }
355
356 #[test]
357 fn try_new_neg_infinity() {
358 let err = RealValidated::try_new(f64::NEG_INFINITY).unwrap_err();
359 assert!(matches!(err, ErrorsValidationRawReal::IsNegInfinity { .. }));
360 }
361 }
362
363 mod complex {
364 use super::*;
365
366 #[test]
367 fn into_inner() {
368 let v = Complex::new(1., 2.);
369 let value = ComplexValidated::try_new(v).unwrap();
370 assert_eq!(value.into_inner(), v);
371 }
372
373 #[test]
374 fn new() {
375 let v = Complex::new(1., 2.);
376 let value = ComplexValidated::new(v);
377 assert_eq!(value.into_inner(), v);
378 }
379
380 #[test]
381 fn real_part() {
382 let c1 = ComplexValidated::try_new_validated(Complex::new(1.23, 4.56)).unwrap();
383 assert_eq!(c1.real_part(), 1.23);
384
385 let c2 = ComplexValidated::try_new_validated(Complex::new(-7.89, 0.12)).unwrap();
386 assert_eq!(c2.real_part(), -7.89);
387
388 let c3 = ComplexValidated::try_new_validated(Complex::new(0., 10.)).unwrap();
389 assert_eq!(c3.real_part(), 0.);
390
391 let c_nan_re =
392 ComplexValidated::try_new_validated(Complex::new(f64::NAN, 5.)).unwrap_err();
393 assert!(matches!(
394 c_nan_re,
395 ErrorsValidationRawComplex::InvalidRealPart {
396 source: ErrorsValidationRawReal::IsNaN { .. }
397 }
398 ));
399
400 let c_inf_re = ComplexValidated::try_new_validated(Complex::new(f64::INFINITY, 5.))
401 .unwrap_err();
402 assert!(matches!(
403 c_inf_re,
404 ErrorsValidationRawComplex::InvalidRealPart {
405 source: ErrorsValidationRawReal::IsPosInfinity { .. }
406 }
407 ));
408
409 let c_neg_inf_re =
410 ComplexValidated::try_new_validated(Complex::new(f64::NEG_INFINITY, 5.))
411 .unwrap_err();
412 assert!(matches!(
413 c_neg_inf_re,
414 ErrorsValidationRawComplex::InvalidRealPart {
415 source: ErrorsValidationRawReal::IsNegInfinity { .. }
416 }
417 ));
418 }
419
420 #[test]
421 fn imag_part() {
422 let c1 = ComplexValidated::try_new_validated(Complex::new(1.23, 4.56)).unwrap();
423 assert_eq!(c1.imag_part(), 4.56);
424
425 let c2 = ComplexValidated::try_new_validated(Complex::new(-7.89, 0.12)).unwrap();
426 assert_eq!(c2.imag_part(), 0.12);
427
428 let c3 = ComplexValidated::try_new_validated(Complex::new(10., 0.)).unwrap();
429 assert_eq!(c3.imag_part(), 0.);
430
431 let c_nan_im =
432 ComplexValidated::try_new_validated(Complex::new(5., f64::NAN)).unwrap_err();
433 assert!(matches!(
434 c_nan_im,
435 ErrorsValidationRawComplex::InvalidImaginaryPart {
436 source: ErrorsValidationRawReal::IsNaN { .. }
437 }
438 ));
439
440 let c_inf_im = ComplexValidated::try_new_validated(Complex::new(5., f64::INFINITY))
441 .unwrap_err();
442 assert!(matches!(
443 c_inf_im,
444 ErrorsValidationRawComplex::InvalidImaginaryPart {
445 source: ErrorsValidationRawReal::IsPosInfinity { .. }
446 }
447 ));
448
449 let c_neg_inf_im =
450 ComplexValidated::try_new_validated(Complex::new(5., f64::NEG_INFINITY))
451 .unwrap_err();
452 assert!(matches!(
453 c_neg_inf_im,
454 ErrorsValidationRawComplex::InvalidImaginaryPart {
455 source: ErrorsValidationRawReal::IsNegInfinity { .. }
456 }
457 ));
458 }
459
460 #[test]
461 fn try_new_complex() {
462 let r1 = RealValidated::try_new(1.23).unwrap();
463 let i1 = RealValidated::try_new(4.56).unwrap();
464 let c1 = ComplexValidated::try_new_complex(*r1.as_ref(), *i1.as_ref()).unwrap();
465 assert_eq!(c1.real_part(), r1);
466 assert_eq!(c1.imag_part(), i1);
467
468 let r2 = RealValidated::try_new(-7.89).unwrap();
469 let i2 = RealValidated::try_new(-0.12).unwrap();
470 let c2 = ComplexValidated::try_new_complex(*r2.as_ref(), *i2.as_ref()).unwrap();
471 assert_eq!(c2.real_part(), r2);
472 assert_eq!(c2.imag_part(), i2);
473
474 let r3 = RealValidated::try_new(0.).unwrap();
475 let i3 = RealValidated::try_new(0.).unwrap();
476 let c3 = ComplexValidated::try_new_complex(*r3.as_ref(), *i3.as_ref()).unwrap();
477 assert_eq!(c3.real_part(), r3);
478 assert_eq!(c3.real_part(), i3);
479 assert!(c3.is_zero());
480
481 let c_nan_re = ComplexValidated::try_new_complex(f64::NAN, 5.).unwrap_err();
482 assert!(matches!(
483 c_nan_re,
484 ErrorsValidationRawComplex::InvalidRealPart { .. }
485 ));
486
487 let c_inf_im = ComplexValidated::try_new_complex(10., f64::INFINITY).unwrap_err();
488 assert!(matches!(
489 c_inf_im,
490 ErrorsValidationRawComplex::InvalidImaginaryPart { .. }
491 ));
492
493 let c_nan_re_inf_im =
494 ComplexValidated::try_new_complex(f64::NAN, f64::INFINITY).unwrap_err();
495 assert!(matches!(
496 c_nan_re_inf_im,
497 ErrorsValidationRawComplex::InvalidBothParts { .. }
498 ));
499 }
500
501 #[test]
502 fn try_new_pure_real() {
503 let r1 = RealValidated::try_new(1.23).unwrap();
504 let c1 = ComplexValidated::try_new_pure_real(*r1.as_ref()).unwrap();
505 assert_eq!(c1.real_part(), r1);
506 assert!(c1.imag_part().is_zero());
507
508 let c_nan = ComplexValidated::try_new_pure_real(f64::NAN).unwrap_err();
509 assert!(matches!(
510 c_nan,
511 ErrorsValidationRawComplex::InvalidRealPart {
512 source: ErrorsValidationRawReal::IsNaN { .. }
513 }
514 ));
515 }
516
517 #[test]
518 fn try_new_pure_imaginary() {
519 let i1 = RealValidated::try_new(1.23).unwrap();
520 let c1 = ComplexValidated::try_new_pure_imaginary(*i1.as_ref()).unwrap();
521 assert!(c1.real_part().is_zero());
522 assert_eq!(c1.imag_part(), i1);
523
524 let c_nan = ComplexValidated::try_new_pure_imaginary(f64::NAN).unwrap_err();
525 assert!(matches!(
526 c_nan,
527 ErrorsValidationRawComplex::InvalidImaginaryPart {
528 source: ErrorsValidationRawReal::IsNaN { .. }
529 }
530 ));
531 }
532
533 #[test]
534 fn add_to_real_part() {
535 let mut c = ComplexValidated::try_new_validated(Complex::new(1., 2.)).unwrap();
536 c.add_to_real_part(&RealValidated::try_new(3.).unwrap());
537 assert_eq!(c.real_part(), 4.);
538 assert_eq!(c.imag_part(), 2.);
539
540 c.add_to_real_part(&RealValidated::try_new(-5.).unwrap());
541 assert_eq!(c.real_part(), -1.);
542 assert_eq!(c.imag_part(), 2.);
543 }
544
545 #[test]
546 fn add_to_imaginary_part() {
547 let mut c = ComplexValidated::try_new_validated(Complex::new(1., 2.)).unwrap();
548 c.add_to_imaginary_part(&RealValidated::try_new(3.).unwrap());
549 assert_eq!(c.real_part(), 1.);
550 assert_eq!(c.imag_part(), 5.);
551
552 c.add_to_imaginary_part(&RealValidated::try_new(-4.).unwrap());
553 assert_eq!(c.real_part(), 1.);
554 assert_eq!(c.imag_part(), 1.);
555 }
556
557 #[test]
558 fn multiply_real_part() {
559 let mut c = ComplexValidated::try_new_validated(Complex::new(1., 2.)).unwrap();
560 c.multiply_real_part(&RealValidated::try_new(3.).unwrap());
561 assert_eq!(c.real_part(), 3.);
562 assert_eq!(c.imag_part(), 2.);
563
564 c.multiply_real_part(&RealValidated::try_new(-2.).unwrap());
565 assert_eq!(c.real_part(), -6.);
566 assert_eq!(c.imag_part(), 2.);
567 }
568
569 #[test]
570 fn multiply_imaginary_part() {
571 let mut c = ComplexValidated::try_new_validated(Complex::new(1., 2.)).unwrap();
572 c.multiply_imaginary_part(&RealValidated::try_new(3.).unwrap());
573 assert_eq!(c.real_part(), 1.);
574 assert_eq!(c.imag_part(), 6.);
575
576 c.multiply_imaginary_part(&RealValidated::try_new(-0.5).unwrap());
577 assert_eq!(c.real_part(), 1.);
578 assert_eq!(c.imag_part(), -3.);
579 }
580
581 #[test]
582 fn set_real_part() {
583 let mut c = ComplexValidated::try_new_validated(Complex::new(1., 2.)).unwrap();
584 c.set_real_part(RealValidated::try_new(3.).unwrap());
585 assert_eq!(c.real_part(), 3.);
586 assert_eq!(c.imag_part(), 2.);
587
588 c.set_real_part(RealValidated::try_new(-4.).unwrap());
589 assert_eq!(c.real_part(), -4.);
590 assert_eq!(c.imag_part(), 2.);
591 }
592
593 #[test]
594 fn set_imaginary_part() {
595 let mut c = ComplexValidated::try_new_validated(Complex::new(1., 2.)).unwrap();
596 c.set_imaginary_part(RealValidated::try_new(3.).unwrap());
597 assert_eq!(c.real_part(), 1.);
598 assert_eq!(c.imag_part(), 3.);
599
600 c.set_imaginary_part(RealValidated::try_new(-4.).unwrap());
601 assert_eq!(c.real_part(), 1.);
602 assert_eq!(c.imag_part(), -4.);
603 }
604 }
605 }
606
607 mod mul {
608 use super::*;
609
610 mod real {
611 use super::*;
612
613 #[test]
614 fn multiply_ref() {
615 let r1 = RealValidated::try_new_validated(3.).unwrap();
616 let r2 = RealValidated::try_new_validated(4.).unwrap();
617 let result = r1 * &r2;
618 assert_eq!(result, RealValidated::try_new_validated(12.).unwrap());
619 }
620 }
621
622 mod complex {
623 use super::*;
624
625 #[test]
626 fn multiply_ref() {
627 let c1 = ComplexValidated::try_new_validated(Complex::new(1., 2.)).unwrap();
628 let c2 = ComplexValidated::try_new_validated(Complex::new(3., 4.)).unwrap();
629 let result = c1 * &c2;
630 assert_eq!(
631 result,
632 ComplexValidated::try_new_validated(Complex::new(-5., 10.)).unwrap()
633 ); }
635
636 #[test]
637 fn complex_times_real() {
638 let r = RealValidated::try_new_validated(2.).unwrap();
639 let c = ComplexValidated::try_new_validated(Complex::new(3., 4.)).unwrap();
640
641 let result_expected =
642 ComplexValidated::try_new_validated(Complex::new(6., 8.)).unwrap(); let result = c.clone() * &r;
645 assert_eq!(&result, &result_expected);
646
647 let result = c.clone() * r.clone();
648 assert_eq!(&result, &result_expected);
649
650 let mut result = c.clone();
651 result *= &r;
652 assert_eq!(&result, &result_expected);
653
654 let mut result = c.clone();
655 result *= r;
656 assert_eq!(&result, &result_expected);
657 }
658
659 #[test]
660 fn real_times_complex() {
661 let r = RealValidated::try_new_validated(2.).unwrap();
662 let c = ComplexValidated::try_new_validated(Complex::new(3., 4.)).unwrap();
663
664 let result_expected =
665 ComplexValidated::try_new_validated(Complex::new(6., 8.)).unwrap(); let result = &r * c.clone();
668 assert_eq!(&result, &result_expected);
669
670 let result = r * c.clone();
671 assert_eq!(&result, &result_expected);
672 }
673 }
674 }
675
676 mod arithmetic {
677 use super::*;
678
679 mod real {
680 use super::*;
681
682 #[test]
683 fn add() {
684 let r1 = RealValidated::try_new_validated(3.).unwrap();
685 let r2 = RealValidated::try_new_validated(4.).unwrap();
686
687 let expected_result = RealValidated::try_new_validated(7.).unwrap();
688
689 let result = r1.clone().add(&r2);
690 assert_eq!(result, expected_result);
691
692 let result = r1.clone().add(r2.clone());
693 assert_eq!(result, expected_result);
694
695 let result = (&r1).add(r2.clone());
696 assert_eq!(result, expected_result);
697
698 let result = (&r1).add(&r2);
699 assert_eq!(result, expected_result);
700
701 let mut result = r1.clone();
702 result.add_assign(&r2);
703 assert_eq!(result, expected_result);
704
705 let mut result = r1.clone();
706 result.add_assign(r2);
707 assert_eq!(result, expected_result);
708 }
709
710 #[test]
711 fn sub() {
712 let r1 = RealValidated::try_new_validated(3.).unwrap();
713 let r2 = RealValidated::try_new_validated(4.).unwrap();
714
715 let expected_result = RealValidated::try_new_validated(-1.).unwrap();
716
717 let result = r1.clone().sub(&r2);
718 assert_eq!(result, expected_result);
719
720 let result = r1.clone().sub(r2.clone());
721 assert_eq!(result, expected_result);
722
723 let result = (&r1).sub(r2.clone());
724 assert_eq!(result, expected_result);
725
726 let result = (&r1).sub(&r2);
727 assert_eq!(result, expected_result);
728
729 let mut result = r1.clone();
730 result.sub_assign(&r2);
731 assert_eq!(result, expected_result);
732
733 let mut result = r1.clone();
734 result.sub_assign(r2);
735 assert_eq!(result, expected_result);
736 }
737
738 #[test]
739 fn mul() {
740 let r1 = RealValidated::try_new_validated(3.).unwrap();
741 let r2 = RealValidated::try_new_validated(4.).unwrap();
742
743 let expected_result = RealValidated::try_new_validated(12.).unwrap();
744
745 let result = r1.clone().mul(&r2);
746 assert_eq!(result, expected_result);
747
748 let result = r1.clone().mul(r2.clone());
749 assert_eq!(result, expected_result);
750
751 let result = (&r1).mul(r2.clone());
752 assert_eq!(result, expected_result);
753
754 let result = (&r1).mul(&r2);
755 assert_eq!(result, expected_result);
756
757 let mut result = r1.clone();
758 result.mul_assign(&r2);
759 assert_eq!(result, expected_result);
760
761 let mut result = r1.clone();
762 result.mul_assign(r2);
763 assert_eq!(result, expected_result);
764 }
765
766 #[test]
767 fn div() {
768 let r1 = RealValidated::try_new_validated(3.).unwrap();
769 let r2 = RealValidated::try_new_validated(4.).unwrap();
770
771 let expected_result = RealValidated::try_new_validated(0.75).unwrap();
772
773 let result = r1.clone().div(&r2);
774 assert_eq!(result, expected_result);
775
776 let result = r1.clone().div(r2.clone());
777 assert_eq!(result, expected_result);
778
779 let result = (&r1).div(r2.clone());
780 assert_eq!(result, expected_result);
781
782 let result = (&r1).div(&r2);
783 assert_eq!(result, expected_result);
784
785 let mut result = r1.clone();
786 result.div_assign(&r2);
787 assert_eq!(result, expected_result);
788
789 let mut result = r1.clone();
790 result.div_assign(r2);
791 assert_eq!(result, expected_result);
792 }
793
794 #[test]
795 fn neg() {
796 let num = RealValidated::try_new_validated(1.).unwrap();
797 let expected = RealValidated::try_new_validated(-1.).unwrap();
798 assert_eq!(num.neg(), expected);
799 }
800
801 #[test]
802 fn neg_assign() {
803 let mut num = 1.;
804 num.neg_assign();
805 let expected = -1.;
806 assert_eq!(&num, &expected);
807
808 let mut num = RealValidated::one();
809 num.neg_assign();
810 let expected = RealValidated::try_new_validated(-1.).unwrap();
811 assert_eq!(&num, &expected);
812 }
813
814 #[test]
815 #[should_panic(expected = "Division failed validation")]
816 fn div_by_zero() {
817 let one = RealValidated::one();
818 let zero = RealValidated::zero();
819 let _ = &one / &zero;
820 }
821
822 #[test]
823 #[should_panic(expected = "Division failed validation")]
824 fn div_assign_by_zero() {
825 let mut num = RealValidated::one();
826 let zero_ref = &RealValidated::zero();
827 num /= zero_ref;
828 }
829
830 #[test]
831 fn mul_add() {
832 let a = RealValidated::try_new(2.0).unwrap();
833 let b = RealValidated::try_new(3.0).unwrap();
834 let c = RealValidated::try_new(4.0).unwrap();
835 assert_eq!(a.mul_add_ref(&b, &c), RealValidated::try_new(10.0).unwrap());
837 }
838 }
839
840 mod complex {
841 use super::*;
842
843 #[test]
844 fn add() {
845 let r1 = ComplexValidated::try_new_validated(Complex::new(2., 3.)).unwrap();
846 let r2 = ComplexValidated::try_new_validated(Complex::new(4., -4.)).unwrap();
847
848 let expected_result =
849 ComplexValidated::try_new_validated(Complex::new(6., -1.)).unwrap();
850
851 let result = r1.clone().add(&r2);
852 assert_eq!(result, expected_result);
853
854 let result = r1.clone().add(r2.clone());
855 assert_eq!(result, expected_result);
856
857 let result = (&r1).add(r2.clone());
858 assert_eq!(result, expected_result);
859
860 let result = (&r1).add(&r2);
861 assert_eq!(result, expected_result);
862
863 let mut result = r1.clone();
864 result.add_assign(&r2);
865 assert_eq!(result, expected_result);
866
867 let mut result = r1.clone();
868 result.add_assign(r2);
869 assert_eq!(result, expected_result);
870 }
871
872 #[test]
873 fn sub() {
874 let r1 = ComplexValidated::try_new_validated(Complex::new(2., 3.)).unwrap();
875 let r2 = ComplexValidated::try_new_validated(Complex::new(4., -4.)).unwrap();
876
877 let expected_result =
878 ComplexValidated::try_new_validated(Complex::new(-2., 7.)).unwrap();
879
880 let result = r1.clone().sub(&r2);
881 assert_eq!(result, expected_result);
882
883 let result = r1.clone().sub(r2.clone());
884 assert_eq!(result, expected_result);
885
886 let result = (&r1).sub(r2.clone());
887 assert_eq!(result, expected_result);
888
889 let result = (&r1).sub(&r2);
890 assert_eq!(result, expected_result);
891
892 let mut result = r1.clone();
893 result.sub_assign(&r2);
894 assert_eq!(result, expected_result);
895
896 let mut result = r1.clone();
897 result.sub_assign(r2);
898 assert_eq!(result, expected_result);
899 }
900
901 #[test]
902 fn mul() {
903 let r1 = ComplexValidated::try_new_validated(Complex::new(2., 3.)).unwrap();
904 let r2 = ComplexValidated::try_new_validated(Complex::new(4., -4.)).unwrap();
905
906 let expected_result =
907 ComplexValidated::try_new_validated(Complex::new(20., 4.)).unwrap();
908
909 let result = r1.clone().mul(&r2);
910 assert_eq!(result, expected_result);
911
912 let result = r1.clone().mul(r2.clone());
913 assert_eq!(result, expected_result);
914
915 let result = (&r1).mul(r2.clone());
916 assert_eq!(result, expected_result);
917
918 let result = (&r1).mul(&r2);
919 assert_eq!(result, expected_result);
920
921 let mut result = r1.clone();
922 result.mul_assign(&r2);
923 assert_eq!(result, expected_result);
924
925 let mut result = r1.clone();
926 result.mul_assign(r2);
927 assert_eq!(result, expected_result);
928 }
929
930 #[test]
931 fn div() {
932 let r1 = ComplexValidated::try_new_validated(Complex::new(2., 3.)).unwrap();
933 let r2 = ComplexValidated::try_new_validated(Complex::new(4., -4.)).unwrap();
934
935 let expected_result =
936 ComplexValidated::try_new_validated(Complex::new(-0.125, 0.625)).unwrap();
937
938 let result = r1.clone().div(&r2);
939 assert_eq!(result, expected_result);
940
941 let result = r1.clone().div(r2.clone());
942 assert_eq!(result, expected_result);
943
944 let result = (&r1).div(r2.clone());
945 assert_eq!(result, expected_result);
946
947 let result = (&r1).div(&r2);
948 assert_eq!(result, expected_result);
949
950 let mut result = r1.clone();
951 result.div_assign(&r2);
952 assert_eq!(result, expected_result);
953
954 let mut result = r1.clone();
955 result.div_assign(r2);
956 assert_eq!(result, expected_result);
957 }
958
959 #[test]
960 fn neg() {
961 let v = Complex::new(1., 2.);
962
963 let num = ComplexValidated::try_new_validated(v).unwrap();
964 let expected = Complex::new(-1., -2.);
965 assert_eq!(num.neg().into_inner(), expected);
966 }
967
968 #[test]
969 fn neg_assign() {
970 let v = Complex::new(1., 2.);
971
972 let mut num = ComplexValidated::try_new_validated(v).unwrap();
973 let expected = Complex::new(-1., -2.);
974 num.neg_assign();
975 assert_eq!(num.as_ref(), &expected);
976 }
977
978 #[test]
979 #[should_panic(expected = "Division failed validation")]
980 fn div_by_zero() {
981 let one = ComplexValidated::one();
982 let zero = ComplexValidated::zero();
983 let _ = &one / &zero;
984 }
985
986 #[test]
987 #[should_panic(expected = "Division failed validation")]
988 fn div_assign_by_zero() {
989 let mut num = ComplexValidated::one();
990 let zero_ref = &ComplexValidated::zero();
991 num /= zero_ref;
992 }
993
994 #[test]
995 fn mul_add() {
996 let ca = ComplexValidated::try_new(Complex::new(1.0, 2.0)).unwrap();
997 let cb = ComplexValidated::try_new(Complex::new(3.0, 4.0)).unwrap();
998 let cc = ComplexValidated::try_new(Complex::new(5.0, 6.0)).unwrap();
999 let expected = ComplexValidated::try_new(Complex::new(0.0, 16.0)).unwrap();
1001 assert_eq!(ca.mul_add_ref(&cb, &cc), expected);
1002 }
1003 }
1004 }
1005
1006 mod real_scalar_methods {
1007 use super::*;
1008
1009 #[test]
1010 fn test_constants() {
1011 assert_eq!(<RealValidated as Constants>::epsilon(), f64::EPSILON);
1012 assert_eq!(<RealValidated as Constants>::negative_one(), -1.0);
1013 assert_eq!(<RealValidated as Constants>::one_div_2(), 0.5);
1014 assert_eq!(<RealValidated as Constants>::two(), 2.0);
1015 assert_eq!(<RealValidated as Constants>::max_finite(), f64::MAX);
1016 assert_eq!(<RealValidated as Constants>::min_finite(), f64::MIN);
1017 assert_eq!(<RealValidated as Constants>::pi(), std::f64::consts::PI);
1018 assert_eq!(
1019 <RealValidated as Constants>::two_pi(),
1020 std::f64::consts::PI * 2.0
1021 );
1022 assert_eq!(
1023 <RealValidated as Constants>::pi_div_2(),
1024 std::f64::consts::FRAC_PI_2
1025 );
1026 assert_eq!(<RealValidated as Constants>::ln_2(), std::f64::consts::LN_2);
1027 assert_eq!(
1028 <RealValidated as Constants>::ln_10(),
1029 std::f64::consts::LN_10
1030 );
1031 assert_eq!(
1032 <RealValidated as Constants>::log10_2(),
1033 std::f64::consts::LOG10_2
1034 );
1035 assert_eq!(
1036 <RealValidated as Constants>::log2_10(),
1037 std::f64::consts::LOG2_10
1038 );
1039 assert_eq!(
1040 <RealValidated as Constants>::log2_e(),
1041 std::f64::consts::LOG2_E
1042 );
1043 assert_eq!(
1044 <RealValidated as Constants>::log10_e(),
1045 std::f64::consts::LOG10_E
1046 );
1047 assert_eq!(<RealValidated as Constants>::e(), std::f64::consts::E);
1048 }
1049
1050 #[test]
1051 fn round_ties_even() {
1052 let f = RealValidated::try_new(3.3).unwrap();
1053 let g = RealValidated::try_new(-3.3).unwrap();
1054 let h = RealValidated::try_new(3.5).unwrap();
1055 let i = RealValidated::try_new(4.5).unwrap();
1056 let j = RealValidated::try_new(-3.5).unwrap();
1057 let k = RealValidated::try_new(-4.5).unwrap();
1058
1059 assert_eq!(
1060 f.kernel_round_ties_even(),
1061 RealValidated::try_new(3.0).unwrap()
1062 );
1063 assert_eq!(
1064 g.kernel_round_ties_even(),
1065 RealValidated::try_new(-3.0).unwrap()
1066 );
1067 assert_eq!(
1068 h.kernel_round_ties_even(),
1069 RealValidated::try_new(4.0).unwrap()
1070 );
1071 assert_eq!(
1072 i.kernel_round_ties_even(),
1073 RealValidated::try_new(4.0).unwrap()
1074 );
1075 assert_eq!(
1076 j.kernel_round_ties_even(),
1077 RealValidated::try_new(-4.0).unwrap()
1078 );
1079 assert_eq!(
1080 k.kernel_round_ties_even(),
1081 RealValidated::try_new(-4.0).unwrap()
1082 );
1083 }
1084
1085 #[test]
1086 fn classify() {
1087 let normal = RealValidated::try_new(1.0).unwrap();
1088 assert_eq!(normal.kernel_classify(), FpCategory::Normal);
1089
1090 let zero = RealValidated::zero();
1091 assert_eq!(zero.kernel_classify(), FpCategory::Zero);
1092
1093 let subnormal_err = RealValidated::try_new(f64::MIN_POSITIVE / 2.).unwrap_err();
1096 assert!(matches!(
1097 subnormal_err,
1098 ErrorsValidationRawReal::IsSubnormal { .. }
1099 ));
1100
1101 let pos_inf_err = RealValidated::try_new(f64::INFINITY).unwrap_err();
1102 assert!(matches!(
1103 pos_inf_err,
1104 ErrorsValidationRawReal::IsPosInfinity { .. }
1105 ));
1106
1107 let neg_inf_err = RealValidated::try_new(f64::NEG_INFINITY).unwrap_err();
1108 assert!(matches!(
1109 neg_inf_err,
1110 ErrorsValidationRawReal::IsNegInfinity { .. }
1111 ));
1112
1113 let nan_err = RealValidated::try_new(f64::NAN).unwrap_err();
1114 assert!(matches!(nan_err, ErrorsValidationRawReal::IsNaN { .. }));
1115 }
1116
1117 #[test]
1118 fn try_from_f64_valid() {
1119 let val = RealValidated::try_from_f64(123.45).unwrap();
1120 assert_eq!(val.as_ref(), &123.45);
1121 }
1122
1123 #[test]
1124 fn try_from_f64_invalid() {
1125 let err = RealValidated::try_from_f64(f64::NAN).unwrap_err();
1126 assert!(matches!(
1127 err,
1128 ErrorsTryFromf64::Output {
1129 source: ErrorsValidationRawReal::IsNaN { .. }
1130 }
1131 ));
1132 }
1133
1134 #[test]
1135 fn rounding_and_trunc() {
1136 let val1 = RealValidated::try_new(3.7).unwrap();
1137 let val2 = RealValidated::try_new(-3.7).unwrap();
1138
1139 assert_eq!(
1140 val1.clone().kernel_ceil(),
1141 RealValidated::try_new(4.0).unwrap()
1142 );
1143 assert_eq!(
1144 val2.clone().kernel_ceil(),
1145 RealValidated::try_new(-3.0).unwrap()
1146 );
1147
1148 assert_eq!(
1149 val1.clone().kernel_floor(),
1150 RealValidated::try_new(3.0).unwrap()
1151 );
1152 assert_eq!(
1153 val2.clone().kernel_floor(),
1154 RealValidated::try_new(-4.0).unwrap()
1155 );
1156
1157 assert_eq!(
1158 val1.clone().kernel_round(),
1159 RealValidated::try_new(4.0).unwrap()
1160 );
1161 assert_eq!(
1162 val2.clone().kernel_round(),
1163 RealValidated::try_new(-4.0).unwrap()
1164 );
1165
1166 assert_eq!(
1167 val1.clone().kernel_trunc(),
1168 RealValidated::try_new(3.0).unwrap()
1169 );
1170 assert_eq!(
1171 val2.clone().kernel_trunc(),
1172 RealValidated::try_new(-3.0).unwrap()
1173 );
1174
1175 let frac1 = val1.kernel_fract();
1177 assert!((frac1.as_ref() - 0.7).abs() < 1e-9);
1178
1179 let frac2 = val2.kernel_fract();
1180 assert!((frac2.as_ref() - (-0.7)).abs() < 1e-9);
1181 }
1182
1183 #[test]
1184 fn sign_and_constants() {
1185 let pos = RealValidated::try_new(5.0).unwrap();
1186 let neg = RealValidated::try_new(-5.0).unwrap();
1187 let zero = RealValidated::zero();
1188
1189 assert!(pos.kernel_is_sign_positive());
1190 assert!(!pos.kernel_is_sign_negative());
1191
1192 assert!(!neg.kernel_is_sign_positive());
1193 assert!(neg.kernel_is_sign_negative());
1194
1195 assert!(zero.kernel_is_sign_positive()); assert!(!zero.kernel_is_sign_negative());
1197
1198 let neg_zero = RealValidated::try_new(-0.0).unwrap();
1199 assert!(!neg_zero.kernel_is_sign_positive());
1200 assert!(neg_zero.kernel_is_sign_negative());
1201
1202 assert_eq!(pos.clone().kernel_copysign(&neg), neg);
1203 assert_eq!(neg.clone().kernel_copysign(&pos), pos);
1204
1205 assert_eq!(
1206 RealValidated::one_div_2(),
1207 RealValidated::try_new(0.5).unwrap()
1208 );
1209 assert_eq!(RealValidated::two(), RealValidated::try_new(2.0).unwrap());
1210 assert_eq!(
1211 RealValidated::max_finite(),
1212 RealValidated::try_new(f64::MAX).unwrap()
1213 );
1214 assert_eq!(
1215 RealValidated::min_finite(),
1216 RealValidated::try_new(f64::MIN).unwrap()
1217 );
1218 }
1219
1220 #[test]
1221 fn epsilon() {
1222 let eps = RealValidated::epsilon();
1223 assert!(eps.is_finite() && eps > RealValidated::zero());
1224 let expected_eps_val = 2.0f64.pow(-52);
1225 let expected_eps = RealValidated::try_new(expected_eps_val).unwrap();
1226 assert_eq!(eps, expected_eps, "Epsilon value mismatch");
1227 }
1228
1229 #[test]
1230 fn clamp() {
1231 let val = RealValidated::try_new(5.).unwrap();
1232 let min_val = RealValidated::try_new(0.).unwrap();
1233 let max_val = RealValidated::try_new(10.).unwrap();
1234
1235 assert_eq!(val.clone().kernel_clamp(&min_val, &max_val), val);
1236 assert_eq!(
1237 RealValidated::try_new(-5.)
1238 .unwrap()
1239 .kernel_clamp(&min_val, &max_val),
1240 min_val
1241 );
1242 assert_eq!(
1243 RealValidated::try_new(15.)
1244 .unwrap()
1245 .kernel_clamp(&min_val, &max_val),
1246 max_val
1247 );
1248 }
1249
1250 #[test]
1251 fn hypot() {
1252 let a = RealValidated::try_new(3.).unwrap();
1253 let b = RealValidated::try_new(4.).unwrap();
1254 let expected = RealValidated::try_new(5.).unwrap();
1255 assert_eq!(a.kernel_hypot(&b), expected);
1256 }
1257
1258 #[test]
1259 fn signum() {
1260 assert_eq!(
1261 RealValidated::try_new(5.).unwrap().kernel_signum(),
1262 RealValidated::one()
1263 );
1264 assert_eq!(
1265 RealValidated::try_new(-5.).unwrap().kernel_signum(),
1266 RealValidated::negative_one()
1267 );
1268 assert_eq!(RealValidated::zero().kernel_signum(), RealValidated::one());
1270 }
1271
1272 #[test]
1273 fn total_cmp() {
1274 let r1 = RealValidated::try_new(1.).unwrap();
1275 let r2 = RealValidated::try_new(2.).unwrap();
1276 assert_eq!(r1.total_cmp(&r1), Ordering::Equal);
1277 assert_eq!(r1.total_cmp(&r2), Ordering::Less);
1278 assert_eq!(r2.total_cmp(&r1), Ordering::Greater);
1279 }
1280
1281 #[test]
1282 fn mul_add_mul_mut() {
1283 let mut a = RealValidated::try_new(2.).unwrap();
1284 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);
1289 assert_eq!(a, RealValidated::try_new(26.).unwrap());
1290 }
1291
1292 #[test]
1293 fn mul_sub_mul_mut() {
1294 let mut a = RealValidated::try_new(10.).unwrap();
1295 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);
1300 assert_eq!(a, RealValidated::try_new(8.).unwrap());
1301 }
1302 }
1303
1304 mod complex_scalar_methods {
1305 use super::*;
1306 use crate::functions::{ArgErrors, ArgInputErrors};
1307
1308 #[test]
1309 fn conjugate() {
1310 let c = ComplexValidated::try_new(Complex::new(1., 2.)).unwrap();
1311 let expected = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
1312 assert_eq!(c.conjugate(), expected);
1313
1314 let c_real = ComplexValidated::try_new_pure_real(5.).unwrap();
1315 assert_eq!(c_real.clone().conjugate(), c_real);
1316
1317 let c_imag = ComplexValidated::try_new_pure_imaginary(3.).unwrap();
1318 let expected_imag = ComplexValidated::try_new_pure_imaginary(-3.).unwrap();
1319 assert_eq!(c_imag.conjugate(), expected_imag);
1320 }
1321
1322 #[test]
1323 fn arg_valid() {
1324 let c1 = ComplexValidated::one();
1326 assert_eq!(c1.arg(), RealValidated::zero());
1327
1328 let c2 = ComplexValidated::try_new_pure_imaginary(1.0).unwrap();
1330 let pi_div_2 = RealValidated::try_new(FRAC_PI_2).unwrap();
1331 assert_eq!(c2.arg(), pi_div_2);
1332
1333 let c3 = ComplexValidated::try_new_pure_real(-1.0).unwrap();
1335 let pi = RealValidated::try_new(PI).unwrap();
1336 assert_eq!(c3.arg(), pi);
1337
1338 let c4 = ComplexValidated::try_new(Complex::new(1.0, 1.0)).unwrap();
1340 let pi_div_4 = RealValidated::try_new(FRAC_PI_4).unwrap();
1341 assert_eq!(c4.arg(), pi_div_4);
1342 }
1343
1344 #[test]
1345 fn arg_zero() {
1346 let zero = ComplexValidated::zero();
1347 let res = zero.try_arg();
1348 assert!(matches!(
1349 res,
1350 Err(ArgErrors::Input {
1351 source: ArgInputErrors::Zero { .. }
1352 })
1353 ));
1354 }
1355 }
1356
1357 mod function_traits {
1358 use super::*;
1359 use crate::functions::{
1360 ATan2InputErrors, LogarithmRealErrors, LogarithmRealInputErrors,
1361 PowComplexBaseRealExponentInputErrors, PowRealBaseRealExponentInputErrors,
1362 ReciprocalInputErrors, SqrtRealInputErrors,
1363 };
1364
1365 mod min_max {
1366 use super::*;
1367
1368 #[test]
1369 fn max_valid() {
1370 let r1 = RealValidated::try_new(3.).unwrap();
1371 let r2 = RealValidated::try_new(4.).unwrap();
1372 assert_eq!(r1.max(&r2), &r2);
1373 assert_eq!(r2.max(&r1), &r2);
1374 }
1375
1376 #[test]
1377 fn min_valid() {
1378 let r1 = RealValidated::try_new(3.).unwrap();
1379 let r2 = RealValidated::try_new(4.).unwrap();
1380 assert_eq!(r1.min(&r2), &r1);
1381 assert_eq!(r2.min(&r1), &r1);
1382 }
1383 }
1384
1385 mod exp {
1386 use super::*;
1387
1388 mod real {
1389 use super::*;
1390
1391 #[test]
1392 fn exp_valid() {
1393 let exponent = RealValidated::try_new(1.).unwrap();
1394 let expected = std::f64::consts::E;
1395 assert_eq!(exponent.clone().try_exp().unwrap().as_ref(), &expected);
1396 assert_eq!(exponent.clone().exp().as_ref(), &expected);
1397 }
1398
1399 #[test]
1400 fn exp_m1_valid() {
1401 let exponent = RealValidated::try_new(1.).unwrap();
1402 let expected = if cfg!(target_arch = "x86_64") {
1403 1.718281828459045
1404 } else if cfg!(target_arch = "aarch64") {
1405 1.7182818284590453
1406 } else {
1407 todo!("Not implemented for this architecture");
1408 };
1409 assert_eq!(exponent.clone().kernel_exp_m1().as_ref(), &expected);
1410 }
1411
1412 #[test]
1413 fn exp_overflow() {
1414 let large_val = RealValidated::try_new(1.0e60).unwrap(); let res_large = large_val.try_exp();
1416 assert!(matches!(
1417 res_large,
1418 Err(ExpErrors::Output {
1419 source: ErrorsValidationRawReal::IsPosInfinity { .. }
1420 })
1421 ),);
1422 }
1423 } mod complex {
1426 use super::*;
1427
1428 #[test]
1429 fn exp_valid() {
1430 let exponent = ComplexValidated::try_new(Complex::new(0., PI)).unwrap();
1431 let expected = Complex::new(-1., 1.2246467991473532e-16);
1432 assert_eq!(exponent.clone().try_exp().unwrap().as_ref(), &expected);
1433 assert_eq!(exponent.clone().exp().as_ref(), &expected);
1434 }
1435 } } mod logarithm {
1439 use super::*;
1440
1441 mod real {
1442 use super::*;
1443
1444 #[test]
1445 fn ln_valid() {
1446 let e = RealValidated::one().exp();
1447 let expected = 1.0;
1448 assert_eq!(e.clone().try_ln().unwrap().as_ref(), &expected);
1449 assert_eq!(e.clone().ln().as_ref(), &expected);
1450 }
1451
1452 #[test]
1453 fn log10_valid() {
1454 let v = RealValidated::try_new(100.).unwrap();
1455 let expected = 2.0;
1456 assert_eq!(v.clone().try_log10().unwrap().as_ref(), &expected);
1457 assert_eq!(v.clone().log10().as_ref(), &expected);
1458 }
1459
1460 #[test]
1461 fn log2_valid() {
1462 let v = RealValidated::try_new(4.).unwrap();
1463 let expected = 2.0;
1464 assert_eq!(v.clone().try_log2().unwrap().as_ref(), &expected);
1465 assert_eq!(v.clone().log2().as_ref(), &expected);
1466 }
1467
1468 #[test]
1469 fn ln_1p_valid() {
1470 let v = RealValidated::one().exp() - RealValidated::one();
1472
1473 assert_eq!(v.clone().kernel_ln_1p().as_ref(), &1.);
1475 }
1476
1477 #[test]
1478 fn ln_domain_errors() {
1479 let neg_val = RealValidated::try_new(-1.).unwrap();
1480 assert!(matches!(
1481 neg_val.try_ln(),
1482 Err(LogarithmRealErrors::Input {
1483 source: LogarithmRealInputErrors::NegativeArgument { .. }
1484 })
1485 ));
1486
1487 let zero_val = RealValidated::zero();
1488 assert!(matches!(
1489 zero_val.try_ln(),
1490 Err(LogarithmRealErrors::Input {
1491 source: LogarithmRealInputErrors::ZeroArgument { .. }
1492 })
1493 ));
1494 }
1495
1496 #[test]
1497 fn log10_domain_errors() {
1498 let neg_val = RealValidated::try_new(-1.).unwrap();
1499 assert!(matches!(
1500 neg_val.try_log10(),
1501 Err(LogarithmRealErrors::Input {
1502 source: LogarithmRealInputErrors::NegativeArgument { .. }
1503 })
1504 ));
1505
1506 let zero_val = RealValidated::zero();
1507 assert!(matches!(
1508 zero_val.try_log10(),
1509 Err(LogarithmRealErrors::Input {
1510 source: LogarithmRealInputErrors::ZeroArgument { .. }
1511 })
1512 ));
1513 }
1514
1515 #[test]
1516 fn log2_domain_errors() {
1517 let neg_val = RealValidated::try_new(-1.).unwrap();
1518 assert!(matches!(
1519 neg_val.try_log2(),
1520 Err(LogarithmRealErrors::Input {
1521 source: LogarithmRealInputErrors::NegativeArgument { .. }
1522 })
1523 ));
1524
1525 let zero_val = RealValidated::zero();
1526 assert!(matches!(
1527 zero_val.try_log2(),
1528 Err(LogarithmRealErrors::Input {
1529 source: LogarithmRealInputErrors::ZeroArgument { .. }
1530 })
1531 ));
1532 }
1533 } mod complex {
1536 use super::*;
1537
1538 #[test]
1539 fn ln_valid() {
1540 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
1541 let expected = Complex::new(0.8047189562170503, -1.1071487177940904);
1542 assert_eq!(v.clone().try_ln().unwrap().as_ref(), &expected);
1543 assert_eq!(v.clone().ln().as_ref(), &expected);
1544 }
1545
1546 #[test]
1547 fn log10_valid() {
1548 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
1549 let expected = Complex::new(0.3494850021680094, -0.480828578784234);
1550 assert_eq!(v.clone().try_log10().unwrap().as_ref(), &expected);
1551 assert_eq!(v.clone().log10().as_ref(), &expected);
1552 }
1553
1554 #[test]
1555 fn log2_valid() {
1556 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
1557 let expected = Complex::new(1.1609640474436813, -1.5972779646881088);
1558 assert_eq!(v.clone().try_log2().unwrap().as_ref(), &expected);
1559 assert_eq!(v.clone().log2().as_ref(), &expected);
1560 }
1561
1562 #[test]
1563 fn ln_zero() {
1564 let zero_val = ComplexValidated::zero();
1565 assert!(matches!(
1566 zero_val.try_ln(),
1567 Err(LogarithmComplexErrors::Input {
1568 source: LogarithmComplexInputErrors::ZeroArgument { .. }
1569 })
1570 ));
1571 }
1572
1573 #[test]
1574 fn log10_zero() {
1575 let zero_val = ComplexValidated::zero();
1576 assert!(matches!(
1577 zero_val.try_log10(),
1578 Err(LogarithmComplexErrors::Input {
1579 source: LogarithmComplexInputErrors::ZeroArgument { .. }
1580 })
1581 ));
1582 }
1583
1584 #[test]
1585 fn log2_zero() {
1586 let zero_val = ComplexValidated::zero();
1587 assert!(matches!(
1588 zero_val.try_log2(),
1589 Err(LogarithmComplexErrors::Input {
1590 source: LogarithmComplexInputErrors::ZeroArgument { .. }
1591 })
1592 ));
1593 }
1594 } } mod pow {
1598 use super::*;
1599
1600 mod real_base {
1601 use super::*;
1602
1603 #[test]
1604 fn negative_base_real_exponent_error() {
1605 let base = RealValidated::try_new(-2.).unwrap();
1606 let exponent = RealValidated::try_new(0.5).unwrap();
1607 let res = base.try_pow(&exponent);
1608 assert!(matches!(
1609 res,
1610 Err(PowRealBaseRealExponentErrors::Input {
1611 source: PowRealBaseRealExponentInputErrors::NegativeBase { .. }
1612 })
1613 ));
1614 }
1615
1616 #[test]
1617 fn real_base_uint_exponent_valid() {
1618 let base = RealValidated::try_new(2.).unwrap();
1619 assert_eq!(
1620 base.clone().try_pow(3u8).unwrap(),
1621 RealValidated::try_new(8.).unwrap()
1622 );
1623 assert_eq!(
1624 base.clone().try_pow(3u16).unwrap(),
1625 RealValidated::try_new(8.).unwrap()
1626 );
1627 assert_eq!(
1628 base.clone().try_pow(3u32).unwrap(),
1629 RealValidated::try_new(8.).unwrap()
1630 );
1631 assert_eq!(
1632 base.clone().try_pow(3u64).unwrap(),
1633 RealValidated::try_new(8.).unwrap()
1634 );
1635 assert_eq!(
1636 base.clone().try_pow(3u128).unwrap(),
1637 RealValidated::try_new(8.).unwrap()
1638 );
1639 assert_eq!(
1640 base.clone().try_pow(3usize).unwrap(),
1641 RealValidated::try_new(8.).unwrap()
1642 );
1643
1644 assert_eq!(base.clone().pow(3u8), RealValidated::try_new(8.).unwrap());
1645 assert_eq!(base.clone().pow(3u16), RealValidated::try_new(8.).unwrap());
1646 assert_eq!(base.clone().pow(3u32), RealValidated::try_new(8.).unwrap());
1647 assert_eq!(base.clone().pow(3u64), RealValidated::try_new(8.).unwrap());
1648 assert_eq!(base.clone().pow(3u128), RealValidated::try_new(8.).unwrap());
1649 assert_eq!(
1650 base.clone().pow(3usize),
1651 RealValidated::try_new(8.).unwrap()
1652 );
1653 }
1654
1655 #[test]
1656 fn real_base_int_exponent_valid() {
1657 let base = RealValidated::try_new(2.).unwrap();
1658 assert_eq!(
1659 base.clone().try_pow(3i8).unwrap(),
1660 RealValidated::try_new(8.).unwrap()
1661 );
1662 assert_eq!(
1663 base.clone().try_pow(3i16).unwrap(),
1664 RealValidated::try_new(8.).unwrap()
1665 );
1666 assert_eq!(
1667 base.clone().try_pow(3i32).unwrap(),
1668 RealValidated::try_new(8.).unwrap()
1669 );
1670 assert_eq!(
1671 base.clone().try_pow(3i64).unwrap(),
1672 RealValidated::try_new(8.).unwrap()
1673 );
1674 assert_eq!(
1675 base.clone().try_pow(3i128).unwrap(),
1676 RealValidated::try_new(8.).unwrap()
1677 );
1678 assert_eq!(
1679 base.clone().try_pow(3isize).unwrap(),
1680 RealValidated::try_new(8.).unwrap()
1681 );
1682
1683 assert_eq!(base.clone().pow(3i8), RealValidated::try_new(8.).unwrap());
1684 assert_eq!(base.clone().pow(3i16), RealValidated::try_new(8.).unwrap());
1685 assert_eq!(base.clone().pow(3i32), RealValidated::try_new(8.).unwrap());
1686 assert_eq!(base.clone().pow(3i64), RealValidated::try_new(8.).unwrap());
1687 assert_eq!(base.clone().pow(3i128), RealValidated::try_new(8.).unwrap());
1688 assert_eq!(
1689 base.clone().pow(3isize),
1690 RealValidated::try_new(8.).unwrap()
1691 );
1692 }
1693
1694 #[test]
1695 fn real_base_int_exponent_zero_neg_exp_error() {
1696 let base = RealValidated::zero();
1697 let exponent: i32 = -2;
1698 let res = base.try_pow(exponent);
1699 assert!(matches!(
1700 res,
1701 Err(PowIntExponentErrors::Input {
1702 source: PowIntExponentInputErrors::ZeroBaseNegativeExponent { .. }
1703 })
1704 ));
1705 }
1706
1707 #[test]
1708 fn real_base_real_exponent_valid() {
1709 let base = RealValidated::try_new(2.).unwrap();
1710 let exponent = RealValidated::try_new(3.).unwrap();
1711 let expected = 8.;
1712 assert_eq!(base.clone().try_pow(&exponent).unwrap().as_ref(), &expected);
1713 assert_eq!(base.clone().pow(&exponent).as_ref(), &expected);
1714 }
1715 }
1716
1717 mod complex_base {
1718 use super::*;
1719
1720 #[test]
1721 fn complex_base_uint_exponent_valid() {
1722 let base = ComplexValidated::try_new(Complex::new(2., 3.)).unwrap();
1723 let expected_res = ComplexValidated::try_new(Complex::new(-46., 9.)).unwrap();
1724
1725 assert_eq!(&base.clone().try_pow(3u8).unwrap(), &expected_res);
1726 assert_eq!(&base.clone().try_pow(3u16).unwrap(), &expected_res);
1727 assert_eq!(&base.clone().try_pow(3u32).unwrap(), &expected_res);
1728 assert_eq!(&base.clone().try_pow(3u64).unwrap(), &expected_res);
1729 assert_eq!(&base.clone().try_pow(3u128).unwrap(), &expected_res);
1730 assert_eq!(&base.clone().try_pow(3usize).unwrap(), &expected_res);
1731
1732 assert_eq!(&base.clone().pow(3u8), &expected_res);
1733 assert_eq!(&base.clone().pow(3u16), &expected_res);
1734 assert_eq!(&base.clone().pow(3u32), &expected_res);
1735 assert_eq!(&base.clone().pow(3u64), &expected_res);
1736 assert_eq!(&base.clone().pow(3u128), &expected_res);
1737 assert_eq!(&base.clone().pow(3usize), &expected_res);
1738 }
1739
1740 #[test]
1741 fn complex_base_int_exponent_valid() {
1742 let base = ComplexValidated::try_new(Complex::new(2., 3.)).unwrap();
1743 let expected_res = ComplexValidated::try_new(Complex::new(-46., 9.)).unwrap();
1744
1745 assert_eq!(&base.clone().try_pow(3i8).unwrap(), &expected_res);
1746 assert_eq!(&base.clone().try_pow(3i16).unwrap(), &expected_res);
1747 assert_eq!(&base.clone().try_pow(3i32).unwrap(), &expected_res);
1748 assert_eq!(&base.clone().try_pow(3i64).unwrap(), &expected_res);
1749 assert_eq!(&base.clone().try_pow(3i128).unwrap(), &expected_res);
1750 assert_eq!(&base.clone().try_pow(3isize).unwrap(), &expected_res);
1751
1752 assert_eq!(&base.clone().pow(3i8), &expected_res);
1753 assert_eq!(&base.clone().pow(3i16), &expected_res);
1754 assert_eq!(&base.clone().pow(3i32), &expected_res);
1755 assert_eq!(&base.clone().pow(3i64), &expected_res);
1756 assert_eq!(&base.clone().pow(3i128), &expected_res);
1757 assert_eq!(&base.clone().pow(3isize), &expected_res);
1758 }
1759
1760 #[test]
1761 fn complex_zero_base_negative_real_exponent_error() {
1762 let base = ComplexValidated::zero();
1763 let exponent = RealValidated::try_new(-2.).unwrap();
1764 let res = base.try_pow(&exponent);
1765 assert!(matches!(
1766 res,
1767 Err(PowComplexBaseRealExponentErrors::Input {
1768 source:
1769 PowComplexBaseRealExponentInputErrors::ZeroBaseNegativeExponent { .. }
1770 })
1771 ));
1772 }
1773
1774 #[test]
1775 fn complex_zero_base_zero_real_exponent() {
1776 let base = ComplexValidated::zero();
1777 let exponent = RealValidated::zero();
1778 let res = base.try_pow(&exponent).unwrap();
1779 assert_eq!(res, ComplexValidated::one());
1780 }
1781
1782 #[test]
1783 fn complex_base_int_exponent_zero_neg_exp_error() {
1784 let base = ComplexValidated::zero();
1785 let exponent: i32 = -2;
1786 let res = base.try_pow(exponent);
1787 assert!(matches!(
1788 res,
1789 Err(PowIntExponentErrors::Input {
1790 source: PowIntExponentInputErrors::ZeroBaseNegativeExponent { .. }
1791 })
1792 ));
1793 }
1794
1795 #[test]
1796 fn complex_base_real_exponent_valid() {
1797 let base = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
1798 let exponent = RealValidated::try_new(3.).unwrap();
1799 let expected = Complex::new(-11.000000000000004, 1.9999999999999973);
1800 assert_eq!(base.clone().try_pow(&exponent).unwrap().as_ref(), &expected);
1801 assert_eq!(base.clone().pow(&exponent).as_ref(), &expected);
1802 }
1803
1804 #[test]
1805 fn complex_zero_base_real_exponent_valid() {
1806 let base = ComplexValidated::zero();
1807 let exponent = RealValidated::try_new(3.).unwrap();
1808 let expected = Complex::new(0., 0.);
1809 assert_eq!(base.clone().try_pow(&exponent).unwrap().as_ref(), &expected);
1810 assert_eq!(base.clone().pow(&exponent).as_ref(), &expected);
1811 }
1812 }
1813 }
1814
1815 mod reciprocal {
1816 use super::*;
1817
1818 mod real {
1819 use super::*;
1820
1821 #[test]
1822 fn reciprocal_valid() {
1823 let v = RealValidated::try_new(2.).unwrap();
1824
1825 let res = v.clone().try_reciprocal().unwrap();
1826 assert_eq!(res.into_inner(), 0.5);
1827
1828 let res = v.clone().reciprocal();
1829 assert_eq!(res.into_inner(), 0.5);
1830 }
1831
1832 #[test]
1833 fn reciprocal_real_zero() {
1834 let zero_val = RealValidated::zero();
1835 let res = zero_val.try_reciprocal();
1836 assert!(matches!(
1837 res,
1838 Err(ReciprocalErrors::Input {
1839 source: ReciprocalInputErrors::DivisionByZero { .. }
1840 })
1841 ));
1842 }
1843 }
1844
1845 mod complex {
1846 use super::*;
1847
1848 #[test]
1849 fn reciprocal_valid() {
1850 let v = ComplexValidated::try_new(Complex::new(3., 4.)).unwrap();
1851
1852 let expected = Complex::new(0.12, -0.16);
1853
1854 let res = v.clone().try_reciprocal().unwrap();
1855 assert_eq!(res.as_ref(), &expected);
1856
1857 let res = v.clone().reciprocal();
1858 assert_eq!(res.as_ref(), &expected);
1859 }
1860
1861 #[test]
1862 fn reciprocal_complex_zero() {
1863 let zero_val = ComplexValidated::zero();
1864 let res = zero_val.try_reciprocal();
1865 assert!(matches!(
1866 res,
1867 Err(ReciprocalErrors::Input {
1868 source: ReciprocalInputErrors::DivisionByZero { .. }
1869 })
1870 ));
1871 }
1872 }
1873 } mod sqrt {
1876 use super::*;
1877
1878 mod real {
1879 use super::*;
1880
1881 #[test]
1882 fn sqrt_valid() {
1883 let v = RealValidated::try_new(9.).unwrap();
1884 assert_eq!(v.clone().try_sqrt().unwrap().as_ref(), &3.);
1885 assert_eq!(v.clone().sqrt().as_ref(), &3.);
1886 }
1887
1888 #[test]
1889 fn sqrt_negative_input() {
1890 let neg_val = RealValidated::try_new(-4.).unwrap();
1891 let res = neg_val.try_sqrt();
1892 assert!(matches!(
1893 res,
1894 Err(SqrtRealErrors::Input {
1895 source: SqrtRealInputErrors::NegativeValue { .. }
1896 })
1897 ));
1898 }
1899 } mod complex {
1902 use super::*;
1903
1904 #[test]
1905 fn sqrt_valid() {
1906 let expected = Complex::new(1., 2.);
1907 let v = ComplexValidated::try_new(expected * expected).unwrap();
1908
1909 let expected = Complex::new(1.0000000000000002, 2.);
1910 assert_eq!(v.clone().try_sqrt().unwrap().as_ref(), &expected);
1911 assert_eq!(v.clone().sqrt().as_ref(), &expected);
1912 }
1913 }
1914 } mod trigonometric {
1917 use super::*;
1918
1919 mod real {
1920 use super::*;
1921
1922 #[test]
1923 fn sin_real_valid() {
1924 let v = RealValidated::pi_div_2();
1925
1926 let expected = 1.;
1927 assert_eq!(v.clone().try_sin().unwrap().as_ref(), &expected);
1928 assert_eq!(v.clone().sin().as_ref(), &expected);
1929 }
1930
1931 #[test]
1932 fn cos_real_valid() {
1933 let v = RealValidated::pi();
1934
1935 let expected = -1.;
1936 assert_eq!(v.clone().try_cos().unwrap().as_ref(), &expected);
1937 assert_eq!(v.clone().cos().as_ref(), &expected);
1938 }
1939
1940 #[test]
1941 fn tan_real_valid() {
1942 let v = RealValidated::one();
1943
1944 let expected = if cfg!(target_arch = "x86_64") {
1945 1.5574077246549023
1946 } else if cfg!(target_arch = "aarch64") {
1947 1.557407724654902
1948 } else {
1949 todo!("Implement for other architectures");
1950 };
1951 assert_eq!(v.clone().try_tan().unwrap().as_ref(), &expected);
1952 assert_eq!(v.clone().tan().as_ref(), &expected);
1953 }
1954
1955 #[test]
1956 fn asin_real_valid() {
1957 let v = RealValidated::one();
1958
1959 let expected = std::f64::consts::FRAC_PI_2; assert_eq!(v.clone().try_asin().unwrap().as_ref(), &expected);
1961 assert_eq!(v.clone().asin().as_ref(), &expected);
1962 }
1963
1964 #[test]
1965 fn acos_real_valid() {
1966 let v = RealValidated::one();
1967
1968 let expected = 0.;
1969 assert_eq!(v.clone().try_acos().unwrap().as_ref(), &expected);
1970 assert_eq!(v.clone().acos().as_ref(), &expected);
1971 }
1972
1973 #[test]
1974 fn atan_real_valid() {
1975 let v = RealValidated::one();
1976
1977 let expected = std::f64::consts::FRAC_PI_4; assert_eq!(v.clone().try_atan().unwrap().as_ref(), &expected);
1979 assert_eq!(v.clone().atan().as_ref(), &expected);
1980 }
1981
1982 #[test]
1983 fn atan2_valid() {
1984 let one = RealValidated::one();
1985 let zero = RealValidated::zero();
1986
1987 let expected = std::f64::consts::FRAC_PI_2; assert_eq!(one.clone().try_atan2(&zero).unwrap().as_ref(), &expected);
1989 assert_eq!(one.clone().atan2(&zero).as_ref(), &expected);
1990
1991 let expected = 0.;
1992 assert_eq!(zero.clone().try_atan2(&one).unwrap().as_ref(), &expected);
1993 assert_eq!(zero.clone().atan2(&one).as_ref(), &expected);
1994
1995 let expected = std::f64::consts::FRAC_PI_4; assert_eq!(one.clone().try_atan2(&one).unwrap().as_ref(), &expected);
1997 assert_eq!(one.clone().atan2(&one).as_ref(), &expected);
1998 }
1999
2000 #[test]
2001 fn atan2_zero_over_zero() {
2002 let zero_val = RealValidated::zero();
2003 let res = zero_val.try_atan2(&RealValidated::zero());
2004 assert!(matches!(
2005 res,
2006 Err(ATan2Errors::Input {
2007 source: ATan2InputErrors::ZeroOverZero { .. }
2008 })
2009 ));
2010 }
2011
2012 #[test]
2030 fn asin_real_out_of_domain() {
2031 let val_gt_1 = RealValidated::try_new(1.5).unwrap();
2032 assert!(matches!(
2033 val_gt_1.try_asin(),
2034 Err(ASinRealErrors::Input {
2035 source: ASinRealInputErrors::OutOfDomain { .. }
2036 })
2037 ));
2038 let val_lt_neg1 = RealValidated::try_new(-1.5).unwrap();
2039 assert!(matches!(
2040 val_lt_neg1.try_asin(),
2041 Err(ASinRealErrors::Input {
2042 source: ASinRealInputErrors::OutOfDomain { .. }
2043 })
2044 ));
2045 }
2046
2047 #[test]
2048 fn acos_real_out_of_domain() {
2049 let val_gt_1 = RealValidated::try_new(1.5).unwrap();
2050 assert!(matches!(
2051 val_gt_1.try_acos(),
2052 Err(ACosRealErrors::Input {
2053 source: ACosRealInputErrors::OutOfDomain { .. }
2054 })
2055 ));
2056 let val_lt_neg1 = RealValidated::try_new(-1.5).unwrap();
2057 assert!(matches!(
2058 val_lt_neg1.try_acos(),
2059 Err(ACosRealErrors::Input {
2060 source: ACosRealInputErrors::OutOfDomain { .. }
2061 })
2062 ));
2063 }
2064 } mod complex {
2067 use super::*;
2068
2069 #[test]
2070 fn sin_complex_valid() {
2071 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2072
2073 let expected = if cfg!(target_arch = "x86_64") {
2074 Complex::new(3.165778513216168, -1.9596010414216063)
2075 } else if cfg!(target_arch = "aarch64") {
2076 Complex::new(3.165778513216168, -1.959601041421606)
2077 } else {
2078 todo!("Implement for other architectures");
2079 };
2080 assert_eq!(v.clone().try_sin().unwrap().as_ref(), &expected);
2081 assert_eq!(v.clone().sin().as_ref(), &expected);
2082
2083 let zero = ComplexValidated::zero();
2084 let expected = Complex::new(0., 0.);
2085 assert_eq!(zero.clone().try_sin().unwrap().as_ref(), &expected);
2086 assert_eq!(zero.clone().sin().as_ref(), &expected);
2087 }
2088
2089 #[test]
2090 fn cos_complex_valid() {
2091 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2092
2093 let expected = if cfg!(target_arch = "x86_64") {
2094 Complex::new(2.0327230070196656, 3.0518977991518)
2095 } else if cfg!(target_arch = "aarch64") {
2096 Complex::new(2.0327230070196656, 3.0518977991517997)
2097 } else {
2098 todo!("Implement for other architectures");
2099 };
2100 assert_eq!(v.clone().try_cos().unwrap().as_ref(), &expected);
2101 assert_eq!(v.clone().cos().as_ref(), &expected);
2102
2103 let zero = ComplexValidated::zero();
2104 let expected = Complex::new(1., 0.);
2105 assert_eq!(zero.clone().try_cos().unwrap().as_ref(), &expected);
2106 assert_eq!(zero.clone().cos().as_ref(), &expected);
2107 }
2108
2109 #[test]
2110 fn tan_complex_valid() {
2111 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2112
2113 let expected = Complex::new(0.03381282607989669, -1.0147936161466335);
2114 assert_eq!(v.clone().try_tan().unwrap().as_ref(), &expected);
2115 assert_eq!(v.clone().tan().as_ref(), &expected);
2116
2117 let zero = ComplexValidated::zero();
2118 let expected = Complex::new(0., 0.);
2119 assert_eq!(zero.clone().try_tan().unwrap().as_ref(), &expected);
2120 assert_eq!(zero.clone().tan().as_ref(), &expected);
2121 }
2122
2123 #[test]
2124 fn asin_complex_valid() {
2125 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2126
2127 let expected = Complex::new(0.42707858639247614, -1.528570919480998);
2128 assert_eq!(v.clone().try_asin().unwrap().as_ref(), &expected);
2129 assert_eq!(v.clone().asin().as_ref(), &expected);
2130
2131 let zero = ComplexValidated::zero();
2132 let expected = Complex::new(0., 0.);
2133 assert_eq!(zero.clone().try_asin().unwrap().as_ref(), &expected);
2134 assert_eq!(zero.clone().asin().as_ref(), &expected);
2135 }
2136
2137 #[test]
2138 fn acos_complex_valid() {
2139 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2140
2141 let expected = Complex::new(1.14371774040242, 1.5285709194809995);
2142 assert_eq!(v.clone().try_acos().unwrap().as_ref(), &expected);
2143 assert_eq!(v.clone().acos().as_ref(), &expected);
2144
2145 let one = ComplexValidated::one();
2146 let expected = Complex::new(0., 0.);
2147 assert_eq!(one.clone().try_acos().unwrap().as_ref(), &expected);
2148 assert_eq!(one.clone().acos().as_ref(), &expected);
2149 }
2150
2151 #[test]
2152 fn atan_complex_valid() {
2153 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2154
2155 let expected = Complex::new(1.3389725222944935, -0.4023594781085251);
2156 assert_eq!(v.clone().try_atan().unwrap().as_ref(), &expected);
2157 assert_eq!(v.clone().atan().as_ref(), &expected);
2158
2159 let zero = ComplexValidated::zero();
2160 let expected = Complex::new(0., 0.);
2161 assert_eq!(zero.clone().try_atan().unwrap().as_ref(), &expected);
2162 assert_eq!(zero.clone().atan().as_ref(), &expected);
2163 }
2164
2165 #[test]
2166 fn atan_complex_pole() {
2167 let i_val = ComplexValidated::try_new_pure_imaginary(1.).unwrap();
2169 assert!(matches!(
2170 i_val.try_atan(),
2171 Err(ATanComplexErrors::Input {
2172 source: ATanComplexInputErrors::ArgumentIsPole { .. }
2173 })
2174 ));
2175
2176 let neg_i_val = ComplexValidated::try_new_pure_imaginary(-1.).unwrap();
2177 assert!(matches!(
2178 neg_i_val.try_atan(),
2179 Err(ATanComplexErrors::Input {
2180 source: ATanComplexInputErrors::ArgumentIsPole { .. }
2181 })
2182 ));
2183 }
2184 } } mod hyperbolic {
2188 use super::*;
2189
2190 mod real {
2191 use super::*;
2192
2193 #[test]
2194 fn atanh_real_valid() {
2195 let v = RealValidated::zero();
2196 let expected = 0.;
2197 assert_eq!(v.clone().try_atanh().unwrap().as_ref(), &expected);
2198 assert_eq!(v.clone().atanh().as_ref(), &expected);
2199 }
2200
2201 #[test]
2202 fn atanh_real_out_of_domain() {
2203 let val_ge_1 = RealValidated::one(); assert!(matches!(
2205 val_ge_1.try_atanh(),
2206 Err(ATanHErrors::Input {
2207 source: ATanHInputErrors::OutOfDomain { .. }
2208 })
2209 ));
2210
2211 let val_le_neg1 = RealValidated::negative_one(); assert!(matches!(
2213 val_le_neg1.try_atanh(),
2214 Err(ATanHErrors::Input {
2215 source: ATanHInputErrors::OutOfDomain { .. }
2216 })
2217 ));
2218 }
2219
2220 #[test]
2221 fn acosh_real_valid() {
2222 let v = RealValidated::one();
2223 let expected = 0.;
2224 assert_eq!(v.clone().try_acosh().unwrap().as_ref(), &expected);
2225 assert_eq!(v.clone().acosh().as_ref(), &expected);
2226 }
2227
2228 #[test]
2229 fn acosh_real_out_of_domain() {
2230 let val_lt_1 = RealValidated::try_new(0.5).unwrap();
2231 assert!(matches!(
2232 val_lt_1.try_acosh(),
2233 Err(ACosHErrors::Input {
2234 source: ACosHInputErrors::OutOfDomain { .. }
2235 })
2236 ));
2237 }
2238
2239 #[test]
2240 fn asinh_real_valid() {
2241 let v = RealValidated::one();
2242 let expected = 0.881373587019543;
2243 assert_eq!(v.clone().try_asinh().unwrap().as_ref(), &expected);
2244 assert_eq!(v.clone().asinh().as_ref(), &expected);
2245 }
2246
2247 #[test]
2248 fn sinh_real_valid() {
2249 let v = RealValidated::try_new(0.881373587019543).unwrap();
2250 let expected = 1.;
2251 assert_eq!(v.clone().try_sinh().unwrap().as_ref(), &expected);
2252 assert_eq!(v.clone().sinh().as_ref(), &expected);
2253 }
2254
2255 #[test]
2256 fn cosh_real_valid() {
2257 let v = RealValidated::one();
2258 let expected = 1.5430806348152437;
2259 assert_eq!(v.clone().try_cosh().unwrap().as_ref(), &expected);
2260 assert_eq!(v.clone().cosh().as_ref(), &expected);
2261 }
2262
2263 #[test]
2264 fn tanh_real_valid() {
2265 let v = RealValidated::one();
2266 let expected = 0.7615941559557649;
2267 assert_eq!(v.clone().try_tanh().unwrap().as_ref(), &expected);
2268 assert_eq!(v.clone().tanh().as_ref(), &expected);
2269 }
2270 }
2271
2272 mod complex {
2273 use super::*;
2274
2275 #[test]
2276 fn sinh_valid() {
2277 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2278 let expected = Complex::new(-0.4890562590412937, -1.4031192506220405);
2279 assert_eq!(v.clone().try_sinh().unwrap().as_ref(), &expected);
2280 assert_eq!(v.clone().sinh().as_ref(), &expected);
2281 }
2282
2283 #[test]
2284 fn cosh_valid() {
2285 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2286 let expected = Complex::new(-0.64214812471552, -1.0686074213827783);
2287 assert_eq!(v.clone().try_cosh().unwrap().as_ref(), &expected);
2288 assert_eq!(v.clone().cosh().as_ref(), &expected);
2289 }
2290
2291 #[test]
2292 fn tanh_valid() {
2293 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2294 let expected = if cfg!(target_arch = "x86_64") {
2295 Complex::new(1.16673625724092, 0.24345820118572523)
2296 } else if cfg!(target_arch = "aarch64") {
2297 Complex::new(1.16673625724092, 0.24345820118572528)
2298 } else {
2299 todo!("Missing target architecture!");
2300 };
2301 assert_eq!(v.clone().try_tanh().unwrap().as_ref(), &expected);
2302 assert_eq!(v.clone().tanh().as_ref(), &expected);
2303 }
2304
2305 #[test]
2306 fn asinh_valid() {
2307 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2308 let expected = Complex::new(1.4693517443681852, -1.0634400235777521);
2309 Complex::new(1.4693517443681852, -1.0634400235777521);
2310 assert_eq!(v.clone().try_asinh().unwrap().as_ref(), &expected);
2311 assert_eq!(v.clone().asinh().as_ref(), &expected);
2312 }
2313
2314 #[test]
2315 fn acosh_valid() {
2316 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2317 let expected = Complex::new(1.528570919480998, -1.1437177404024206);
2318 assert_eq!(v.clone().try_acosh().unwrap().as_ref(), &expected);
2319 assert_eq!(v.clone().acosh().as_ref(), &expected);
2320 }
2321
2322 #[test]
2323 fn atanh_valid() {
2324 let v = ComplexValidated::try_new(Complex::new(1., -2.)).unwrap();
2325 let expected = Complex::new(0.1732867951399864, -1.1780972450961724);
2326 assert_eq!(v.clone().try_atanh().unwrap().as_ref(), &expected);
2327 assert_eq!(v.clone().atanh().as_ref(), &expected);
2328 }
2329
2330 #[test]
2349 fn acosh_out_of_domain() {
2350 let val_on_branch_cut = ComplexValidated::try_new_pure_real(0.5).unwrap();
2352 assert!(matches!(
2353 val_on_branch_cut.try_acosh(),
2354 Err(ACosHErrors::Input {
2355 source: ACosHInputErrors::OutOfDomain { .. }
2356 })
2357 ));
2358
2359 let val_on_branch_cut_neg = ComplexValidated::try_new_pure_real(-5.).unwrap();
2360 assert!(matches!(
2361 val_on_branch_cut_neg.try_acosh(),
2362 Err(ACosHErrors::Input {
2363 source: ACosHInputErrors::OutOfDomain { .. }
2364 })
2365 ));
2366 }
2367
2368 #[test]
2369 fn atanh_out_of_domain() {
2370 let val_ge_1 = ComplexValidated::try_new_pure_real(1.).unwrap();
2371 assert!(matches!(
2372 val_ge_1.try_atanh(),
2373 Err(ATanHErrors::Input {
2374 source: ATanHInputErrors::OutOfDomain { .. }
2375 })
2376 ));
2377
2378 let val_le_neg1 = ComplexValidated::try_new_pure_real(-1.).unwrap();
2379 assert!(matches!(
2380 val_le_neg1.try_atanh(),
2381 Err(ATanHErrors::Input {
2382 source: ATanHInputErrors::OutOfDomain { .. }
2383 })
2384 ));
2385 }
2386 }
2387
2388 } }
2406
2407 mod summation {
2408 use super::*;
2409
2410 #[test]
2411 fn sum_real() {
2412 let values = vec![
2413 RealValidated::try_new(1.0).unwrap(),
2414 RealValidated::try_new(2.0).unwrap(),
2415 RealValidated::try_new(3.0).unwrap(),
2416 RealValidated::try_new(4.0).unwrap(),
2417 RealValidated::try_new(5.0).unwrap(),
2418 ];
2419 let sum: RealValidated = values.into_iter().sum();
2420 assert_eq!(sum, RealValidated::try_new(15.0).unwrap());
2421 }
2422
2423 #[test]
2424 fn sum_real_compensated() {
2425 let values = vec![
2427 RealValidated::try_new(1.0e100).unwrap(),
2428 RealValidated::try_new(1.0).unwrap(),
2429 RealValidated::try_new(-1.0e100).unwrap(),
2430 ];
2431 let sum: RealValidated = values.into_iter().sum();
2432 assert_eq!(sum, RealValidated::try_new(1.0).unwrap());
2434 }
2435
2436 #[test]
2437 fn sum_complex() {
2438 let values = vec![
2439 ComplexValidated::try_new(Complex::new(1.0, 2.0)).unwrap(),
2440 ComplexValidated::try_new(Complex::new(3.0, 4.0)).unwrap(),
2441 ComplexValidated::try_new(Complex::new(5.0, 6.0)).unwrap(),
2442 ];
2443 let sum: ComplexValidated = values.into_iter().sum();
2444 assert_eq!(
2445 sum,
2446 ComplexValidated::try_new(Complex::new(9.0, 12.0)).unwrap()
2447 );
2448 }
2449
2450 #[test]
2451 fn sum_complex_compensated() {
2452 let values = vec![
2453 ComplexValidated::try_new(Complex::new(1.0e100, -1.0e100)).unwrap(),
2454 ComplexValidated::try_new(Complex::new(1.0, 2.0)).unwrap(),
2455 ComplexValidated::try_new(Complex::new(-1.0e100, 1.0e100)).unwrap(),
2456 ];
2457 let sum: ComplexValidated = values.into_iter().sum();
2458 assert_eq!(
2459 sum,
2460 ComplexValidated::try_new(Complex::new(1.0, 2.0)).unwrap()
2461 );
2462 }
2463 } mod neumaier_sum {
2466 use crate::neumaier_compensated_sum::NeumaierSum;
2467 use try_create::TryNewValidated;
2468
2469 use super::*;
2470
2471 mod real {
2472 use super::*;
2473
2474 #[test]
2475 fn new() {
2476 let neumaier = NeumaierSum::new(RealValidated::try_new_validated(1.0).unwrap());
2477 assert_eq!(neumaier.sum_before_compensation(), &1.0);
2478 assert_eq!(neumaier.compensation(), &0.0);
2479 }
2480
2481 #[test]
2482 fn zero() {
2483 let neumaier = NeumaierSum::<RealValidated>::zero();
2484 assert_eq!(neumaier.sum_before_compensation(), &0.0);
2485 assert_eq!(neumaier.compensation(), &0.0);
2486 }
2487
2488 #[test]
2489 fn add() {
2490 let mut neumaier = NeumaierSum::zero();
2491 neumaier.add(RealValidated::try_new_validated(1.0).unwrap());
2492 neumaier.add(RealValidated::try_new_validated(1e-16).unwrap());
2493 neumaier.add(RealValidated::try_new_validated(-1.0).unwrap());
2494 assert_eq!(neumaier.sum_before_compensation(), &0.0);
2495 assert_eq!(neumaier.compensation(), &1e-16);
2496 }
2497
2498 #[test]
2499 fn sum() {
2500 let mut neumaier = NeumaierSum::zero();
2501 neumaier.add(RealValidated::try_new_validated(1.0).unwrap());
2502 neumaier.add(RealValidated::try_new_validated(1e-16).unwrap());
2503 neumaier.add(RealValidated::try_new_validated(-1.0).unwrap());
2504 assert_eq!(neumaier.sum_before_compensation(), &0.0);
2505 assert_eq!(neumaier.compensation(), &1e-16);
2506 assert_eq!(neumaier.sum().as_ref(), &1e-16);
2507 println!("compensated sum = {}", neumaier.sum());
2508 }
2509
2510 #[test]
2511 fn reset() {
2512 let mut neumaier = NeumaierSum::zero();
2513 neumaier.add(RealValidated::try_new_validated(1.0).unwrap());
2514 neumaier.add(RealValidated::try_new_validated(1e-16).unwrap());
2515 assert_eq!(neumaier.sum_before_compensation(), &1.0);
2516 assert_eq!(neumaier.compensation(), &1e-16);
2517
2518 neumaier.reset();
2519 assert_eq!(neumaier.sum_before_compensation(), &0.0);
2520 assert_eq!(neumaier.compensation(), &0.0);
2521 }
2522
2523 #[test]
2524 fn sum_big_values() {
2525 let values = [1.0, 1e100, 1.0, -1e100]
2526 .iter()
2527 .map(|&v| RealValidated::try_new_validated(v).unwrap())
2528 .collect::<Vec<_>>();
2529 let sum = values.iter().cloned().sum::<RealValidated>();
2530 assert_eq!(sum, 2.0);
2531
2532 let neumaier = NeumaierSum::new_sequential(values);
2533 assert_eq!(neumaier.sum(), 2.0);
2534 println!("compensated sum = {}", neumaier.sum());
2535 }
2536
2537 #[test]
2538 fn sum_small_values() {
2539 let values = [1.0, 1e-100, -1.0]
2540 .iter()
2541 .map(|&v| RealValidated::try_new_validated(v).unwrap())
2542 .collect::<Vec<_>>();
2543 let sum = values.iter().cloned().sum::<RealValidated>();
2544 assert_eq!(sum, 1e-100);
2545
2546 let neumaier = NeumaierSum::new_sequential(values);
2547 assert_eq!(neumaier.sum(), 1e-100);
2548 println!("compensated sum = {}", neumaier.sum());
2549 }
2550 }
2551
2552 mod complex {
2553 use super::*;
2554
2555 #[test]
2556 fn new() {
2557 let neumaier = NeumaierSum::new(
2558 ComplexValidated::try_new_validated(Complex::new(1.0, 2.0)).unwrap(),
2559 );
2560 assert_eq!(
2561 neumaier.sum_before_compensation().as_ref(),
2562 &Complex::new(1.0, 2.0)
2563 );
2564 assert_eq!(neumaier.compensation().as_ref(), &Complex::new(0.0, 0.0));
2565 }
2566
2567 #[test]
2568 fn zero() {
2569 let neumaier = NeumaierSum::<ComplexValidated>::zero();
2570
2571 let zero = Complex::new(0.0, 0.0);
2572 assert_eq!(neumaier.sum_before_compensation().as_ref(), &zero);
2573 assert_eq!(neumaier.compensation().as_ref(), &zero);
2574 }
2575
2576 #[test]
2577 fn add() {
2578 let zero = Complex::new(0.0, 0.0);
2579 let v = Complex::new(1e-16, 2e-16);
2580
2581 let mut neumaier = NeumaierSum::zero();
2582 neumaier.add(ComplexValidated::try_new_validated(Complex::new(1.0, 2.0)).unwrap());
2583 neumaier.add(ComplexValidated::try_new_validated(v).unwrap());
2584 neumaier
2585 .add(ComplexValidated::try_new_validated(Complex::new(-1.0, -2.0)).unwrap());
2586
2587 assert_eq!(neumaier.sum_before_compensation().as_ref(), &zero);
2588 assert_eq!(neumaier.compensation().as_ref(), &v);
2589 }
2590
2591 #[test]
2592 fn sum() {
2593 let zero = Complex::new(0.0, 0.0);
2594 let v = Complex::new(1e-16, 2e-16);
2595
2596 let mut neumaier = NeumaierSum::zero();
2597 neumaier.add(ComplexValidated::try_new_validated(Complex::new(1.0, 2.0)).unwrap());
2598 neumaier.add(ComplexValidated::try_new_validated(v).unwrap());
2599 neumaier
2600 .add(ComplexValidated::try_new_validated(Complex::new(-1.0, -2.0)).unwrap());
2601 assert_eq!(neumaier.sum_before_compensation().as_ref(), &zero);
2602 assert_eq!(neumaier.compensation().as_ref(), &v);
2603 assert_eq!(neumaier.sum().as_ref(), &v);
2604 println!("compensated sum = {}", neumaier.sum());
2605 }
2606
2607 #[test]
2608 fn reset() {
2609 let zero = Complex::new(0.0, 0.0);
2610 let a = Complex::new(1.0, 2.0);
2611 let v = Complex::new(1e-16, 2e-16);
2612
2613 let mut neumaier = NeumaierSum::zero();
2614 neumaier.add(ComplexValidated::try_new_validated(a).unwrap());
2615 neumaier.add(ComplexValidated::try_new_validated(v).unwrap());
2616 assert_eq!(neumaier.sum_before_compensation().as_ref(), &a);
2617 assert_eq!(neumaier.compensation().as_ref(), &v);
2618
2619 neumaier.reset();
2620 assert_eq!(neumaier.sum_before_compensation().as_ref(), &zero);
2621 assert_eq!(neumaier.compensation().as_ref(), &zero);
2622 }
2623
2624 #[test]
2625 fn sum_big_values() {
2626 let values = [
2627 Complex::new(1.0, 2.0),
2628 Complex::new(1e100, 2e100),
2629 Complex::new(1.0, 2.0),
2630 Complex::new(-1e100, -2e100),
2631 ]
2632 .iter()
2633 .map(|&v| ComplexValidated::try_new_validated(v).unwrap())
2634 .collect::<Vec<_>>();
2635 let sum = values.clone().into_iter().sum::<ComplexValidated>();
2636 let expected_sum = Complex::new(2., 4.);
2637 assert_eq!(sum.as_ref(), &expected_sum);
2638
2639 let neumaier = NeumaierSum::new_sequential(values);
2640 assert_eq!(neumaier.sum().as_ref(), &expected_sum);
2641 println!("compensated sum = {}", neumaier.sum());
2642 }
2643
2644 #[test]
2645 fn sum_small_values() {
2646 let v = Complex::new(1e-100, 2e-100);
2647
2648 let values = [Complex::new(1.0, 2.0), v, Complex::new(-1.0, -2.0)]
2649 .iter()
2650 .map(|&v| ComplexValidated::try_new_validated(v).unwrap())
2651 .collect::<Vec<_>>();
2652 let sum = values.iter().cloned().sum::<ComplexValidated>();
2653 let sum_expected = v;
2654 assert_eq!(sum.as_ref(), &sum_expected);
2655
2656 let neumaier = NeumaierSum::new_sequential(values);
2657 assert_eq!(neumaier.sum().as_ref(), &sum_expected);
2658 println!("compensated sum = {}", neumaier.sum());
2659 }
2660 }
2661 }
2662
2663 mod random {
2664 use super::*;
2665 use crate::{
2666 RandomSampleFromF64,
2667 kernels::native64_validated::{ComplexNative64StrictFinite, RealNative64StrictFinite},
2668 new_random_vec,
2669 };
2670 use rand::{Rng, SeedableRng, distr::Uniform, rngs::StdRng};
2671
2672 #[test]
2676 fn test_random_real_validated() {
2677 let seed = [42; 32];
2678 let mut rng = StdRng::from_seed(seed);
2679
2680 let random_real: RealNative64StrictFinite = rng.random();
2681
2682 assert_eq!(random_real, 0.23713468825474326);
2684
2685 let mut rng2 = StdRng::from_seed(seed);
2687 let random_real2: RealNative64StrictFinite = rng2.random();
2688 assert_eq!(random_real, random_real2);
2689 }
2690
2691 #[test]
2696 fn test_random_complex_validated() {
2697 let seed = [99; 32];
2698 let mut rng = StdRng::from_seed(seed);
2699
2700 let random_complex: ComplexNative64StrictFinite = rng.random();
2701
2702 let real_part = random_complex.real_part();
2705 let imag_part = random_complex.imag_part();
2706
2707 assert_eq!(real_part, 0.9995546882627792);
2708 assert_eq!(imag_part, 0.08932180682540247);
2709
2710 let mut rng2 = StdRng::from_seed(seed);
2712 let random_complex2: ComplexNative64StrictFinite = rng2.random();
2713 assert_eq!(random_complex, random_complex2);
2714 }
2715
2716 const SEED: [u8; 32] = [42; 32];
2717
2718 #[test]
2719 fn test_sample_real_validated() {
2720 let mut rng = StdRng::from_seed(SEED);
2721 let dist = Uniform::new(-10.0, 10.0).unwrap();
2722
2723 let val = RealNative64StrictFinite::sample_from(&dist, &mut rng);
2724 assert_eq!(val, -5.257306234905137);
2725
2726 let mut rng2 = StdRng::from_seed(SEED);
2728 let val2 = RealNative64StrictFinite::sample_from(&dist, &mut rng2);
2729 assert_eq!(val, val2);
2730 }
2731
2732 #[test]
2733 fn test_sample_complex_validated() {
2734 let mut rng = StdRng::from_seed(SEED);
2735 let dist = Uniform::new(-10.0, 10.0).unwrap();
2736
2737 let val = ComplexNative64StrictFinite::sample_from(&dist, &mut rng);
2738 assert_eq!(val.real_part(), -5.257306234905137);
2739 assert_eq!(val.imag_part(), 7.212119776268775);
2740
2741 let mut rng2 = StdRng::from_seed(SEED);
2743 let val2 = ComplexNative64StrictFinite::sample_from(&dist, &mut rng2);
2744 assert_eq!(val, val2);
2745 }
2746
2747 #[test]
2748 fn new_random_vec_real() {
2749 let mut rng = StdRng::from_seed(SEED);
2750 let dist = Uniform::new(-10.0, 10.0).unwrap();
2751 let vec: Vec<RealNative64StrictFinite> = new_random_vec(3, &dist, &mut rng);
2752 assert_eq!(vec.len(), 3);
2753 assert_eq!(vec[0], -5.257306234905137);
2754 assert_eq!(vec[1], 7.212119776268775);
2755 assert_eq!(vec[2], -4.666248990558111);
2756
2757 let mut rng2 = StdRng::from_seed(SEED);
2759 let vec2: Vec<RealNative64StrictFinite> = new_random_vec(3, &dist, &mut rng2);
2760 assert_eq!(vec, vec2);
2761 }
2762
2763 #[test]
2764 fn new_random_vec_complex() {
2765 let mut rng = StdRng::from_seed(SEED);
2766 let dist = Uniform::new(-10.0, 10.0).unwrap();
2767 let vec: Vec<ComplexNative64StrictFinite> = new_random_vec(3, &dist, &mut rng);
2768 assert_eq!(vec.len(), 3);
2769 assert_eq!(vec[0].real_part(), -5.257306234905137);
2770 assert_eq!(vec[0].imag_part(), 7.212119776268775);
2771 assert_eq!(vec[1].real_part(), -4.666248990558111);
2772 assert_eq!(vec[1].imag_part(), 9.66047141517383);
2773 assert_eq!(vec[2].real_part(), -9.04279551029691);
2774 assert_eq!(vec[2].imag_part(), -1.026624649331671);
2775
2776 let mut rng2 = StdRng::from_seed(SEED);
2778 let vec2: Vec<ComplexNative64StrictFinite> = new_random_vec(3, &dist, &mut rng2);
2779 assert_eq!(vec, vec2);
2780 }
2781 }
2782
2783 mod hash_map_key_usage {
2784 use crate::{
2785 functions::Sign,
2786 kernels::native64_validated::{
2787 RealNative64StrictFinite, RealNative64StrictFiniteInDebug,
2788 },
2789 };
2790 use std::collections::HashMap;
2791 use try_create::TryNew;
2792
2793 #[test]
2794 fn test_native64_as_hashmap_key() {
2795 let mut map = HashMap::new();
2796 let key1 = RealNative64StrictFinite::try_new(1.0).unwrap();
2797 let key2 = RealNative64StrictFinite::try_new(2.5).unwrap();
2798
2799 map.insert(key1.clone(), "one");
2800 map.insert(key2, "two_point_five");
2801
2802 assert_eq!(
2803 map.get(&RealNative64StrictFinite::try_new(1.0).unwrap()),
2804 Some(&"one")
2805 );
2806 assert_eq!(map.len(), 2);
2807
2808 let old_value = map.insert(key1.clone(), "new_one");
2810 assert_eq!(old_value, Some("one"));
2811 assert_eq!(map.get(&key1), Some(&"new_one"));
2812 }
2813
2814 #[test]
2815 fn test_native64_debug_as_hashmap_key() {
2816 let mut map = HashMap::new();
2817 let key1 = RealNative64StrictFiniteInDebug::try_new(1.0).unwrap();
2818 let key2 = RealNative64StrictFiniteInDebug::try_new(2.5).unwrap();
2819
2820 map.insert(key1.clone(), "one_debug");
2821 map.insert(key2, "two_point_five_debug");
2822
2823 assert_eq!(
2824 map.get(&RealNative64StrictFiniteInDebug::try_new(1.0).unwrap()),
2825 Some(&"one_debug")
2826 );
2827 assert_eq!(map.len(), 2);
2828
2829 let old_value = map.insert(key1.clone(), "new_one_debug");
2831 assert_eq!(old_value, Some("one_debug"));
2832 assert_eq!(map.get(&key1), Some(&"new_one_debug"));
2833 }
2834
2835 #[test]
2836 fn test_hashmap_basic_operations() {
2837 let mut map = HashMap::new();
2838 let key1 = RealNative64StrictFinite::try_new(1.0).unwrap();
2839 let key2 = RealNative64StrictFinite::try_new(2.5).unwrap();
2840 let key3 = RealNative64StrictFinite::try_new(1.0).unwrap(); assert_eq!(map.insert(key1, "one"), None);
2844 assert_eq!(map.insert(key2, "two_point_five"), None);
2845 assert_eq!(map.len(), 2);
2846
2847 assert_eq!(map.get(&key3), Some(&"one"));
2849
2850 assert_eq!(map.insert(key3, "one_updated"), Some("one"));
2852 assert_eq!(map.len(), 2); }
2854
2855 #[test]
2856 fn test_hashset_operations() {
2857 use std::collections::HashSet;
2858 let mut set = HashSet::new();
2859
2860 let val1 = RealNative64StrictFinite::try_new(1.0).unwrap();
2861 let val2 = RealNative64StrictFinite::try_new(2.0).unwrap();
2862 let val1_duplicate = RealNative64StrictFinite::try_new(1.0).unwrap();
2863
2864 assert!(set.insert(val1));
2865 assert!(set.insert(val2));
2866 assert!(!set.insert(val1_duplicate)); assert_eq!(set.len(), 2);
2869 assert!(set.contains(&RealNative64StrictFinite::try_new(1.0).unwrap()));
2870 }
2871
2872 #[test]
2873 fn test_hash_consistency() {
2874 use std::collections::hash_map::DefaultHasher;
2875 use std::hash::{Hash, Hasher};
2876
2877 let val1 = RealNative64StrictFinite::try_new(1.234).unwrap();
2878 let val2 = RealNative64StrictFinite::try_new(1.234).unwrap();
2879
2880 let mut hasher1 = DefaultHasher::new();
2882 let mut hasher2 = DefaultHasher::new();
2883
2884 val1.hash(&mut hasher1);
2885 val2.hash(&mut hasher2);
2886
2887 assert_eq!(hasher1.finish(), hasher2.finish());
2888 assert_eq!(val1, val2); }
2890
2891 #[test]
2892 fn test_hash_signed_zero() {
2893 use std::collections::hash_map::DefaultHasher;
2894 use std::hash::{Hash, Hasher};
2895
2896 let val1 = RealNative64StrictFinite::try_new(0.0).unwrap();
2897 assert!(val1.kernel_is_sign_positive());
2898 let val2 = RealNative64StrictFinite::try_new(-0.0).unwrap();
2899 assert!(val2.kernel_is_sign_negative());
2900
2901 assert_ne!(
2903 0.0f64.to_bits(),
2904 (-0.0f64).to_bits(),
2905 "Sanity check: +0.0 and -0.0 should have different bit patterns"
2906 );
2907
2908 assert_eq!(val1, val2); let mut hasher1 = DefaultHasher::new();
2912 let mut hasher2 = DefaultHasher::new();
2913
2914 val1.hash(&mut hasher1);
2915 val2.hash(&mut hasher2);
2916
2917 assert_eq!(hasher1.finish(), hasher2.finish());
2918 }
2919 }
2920
2921 mod test_truncate_to_usize {
2922 use super::*;
2923 use crate::validation::ErrorsRawRealToInteger;
2924
2925 #[test]
2926 fn test_positive_integers() {
2927 let value = RealNative64StrictFinite::try_new(42.0).unwrap();
2929 assert_eq!(value.truncate_to_usize().unwrap(), 42);
2930
2931 let value = RealNative64StrictFinite::try_new(1.0).unwrap();
2932 assert_eq!(value.truncate_to_usize().unwrap(), 1);
2933
2934 let value = RealNative64StrictFinite::try_new(100.0).unwrap();
2935 assert_eq!(value.truncate_to_usize().unwrap(), 100);
2936 }
2937
2938 #[test]
2939 fn test_positive_fractionals_truncate() {
2940 let value = RealNative64StrictFinite::try_new(42.9).unwrap();
2942 assert_eq!(value.truncate_to_usize().unwrap(), 42);
2943
2944 let value = RealNative64StrictFinite::try_new(3.7).unwrap();
2945 assert_eq!(value.truncate_to_usize().unwrap(), 3);
2946
2947 let value = RealNative64StrictFinite::try_new(0.9).unwrap();
2948 assert_eq!(value.truncate_to_usize().unwrap(), 0);
2949
2950 let value = RealNative64StrictFinite::try_new(99.999).unwrap();
2951 assert_eq!(value.truncate_to_usize().unwrap(), 99);
2952 }
2953
2954 #[test]
2955 fn test_zero_cases() {
2956 let value = RealNative64StrictFinite::try_new(0.0).unwrap();
2958 assert_eq!(value.truncate_to_usize().unwrap(), 0);
2959
2960 let value = RealNative64StrictFinite::try_new(0.1).unwrap();
2962 assert_eq!(value.truncate_to_usize().unwrap(), 0);
2963
2964 let value = RealNative64StrictFinite::try_new(0.5).unwrap();
2965 assert_eq!(value.truncate_to_usize().unwrap(), 0);
2966 }
2967
2968 #[test]
2969 fn test_large_valid_values() {
2970 let value = RealNative64StrictFinite::try_new(1_000_000.7).unwrap();
2972 assert_eq!(value.truncate_to_usize().unwrap(), 1_000_000);
2973
2974 let value = RealNative64StrictFinite::try_new(1_000_000_000.0).unwrap();
2975 assert_eq!(value.truncate_to_usize().unwrap(), 1_000_000_000);
2976
2977 let max_safe = (usize::MAX as f64) - 2048.0; let value = RealNative64StrictFinite::try_new(max_safe).unwrap();
2980 let result = value.truncate_to_usize().unwrap();
2981 assert!(result < usize::MAX);
2982 }
2983
2984 #[test]
2985 fn test_negative_values_error() {
2986 let value = RealNative64StrictFinite::try_new(-1.0).unwrap();
2988 let result = value.truncate_to_usize();
2989 assert!(matches!(
2990 result,
2991 Err(ErrorsRawRealToInteger::OutOfRange { .. })
2992 ));
2993
2994 let value = RealNative64StrictFinite::try_new(-10.5).unwrap();
2995 let result = value.truncate_to_usize();
2996 assert!(matches!(
2997 result,
2998 Err(ErrorsRawRealToInteger::OutOfRange { .. })
2999 ));
3000
3001 let value = RealNative64StrictFinite::try_new(-0.1).unwrap();
3002 let result = value.truncate_to_usize();
3003 assert!(matches!(result, Ok(0)));
3004
3005 let value = RealNative64StrictFinite::try_new(-1000.0).unwrap();
3006 let result = value.truncate_to_usize();
3007 assert!(matches!(
3008 result,
3009 Err(ErrorsRawRealToInteger::OutOfRange { .. })
3010 ));
3011 }
3012
3013 #[test]
3014 fn test_too_large_values_error() {
3015 let too_large = (usize::MAX as f64) * 2.0;
3017 let value = RealNative64StrictFinite::try_new(too_large).unwrap();
3018 let result = value.truncate_to_usize();
3019 assert!(matches!(
3020 result,
3021 Err(ErrorsRawRealToInteger::OutOfRange { .. })
3022 ));
3023
3024 let value = RealNative64StrictFinite::try_new(1e20).unwrap();
3025 let result = value.truncate_to_usize();
3026 assert!(matches!(
3027 result,
3028 Err(ErrorsRawRealToInteger::OutOfRange { .. })
3029 ));
3030 }
3031
3032 #[test]
3033 fn test_edge_cases() {
3034 let value = RealNative64StrictFinite::try_new(f64::EPSILON).unwrap();
3038 assert_eq!(value.truncate_to_usize().unwrap(), 0);
3039
3040 let value = RealNative64StrictFinite::try_new(1.0 - f64::EPSILON).unwrap();
3042 assert_eq!(value.truncate_to_usize().unwrap(), 0);
3043
3044 let value = RealNative64StrictFinite::try_new(1.0 + f64::EPSILON).unwrap();
3046 assert_eq!(value.truncate_to_usize().unwrap(), 1);
3047 }
3048
3049 #[test]
3050 fn test_truncation_behavior() {
3051 let test_cases = [
3053 (2.1, 2),
3054 (2.5, 2), (2.9, 2),
3056 (3.0, 3),
3057 (3.1, 3),
3058 (99.999, 99),
3059 ];
3060
3061 for (input, expected) in test_cases {
3062 let value = RealNative64StrictFinite::try_new(input)
3063 .unwrap()
3064 .truncate_to_usize()
3065 .unwrap();
3066 assert_eq!(
3067 value, expected,
3068 "Failed for input {}: expected {}, got {:?}",
3069 input, expected, value
3070 );
3071 }
3072 }
3073
3074 #[test]
3075 fn test_error_details() {
3076 let value = RealNative64StrictFinite::try_new(-5.0).unwrap();
3080 if let Err(ErrorsRawRealToInteger::OutOfRange {
3081 value: err_val,
3082 min,
3083 max,
3084 ..
3085 }) = value.truncate_to_usize()
3086 {
3087 assert_eq!(err_val, -5.0);
3088 assert_eq!(min, usize::MIN);
3089 assert_eq!(max, usize::MAX);
3090 } else {
3091 panic!("Expected OutOfRange error for negative value");
3092 }
3093
3094 let large_value = 1e20;
3096 let value = RealNative64StrictFinite::try_new(large_value).unwrap();
3097 if let Err(ErrorsRawRealToInteger::OutOfRange {
3098 value: err_val,
3099 min,
3100 max,
3101 ..
3102 }) = value.truncate_to_usize()
3103 {
3104 assert_eq!(err_val, large_value);
3105 assert_eq!(min, usize::MIN);
3106 assert_eq!(max, usize::MAX);
3107 } else {
3108 panic!("Expected OutOfRange error for large value");
3109 }
3110 }
3111
3112 #[test]
3113 fn test_practical_usage_scenario() {
3114 fn create_vector_with_calculated_size<T: Default + Clone>(
3116 size_float: RealNative64StrictFinite,
3117 ) -> Result<Vec<T>, Box<dyn std::error::Error>> {
3118 let size = size_float.truncate_to_usize()?;
3119 Ok(vec![T::default(); size])
3120 }
3121
3122 let calculated_size = RealNative64StrictFinite::try_new(10.7).unwrap();
3124 let vec: Vec<i32> = create_vector_with_calculated_size(calculated_size).unwrap();
3125 assert_eq!(vec.len(), 10); let negative_size = RealNative64StrictFinite::try_new(-5.0).unwrap();
3129 let result: Result<Vec<i32>, _> = create_vector_with_calculated_size(negative_size);
3130 assert!(result.is_err());
3131
3132 let huge_size = RealNative64StrictFinite::try_new(1e20).unwrap();
3134 let result: Result<Vec<i32>, _> = create_vector_with_calculated_size(huge_size);
3135 assert!(result.is_err());
3136 }
3137
3138 #[test]
3139 fn test_consistency_with_f64_behavior() {
3140 let test_values = [0.0, 1.0, 2.5, 42.9, 100.0, 0.1, 0.9];
3142
3143 for &val in &test_values {
3144 let validated = RealNative64StrictFinite::try_new(val).unwrap();
3145 let result = validated.truncate_to_usize().unwrap();
3146
3147 let expected = val.trunc() as usize;
3149 assert_eq!(result, expected, "Mismatch for value {}", val);
3150 }
3151 }
3152 }
3153}