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