1#![deny(rustdoc::broken_intra_doc_links)]
2
3use crate::{
4 functions::FunctionErrors,
5 kernels::{RawComplexTrait, RawRealTrait, RawScalarTrait},
6 validation::{StrictFinitePolicy, capture_backtrace},
7};
8use duplicate::duplicate_item;
9use num::{Complex, Zero};
10use num_traits::int::PrimInt;
11use std::backtrace::Backtrace;
12use thiserror::Error;
13use try_create::ValidationPolicy;
14
15pub trait IntegerExponent: PrimInt {}
18
19impl IntegerExponent for i8 {}
20impl IntegerExponent for u8 {}
21impl IntegerExponent for i16 {}
22impl IntegerExponent for u16 {}
23impl IntegerExponent for i32 {}
24impl IntegerExponent for u32 {}
25impl IntegerExponent for i64 {}
26impl IntegerExponent for u64 {}
27impl IntegerExponent for i128 {}
28impl IntegerExponent for u128 {}
29impl IntegerExponent for isize {}
30impl IntegerExponent for usize {}
31#[derive(Debug, Error)]
41pub enum PowRealBaseRealExponentInputErrors<RawReal: RawRealTrait> {
42 #[error("detected a negative base ({base}) with a real exponent ({exponent}) !")]
46 NegativeBase {
47 base: RawReal,
49
50 exponent: RawReal,
52
53 backtrace: Backtrace,
55 },
56
57 #[error("the base is invalid!")]
62 InvalidBase {
63 #[source]
66 #[backtrace]
67 source: <RawReal as RawScalarTrait>::ValidationErrors,
68 },
69
70 #[error("the exponent is invalid!")]
75 InvalidExponent {
76 #[source]
79 #[backtrace]
80 source: <RawReal as RawScalarTrait>::ValidationErrors,
81 },
82
83 #[error("the base and the exponent are invalid!")]
84 InvalidBaseAndExponent {
85 error_base: <RawReal as RawScalarTrait>::ValidationErrors,
87
88 error_exponent: <RawReal as RawScalarTrait>::ValidationErrors,
90
91 #[backtrace]
92 backtrace: Backtrace,
93 },
94}
95#[derive(Debug, Error)]
105pub enum PowComplexBaseRealExponentInputErrors<RawComplex: RawComplexTrait> {
106 #[error("the input complex base is invalid according to validation policy")]
111 InvalidBase {
112 #[source]
115 #[backtrace]
116 source: <RawComplex as RawScalarTrait>::ValidationErrors,
117 },
118
119 #[error("the input real exponent is invalid according to validation policy")]
124 InvalidExponent {
125 #[source]
128 #[backtrace]
129 source: <RawComplex::RawReal as RawScalarTrait>::ValidationErrors,
130 },
131
132 #[error(
137 "the input complex base and the real exponent is invalid according to validation policy"
138 )]
139 InvalidBaseAndExponent {
140 error_base: <RawComplex as RawScalarTrait>::ValidationErrors,
142
143 error_exponent: <RawComplex::RawReal as RawScalarTrait>::ValidationErrors,
145
146 #[backtrace]
147 backtrace: Backtrace,
148 },
149
150 #[error("the base is zero and the exponent (={exponent}) is negative!")]
153 ZeroBaseNegativeExponent {
154 exponent: RawComplex::RawReal,
156
157 backtrace: Backtrace,
159 },
160}
161#[derive(Debug, Error)]
189pub enum PowIntExponentInputErrors<RawScalar: RawScalarTrait, ExponentType: IntegerExponent> {
190 #[error("the input base is invalid according to validation policy")]
195 InvalidBase {
196 #[source]
199 #[backtrace]
200 source: <RawScalar as RawScalarTrait>::ValidationErrors,
201 },
202
203 #[error("detected a zero base with a negative integer exponent ({exponent:?})!")]
206 ZeroBaseNegativeExponent {
207 exponent: ExponentType,
209
210 backtrace: Backtrace,
212 },
213 }
218#[derive(Debug, Error)]
230pub enum PowRealBaseRealExponentErrors<RawReal: RawRealTrait> {
231 #[error("the input value is invalid!")]
233 Input {
234 #[from]
236 source: PowRealBaseRealExponentInputErrors<RawReal>,
237 },
238
239 #[error("the output value is invalid!")]
241 Output {
242 #[source]
244 #[backtrace]
245 source: <RawReal as RawScalarTrait>::ValidationErrors,
246 },
247}
248#[derive(Debug, Error)]
259pub enum PowComplexBaseRealExponentErrors<RawComplex: RawComplexTrait> {
260 #[error("the input value is invalid!")]
262 Input {
263 #[from]
265 source: PowComplexBaseRealExponentInputErrors<RawComplex>,
266 },
267
268 #[error("the output value is invalid!")]
270 Output {
271 #[source]
273 #[backtrace]
274 source: <RawComplex as RawScalarTrait>::ValidationErrors,
275 },
276}
277pub type PowIntExponentErrors<RawScalar, ExponentType> = FunctionErrors<
289 PowIntExponentInputErrors<RawScalar, ExponentType>,
290 <RawScalar as RawScalarTrait>::ValidationErrors,
291>;
292pub trait Pow<ExponentType>: Sized {
307 type Error: std::error::Error;
310
311 fn try_pow(self, exponent: ExponentType) -> Result<Self, Self::Error>;
323
324 fn pow(self, exponent: ExponentType) -> Self;
357}
358
359impl Pow<&f64> for f64 {
360 type Error = PowRealBaseRealExponentErrors<f64>;
361
362 #[inline(always)]
363 fn try_pow(self, exponent: &f64) -> Result<Self, Self::Error> {
364 let validation_base = StrictFinitePolicy::<f64, 53>::validate(self);
365 let validation_exponent = StrictFinitePolicy::<f64, 53>::validate_ref(exponent);
366 match (validation_base, validation_exponent) {
367 (Ok(base), Ok(())) => {
368 if base < 0.0 {
369 Err(PowRealBaseRealExponentInputErrors::NegativeBase {
370 base,
371 exponent: *exponent,
372 backtrace: capture_backtrace(),
373 }
374 .into())
375 } else {
376 let result = base.powf(*exponent);
377 StrictFinitePolicy::<f64, 53>::validate(result)
378 .map_err(|e| PowRealBaseRealExponentErrors::Output { source: e })
379 }
380 }
381 (Ok(_), Err(error_exponent)) => {
382 Err(PowRealBaseRealExponentInputErrors::InvalidExponent {
383 source: error_exponent,
384 }
385 .into())
386 }
387 (Err(error_base), Ok(_)) => {
388 Err(PowRealBaseRealExponentInputErrors::InvalidBase { source: error_base }.into())
389 }
390 (Err(error_base), Err(error_exponent)) => {
391 Err(PowRealBaseRealExponentInputErrors::InvalidBaseAndExponent {
392 error_base,
393 error_exponent,
394 backtrace: capture_backtrace(),
395 }
396 .into())
397 }
398 }
399 }
400
401 #[inline(always)]
402 fn pow(self, exponent: &f64) -> Self {
404 #[cfg(debug_assertions)]
405 {
406 self.try_pow(exponent).unwrap()
407 }
408 #[cfg(not(debug_assertions))]
409 {
410 self.powf(*exponent)
411 }
412 }
413}
414
415impl Pow<&f64> for Complex<f64> {
416 type Error = PowComplexBaseRealExponentErrors<Self>;
417
418 #[inline(always)]
419 fn try_pow(self, exponent: &f64) -> Result<Self, Self::Error> {
420 let validation_base = StrictFinitePolicy::<Complex<f64>, 53>::validate(self);
421 let validation_exponent = StrictFinitePolicy::<f64, 53>::validate_ref(exponent);
422 match (validation_base, validation_exponent) {
423 (Ok(base), Ok(())) => {
424 if Zero::is_zero(&base) {
425 if *exponent < 0.0 {
426 Err(
427 PowComplexBaseRealExponentInputErrors::ZeroBaseNegativeExponent {
428 exponent: *exponent,
429 backtrace: capture_backtrace(),
430 }
431 .into(),
432 )
433 } else if *exponent == 0.0 {
434 Ok(Complex::new(1.0, 0.0))
435 } else {
436 Ok(Complex::new(0.0, 0.0))
437 }
438 } else {
439 let result = base.powf(*exponent);
440 StrictFinitePolicy::<Complex<f64>, 53>::validate(result)
441 .map_err(|e| PowComplexBaseRealExponentErrors::Output { source: e })
442 }
443 }
444 (Ok(_), Err(error_exponent)) => {
445 Err(PowComplexBaseRealExponentInputErrors::InvalidExponent {
446 source: error_exponent,
447 }
448 .into())
449 }
450 (Err(error_base), Ok(_)) => {
451 Err(
452 PowComplexBaseRealExponentInputErrors::InvalidBase { source: error_base }
453 .into(),
454 )
455 }
456 (Err(error_base), Err(error_exponent)) => Err(
457 PowComplexBaseRealExponentInputErrors::InvalidBaseAndExponent {
458 error_base,
459 error_exponent,
460 backtrace: capture_backtrace(),
461 }
462 .into(),
463 ),
464 }
465 }
466
467 #[inline(always)]
468 fn pow(self, exponent: &f64) -> Self {
470 #[cfg(debug_assertions)]
471 {
472 self.try_pow(exponent)
473 .expect("Error raised by Pow::try_pow() in the function Pow::pow() (debug mode)")
474 }
475 #[cfg(not(debug_assertions))]
476 {
477 self.powf(*exponent)
478 }
479 }
480}
481
482#[duplicate_item(
483 exponent_type exponent_func;
484 [i8] [exponent.into()];
485 [i16] [exponent.into()];
486 [i32] [exponent];
487 [i64] [exponent.try_into().unwrap()];
488 [i128] [exponent.try_into().unwrap()];
489 [isize] [exponent.try_into().unwrap()];
490)]
491impl Pow<exponent_type> for f64 {
492 type Error = PowIntExponentErrors<f64, exponent_type>;
493
494 fn try_pow(self, exponent: exponent_type) -> Result<Self, Self::Error> {
495 StrictFinitePolicy::<f64, 53>::validate(self)
496 .map_err(|e| PowIntExponentInputErrors::InvalidBase { source: e }.into())
497 .and_then(|base| {
498 if base == 0. && exponent < 0 {
499 Err(PowIntExponentInputErrors::ZeroBaseNegativeExponent {
500 exponent,
501 backtrace: capture_backtrace(),
502 }
503 .into())
504 } else {
505 let res = base.powi(exponent_func);
506 StrictFinitePolicy::<f64, 53>::validate(res)
507 .map_err(|e| Self::Error::Output { source: e })
508 }
509 })
510 }
511
512 #[inline(always)]
513 fn pow(self, exponent: exponent_type) -> Self {
515 #[cfg(debug_assertions)]
516 {
517 self.try_pow(exponent).unwrap()
518 }
519 #[cfg(not(debug_assertions))]
520 {
521 self.powi(exponent_func)
522 }
523 }
524}
525
526#[duplicate_item(
527 exponent_type exponent_func;
528 [u8] [exponent.into()];
529 [u16] [exponent.into()];
530 [u32] [exponent.try_into().unwrap()];
531 [u64] [exponent.try_into().unwrap()];
532 [u128] [exponent.try_into().unwrap()];
533 [usize] [exponent.try_into().unwrap()];
534)]
535impl Pow<exponent_type> for f64 {
536 type Error = PowIntExponentErrors<f64, exponent_type>;
537
538 fn try_pow(self, exponent: exponent_type) -> Result<Self, Self::Error> {
539 StrictFinitePolicy::<f64, 53>::validate(self)
540 .map_err(|e| PowIntExponentInputErrors::InvalidBase { source: e }.into())
541 .and_then(|base| {
542 let res = base.powi(exponent_func);
543 StrictFinitePolicy::<f64, 53>::validate(res)
544 .map_err(|e| Self::Error::Output { source: e })
545 })
546 }
547
548 #[inline(always)]
549 fn pow(self, exponent: exponent_type) -> Self {
551 #[cfg(debug_assertions)]
552 {
553 self.try_pow(exponent).unwrap()
554 }
555 #[cfg(not(debug_assertions))]
556 {
557 self.powi(exponent_func)
558 }
559 }
560}
561
562#[duplicate_item(
563 exponent_type func_name exponent_func;
564 [i8] [powi] [exponent.into()];
565 [i16] [powi] [exponent.into()];
566 [i32] [powi] [exponent];
567 [i64] [powi] [exponent.try_into().unwrap()];
568 [i128] [powi] [exponent.try_into().unwrap()];
569 [isize] [powi] [exponent.try_into().unwrap()];
570)]
571impl Pow<exponent_type> for Complex<f64> {
572 type Error = PowIntExponentErrors<Complex<f64>, exponent_type>;
573
574 #[inline(always)]
575 fn try_pow(self, exponent: exponent_type) -> Result<Self, Self::Error> {
576 StrictFinitePolicy::<Self, 53>::validate(self)
577 .map_err(|e| PowIntExponentInputErrors::InvalidBase { source: e }.into())
578 .and_then(|base| {
579 if Zero::is_zero(&base) && exponent < 0 {
580 Err(PowIntExponentInputErrors::ZeroBaseNegativeExponent {
581 exponent,
582 backtrace: capture_backtrace(),
583 }
584 .into())
585 } else {
586 StrictFinitePolicy::<Self, 53>::validate(base.func_name(exponent_func))
587 .map_err(|e| Self::Error::Output { source: e })
588 }
589 })
590 }
591
592 #[inline(always)]
593 fn pow(self, exponent: exponent_type) -> Self {
595 #[cfg(debug_assertions)]
596 {
597 self.try_pow(exponent).unwrap()
598 }
599 #[cfg(not(debug_assertions))]
600 {
601 self.func_name(exponent_func)
602 }
603 }
604}
605
606#[duplicate_item(
607 exponent_type func_name exponent_func;
608 [u8] [powu] [exponent.into()];
609 [u16] [powu] [exponent.into()];
610 [u32] [powu] [exponent];
611 [u64] [powu] [exponent.try_into().unwrap()];
612 [u128] [powu] [exponent.try_into().unwrap()];
613 [usize] [powu] [exponent.try_into().unwrap()];
614)]
615impl Pow<exponent_type> for Complex<f64> {
616 type Error = PowIntExponentErrors<Complex<f64>, exponent_type>;
617
618 #[inline(always)]
619 fn try_pow(self, exponent: exponent_type) -> Result<Self, Self::Error> {
620 StrictFinitePolicy::<Self, 53>::validate(self)
621 .map_err(|e| PowIntExponentInputErrors::InvalidBase { source: e }.into())
622 .and_then(|base| {
623 StrictFinitePolicy::<Self, 53>::validate(base.func_name(exponent_func))
624 .map_err(|e| Self::Error::Output { source: e })
625 })
626 }
627
628 #[inline(always)]
629 fn pow(self, exponent: exponent_type) -> Self {
631 #[cfg(debug_assertions)]
632 {
633 self.try_pow(exponent).unwrap()
634 }
635 #[cfg(not(debug_assertions))]
636 {
637 self.func_name(exponent_func)
638 }
639 }
640}
641pub trait PowIntExponent:
646 Pow<i8, Error = PowIntExponentErrors<Self::RawType, i8>>
647 + Pow<u8, Error = PowIntExponentErrors<Self::RawType, u8>>
648 + Pow<i16, Error = PowIntExponentErrors<Self::RawType, i16>>
649 + Pow<u16, Error = PowIntExponentErrors<Self::RawType, u16>>
650 + Pow<i32, Error = PowIntExponentErrors<Self::RawType, i32>>
651 + Pow<u32, Error = PowIntExponentErrors<Self::RawType, u32>>
652 + Pow<i64, Error = PowIntExponentErrors<Self::RawType, i64>>
653 + Pow<u64, Error = PowIntExponentErrors<Self::RawType, u64>>
654 + Pow<i128, Error = PowIntExponentErrors<Self::RawType, i128>>
655 + Pow<u128, Error = PowIntExponentErrors<Self::RawType, u128>>
656 + Pow<isize, Error = PowIntExponentErrors<Self::RawType, isize>>
657 + Pow<usize, Error = PowIntExponentErrors<Self::RawType, usize>>
658{
659 type RawType: RawScalarTrait;
660}
661
662impl PowIntExponent for f64 {
663 type RawType = f64;
664}
665
666impl PowIntExponent for Complex<f64> {
667 type RawType = Complex<f64>;
668}
669
670#[cfg(test)]
674mod tests {
675 use super::*;
676 use crate::{
677 RealScalar,
678 functions::{
679 Pow, PowIntExponentErrors, PowIntExponentInputErrors,
680 PowRealBaseRealExponentInputErrors,
681 },
682 validation::{ErrorsValidationRawComplex, ErrorsValidationRawReal},
683 };
684 use num::Complex;
685
686 #[cfg(feature = "rug")]
687 use crate::kernels::rug::{ComplexRugStrictFinite, RealRugStrictFinite};
688
689 #[cfg(feature = "rug")]
690 use try_create::TryNew;
691
692 mod pow_u32_exponent {
693 use super::*;
694
695 mod real_base {
696 use super::*;
697
698 fn pow_generic_real_u32_valid<RealType: RealScalar>() {
699 let base = RealType::try_from_f64(2.0).unwrap();
700 let exponent = 3u32;
701 let expected_result = RealType::try_from_f64(8.0).unwrap();
702 assert_eq!(Pow::pow(base.clone(), exponent), expected_result);
703 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
704 }
705
706 #[test]
707 fn test_pow_generic_real_u32_valid() {
708 pow_generic_real_u32_valid::<f64>();
709 }
710
711 #[test]
712 fn test_f64_pow_u32_valid() {
713 let base = 2.0;
714 let exponent = 3u32;
715 let expected_result = 8.0;
716 assert_eq!(Pow::pow(base, exponent), expected_result);
717 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
718 }
719
720 #[test]
721 fn test_f64_pow_u32_zero_exponent() {
722 let base = 2.0;
723 let exponent = 0u32;
724 let expected_result = 1.0;
725 assert_eq!(Pow::pow(base, exponent), expected_result);
726 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
727 }
728
729 #[test]
730 fn test_f64_pow_u32_one_exponent() {
731 let base = 2.0;
732 let exponent = 1u32;
733 let expected_result = 2.0;
734 assert_eq!(Pow::pow(base, exponent), expected_result);
735 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
736 }
737
738 #[test]
739 fn test_f64_pow_u32_zero_base() {
740 let base = 0.0;
741 let exponent = 3u32;
742 let expected_result = 0.0;
743 assert_eq!(Pow::pow(base, exponent), expected_result);
744 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
745 }
746
747 #[test]
748 fn test_f64_pow_u32_nan_base() {
749 let base = f64::NAN;
750 let exponent = 3u32;
751 let result = base.try_pow(exponent);
752 assert!(result.is_err());
753 }
754
755 #[test]
756 fn test_f64_pow_u32_infinity_base() {
757 let base = f64::INFINITY;
758 let exponent = 3u32;
759 let result = base.try_pow(exponent);
760 assert!(result.is_err());
761 }
762 }
763
764 mod complex_base {
765 use super::*;
766
767 #[test]
768 fn test_complex_f64_pow_u32_valid() {
769 let base = Complex::new(2.0, 3.0);
770 let exponent = 2u32;
771 let expected_result = Complex::new(-5.0, 12.0);
772 assert_eq!(Pow::pow(base, exponent), expected_result);
773 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
774 }
775
776 #[test]
777 fn test_complex_f64_pow_u32_zero_exponent() {
778 let base = Complex::new(2.0, 3.0);
779 let exponent = 0u32;
780 let expected_result = Complex::new(1.0, 0.0);
781 assert_eq!(Pow::pow(base, exponent), expected_result);
782 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
783 }
784
785 #[test]
786 fn test_complex_f64_pow_u32_one_exponent() {
787 let base = Complex::new(2.0, 3.0);
788 let exponent = 1u32;
789 let expected_result = Complex::new(2.0, 3.0);
790 assert_eq!(Pow::pow(base, exponent), expected_result);
791 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
792 }
793
794 #[test]
795 fn test_complex_f64_pow_u32_zero_base() {
796 let base = Complex::new(0.0, 0.0);
797 let exponent = 3u32;
798 let expected_result = Complex::new(0.0, 0.0);
799 assert_eq!(Pow::pow(base, exponent), expected_result);
800 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
801 }
802
803 #[test]
804 fn test_complex_f64_pow_u32_nan_base() {
805 let base = Complex::new(f64::NAN, 0.0);
806 let exponent = 3u32;
807 let result = base.try_pow(exponent);
808 assert!(result.is_err());
809
810 let base = Complex::new(0.0, f64::NAN);
811 let result = base.try_pow(exponent);
812 assert!(result.is_err());
813 }
814
815 #[test]
816 fn test_complex_f64_pow_u32_infinity_base() {
817 let base = Complex::new(f64::INFINITY, 0.0);
818 let exponent = 3u32;
819 let result = base.try_pow(exponent);
820 assert!(result.is_err());
821
822 let base = Complex::new(0.0, f64::INFINITY);
823 let result = base.try_pow(exponent);
824 assert!(result.is_err());
825 }
826 }
827 }
828
829 mod pow_i32_exponent {
830 use super::*;
831
832 mod native64 {
833 use super::*;
834
835 mod real_base {
836 use super::*;
837
838 #[test]
839 fn test_f64_pow_valid() {
840 let base = 2.0;
841 let exponent = 3i32;
842 let expected_result = 8.0;
843 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
844 assert_eq!(<f64 as Pow<i32>>::pow(base, exponent), expected_result);
845 }
846
847 #[test]
848 fn test_f64_pow_zero_exponent() {
849 let base = 2.0;
850 let exponent = 0i32;
851 let expected_result = 1.0;
852 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
853 }
854
855 #[test]
856 fn test_f64_pow_negative_exponent() {
857 let base = 2.0;
858 let exponent = -3i32;
859 let expected_result = 0.125;
860 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
861 }
862
863 #[test]
864 fn test_f64_pow_zero_base() {
865 let base = 0.0;
866 let exponent = 3i32;
867 let expected_result = 0.0;
868 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
869 }
870
871 #[test]
872 fn test_f64_pow_zero_base_zero_exponent() {
873 let base = 0.0;
874 let exponent = 0i32;
875 let expected_result = 1.0;
876 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
877 }
878
879 #[test]
880 fn test_f64_pow_zero_base_negative_exponent() {
881 let base = 0.0;
882 let err = base.try_pow(-1i32).unwrap_err();
883 assert!(matches!(
884 err,
885 PowIntExponentErrors::Input {
886 source: PowIntExponentInputErrors::ZeroBaseNegativeExponent {
887 exponent: -1,
888 ..
889 }
890 }
891 ));
892 }
893
894 #[test]
895 fn test_f64_pow_negative_base_positive_exponent() {
896 let base = -2.0;
897 let exponent = 3i32;
898 let expected_result = -8.0;
899 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
900 }
901
902 #[test]
903 fn test_f64_pow_negative_base_negative_exponent() {
904 let base = -2.0;
905 let exponent = -3i32;
906 let expected_result = -0.125;
907 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
908 }
909 }
910
911 mod complex_base {
912 use super::*;
913
914 #[test]
915 fn test_complex_f64_pow_valid() {
916 let base = Complex::new(2.0, 3.0);
917 let exponent = 2i32;
918 let expected_result = Complex::new(-5.0, 12.0);
919 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
920 assert_eq!(
921 <Complex<f64> as Pow<i32>>::pow(base, exponent),
922 expected_result
923 );
924 }
925
926 #[test]
927 fn test_complex_f64_pow_zero_exponent() {
928 let base = Complex::new(2.0, 3.0);
929 let exponent = 0i32;
930 let expected_result = Complex::new(1.0, 0.0);
931 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
932 }
933
934 #[test]
935 fn test_complex_f64_pow_negative_exponent() {
936 let base = Complex::new(2.0, 3.0);
937 let exponent = -2i32;
938 let expected_result = Complex::new(-0.029585798816568053, -0.07100591715976332);
939 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
940 }
941
942 #[test]
943 fn test_complex_f64_pow_zero_base() {
944 let base = Complex::new(0.0, 0.0);
945 let exponent = 3i32;
946 let expected_result = Complex::new(0.0, 0.0);
947 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
948 }
949
950 #[test]
951 fn test_complex_f64_pow_zero_base_zero_exponent() {
952 let base = Complex::new(0.0, 0.0);
953 let exponent = 0i32;
954 let expected_result = Complex::new(1.0, 0.0);
955 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
956 }
957
958 #[test]
959 fn test_complex_f64_pow_zero_base_negative_exponent() {
960 let base = Complex::new(0.0, 0.0);
961 let err = base.try_pow(-1i32).unwrap_err();
962 assert!(matches!(
963 err,
964 PowIntExponentErrors::Input {
965 source: PowIntExponentInputErrors::ZeroBaseNegativeExponent {
966 exponent: -1,
967 ..
968 }
969 }
970 ));
971 }
972
973 #[test]
974 fn test_complex_f64_pow_negative_base_positive_exponent() {
975 let base = Complex::new(-2.0, -3.0);
976 let exponent = 3i32;
977 let expected_result = Complex::new(46.0, -9.0);
978 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
979 }
980
981 #[test]
982 fn test_complex_f64_pow_negative_base_negative_exponent() {
983 let base = Complex::new(-2.0, -3.0);
984 let exponent = -3i32;
985 let expected_result = Complex::new(0.02093764223941739, 0.004096495220755574);
986 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
987 }
988 }
989 }
990
991 #[cfg(feature = "rug")]
992 mod rug53 {
993 use super::*;
994 use crate::kernels::rug::{ComplexRugStrictFinite, RealRugStrictFinite};
995 use rug::Float;
996
997 mod real {
998 use super::*;
999
1000 #[test]
1001 fn test_rug_float_pow_valid() {
1002 let base =
1003 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 2.0)).unwrap();
1004 let exponent = 3;
1005 let expected_result =
1006 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 8.0)).unwrap();
1007 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1008 }
1009
1010 #[test]
1011 fn test_rug_float_pow_zero_exponent() {
1012 let base =
1013 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 2.0)).unwrap();
1014 let exponent = 0;
1015 let expected_result =
1016 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 1.0)).unwrap();
1017 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1018 }
1019
1020 #[test]
1021 fn test_rug_float_pow_negative_exponent() {
1022 let base =
1023 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 2.0)).unwrap();
1024 let exponent = -3;
1025 let expected_result =
1026 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.125)).unwrap();
1027 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1028 }
1029
1030 #[test]
1031 fn test_rug_float_pow_zero_base() {
1032 let base =
1033 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
1034 let exponent = 3;
1035 let expected_result =
1036 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
1037 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1038 }
1039
1040 #[test]
1041 fn test_rug_float_pow_zero_base_zero_exponent() {
1042 let base =
1043 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
1044 let exponent = 0;
1045 let expected_result =
1046 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 1.0)).unwrap();
1047 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1048 }
1049
1050 #[test]
1051 fn test_rug_float_pow_negative_base_positive_exponent() {
1052 let base =
1053 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -2.0)).unwrap();
1054 let exponent = 3;
1055 let expected_result =
1056 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -8.0)).unwrap();
1057 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1058 }
1059
1060 #[test]
1061 fn test_rug_float_pow_negative_base_negative_exponent() {
1062 let base =
1063 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -2.0)).unwrap();
1064 let exponent = -3;
1065 let expected_result =
1066 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -0.125)).unwrap();
1067 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1068 }
1069 }
1070
1071 mod complex {
1072 use super::*;
1073 use rug::Complex;
1074
1075 #[test]
1076 fn test_complex_rug_float_pow_valid() {
1077 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1078 53,
1079 (Float::with_val(53, 2.0), Float::with_val(53, 3.0)),
1080 ))
1081 .unwrap();
1082 let exponent = 2;
1083 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1084 53,
1085 (Float::with_val(53, -5.0), Float::with_val(53, 12.0)),
1086 ))
1087 .unwrap();
1088 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1089 }
1090
1091 #[test]
1092 fn test_complex_rug_float_pow_zero_exponent() {
1093 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1094 53,
1095 (Float::with_val(53, 2.0), Float::with_val(53, 3.0)),
1096 ))
1097 .unwrap();
1098 let exponent = 0;
1099 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1100 53,
1101 (Float::with_val(53, 1.0), Float::with_val(53, 0.0)),
1102 ))
1103 .unwrap();
1104 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1105 }
1106
1107 #[test]
1108 fn test_complex_rug_float_pow_negative_exponent() {
1109 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1110 53,
1111 (Float::with_val(53, 2.0), Float::with_val(53, 3.0)),
1112 ))
1113 .unwrap();
1114 let exponent = -2;
1115 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1116 53,
1117 (
1118 Float::with_val(53, -2.9585798816568046e-2),
1119 Float::with_val(53, -7.100591715976332e-2),
1120 ),
1121 ))
1122 .unwrap();
1123 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1124 }
1125
1126 #[test]
1127 fn test_complex_rug_float_pow_zero_base() {
1128 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1129 53,
1130 (Float::with_val(53, 0.0), Float::with_val(53, 0.0)),
1131 ))
1132 .unwrap();
1133 let exponent = 3;
1134 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1135 53,
1136 (Float::with_val(53, 0.0), Float::with_val(53, 0.0)),
1137 ))
1138 .unwrap();
1139 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1140 }
1141
1142 #[test]
1143 fn test_complex_rug_float_pow_zero_base_zero_exponent() {
1144 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1145 53,
1146 (Float::with_val(53, 0.0), Float::with_val(53, 0.0)),
1147 ))
1148 .unwrap();
1149 let exponent = 0;
1150 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1151 53,
1152 (Float::with_val(53, 1.0), Float::with_val(53, 0.0)),
1153 ))
1154 .unwrap();
1155 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1156 }
1157
1158 #[test]
1159 fn test_complex_rug_float_pow_negative_base_positive_exponent() {
1160 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1161 53,
1162 (Float::with_val(53, -2.0), Float::with_val(53, -3.0)),
1163 ))
1164 .unwrap();
1165 let exponent = 3;
1166 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1167 53,
1168 (Float::with_val(53, 46.0), Float::with_val(53, -9.0)),
1169 ))
1170 .unwrap();
1171 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1172 }
1173
1174 #[test]
1175 fn test_complex_rug_float_pow_negative_base_negative_exponent() {
1176 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1177 53,
1178 (Float::with_val(53, -2.0), Float::with_val(53, -3.0)),
1179 ))
1180 .unwrap();
1181 let exponent = -3;
1182 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1183 53,
1184 (
1185 Float::with_val(53, 2.0937642239417388e-2),
1186 Float::with_val(53, 4.096495220755576e-3),
1187 ),
1188 ))
1189 .unwrap();
1190 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1191 }
1192 }
1193 }
1194 }
1195
1196 mod pow_real_exponent {
1197 use super::*;
1198
1199 mod native64 {
1200 use super::*;
1201
1202 mod real_base {
1203 use super::*;
1204 use core::f64;
1205
1206 #[test]
1207 fn test_f64_pow_f64_valid() {
1208 let base = 2.0;
1209 let exponent = 3.0;
1210 let expected_result = 8.0;
1211 assert_eq!(Pow::pow(base, &exponent), expected_result);
1212 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1213 }
1214
1215 #[test]
1216 fn test_f64_pow_f64_zero_exponent() {
1217 let base = 2.0;
1218 let exponent = 0.0;
1219 let expected_result = 1.0;
1220 assert_eq!(Pow::pow(base, &exponent), expected_result);
1221 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1222 }
1223
1224 #[test]
1225 fn test_f64_pow_f64_invalid_exponent() {
1226 let base = 2.0;
1227 let err = base.try_pow(&f64::NAN).unwrap_err();
1228 assert!(matches!(
1229 err,
1230 PowRealBaseRealExponentErrors::Input {
1231 source: PowRealBaseRealExponentInputErrors::InvalidExponent {
1232 source: ErrorsValidationRawReal::IsNaN { .. }
1233 }
1234 }
1235 ))
1236 }
1237
1238 #[test]
1239 fn test_f64_pow_f64_invalid_base_invalid_exponent() {
1240 let err = (f64::INFINITY).try_pow(&f64::NAN).unwrap_err();
1241 assert!(matches!(
1242 err,
1243 PowRealBaseRealExponentErrors::Input {
1244 source: PowRealBaseRealExponentInputErrors::InvalidBaseAndExponent {
1245 error_base: ErrorsValidationRawReal::IsPosInfinity { .. },
1246 error_exponent: ErrorsValidationRawReal::IsNaN { .. },
1247 ..
1248 }
1249 }
1250 ))
1251 }
1252
1253 #[test]
1254 fn test_f64_pow_f64_one_exponent() {
1255 let base = 2.0;
1256 let exponent = 1.0;
1257 let expected_result = 2.0;
1258 assert_eq!(Pow::pow(base, &exponent), expected_result);
1259 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1260 }
1261
1262 #[test]
1263 fn test_f64_pow_f64_zero_base() {
1264 let base = 0.0;
1265 let exponent = 3.0;
1266 let expected_result = 0.0;
1267 assert_eq!(Pow::pow(base, &exponent), expected_result);
1268 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1269 }
1270
1271 #[test]
1272 fn test_f64_pow_f64_nan_base() {
1273 let base = f64::NAN;
1274 let exponent = 3.0;
1275 let result = base.try_pow(&exponent);
1276 assert!(result.is_err());
1277 }
1278
1279 #[test]
1280 fn test_f64_pow_f64_infinity_base() {
1281 let base = f64::INFINITY;
1282 let exponent = 3.0;
1283 let result = base.try_pow(&exponent);
1284 assert!(matches!(
1285 result,
1286 Err(PowRealBaseRealExponentErrors::Input { .. })
1287 ));
1288 }
1289
1290 #[test]
1291 fn test_f64_pow_f64_negative_exponent() {
1292 let base = 2.0;
1293 let exponent = -2.0;
1294 let expected_result = 0.25;
1295 assert_eq!(Pow::pow(base, &exponent), expected_result);
1296 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1297 }
1298
1299 #[test]
1300 fn test_f64_pow_f64_negative_base_positive_exponent() {
1301 let base = -2.0;
1302 let exponent = 3.0;
1303 let result = base.try_pow(&exponent);
1304 assert!(matches!(
1305 result,
1306 Err(PowRealBaseRealExponentErrors::Input { .. })
1307 ));
1308 }
1309
1310 #[test]
1311 fn test_f64_pow_f64_negative_base_negative_exponent() {
1312 let base = -2.0;
1313 let exponent = -3.0;
1314 let result = base.try_pow(&exponent);
1315 assert!(result.is_err());
1316 }
1317 }
1318
1319 mod complex_base {
1320 use super::*;
1321
1322 #[test]
1323 fn test_complex_f64_pow_ok_base_ok_exponent() {
1324 let base = Complex::new(2.0, 3.0);
1325 let exponent = 2.0;
1326 let expected_result = Complex::new(-4.999999999999999, 11.999999999999998);
1327 assert_eq!(Pow::pow(base, &exponent), expected_result);
1328 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1329 }
1330
1331 #[test]
1332 fn test_complex_f64_pow_ok_base_zero_exponent() {
1333 let base = Complex::new(2.0, 3.0);
1334 let exponent = 0.0;
1335 let expected_result = Complex::new(1.0, 0.0);
1336 assert_eq!(Pow::pow(base, &exponent), expected_result);
1337 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1338 }
1339
1340 #[test]
1341 fn test_complex_f64_pow_zero_base_zero_exponent() {
1342 let base = Complex::new(0.0, 0.0);
1343 let exponent = 0.0;
1344 let expected_result = Complex::new(1.0, 0.0);
1345 assert_eq!(Pow::pow(base, &exponent), expected_result);
1346 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1347 }
1348
1349 #[test]
1350 fn test_complex_f64_pow_zero_base_negative_exponent() {
1351 let base = Complex::new(0.0, 0.0);
1352 let exponent = -1.0;
1353 let err = base.try_pow(&exponent).unwrap_err();
1354 assert!(matches!(
1355 err,
1356 PowComplexBaseRealExponentErrors::Input {
1357 source:
1358 PowComplexBaseRealExponentInputErrors::ZeroBaseNegativeExponent {
1359 exponent: -1.,
1360 ..
1361 }
1362 }
1363 ));
1364 }
1365
1366 #[test]
1367 fn test_complex_f64_pow_ok_base_nan_exponent() {
1368 let base = Complex::new(0.0, 0.0);
1369 let exponent = f64::NAN;
1370 let err = base.try_pow(&exponent).unwrap_err();
1371 assert!(matches!(
1372 err,
1373 PowComplexBaseRealExponentErrors::Input {
1374 source: PowComplexBaseRealExponentInputErrors::InvalidExponent {
1375 source: ErrorsValidationRawReal::IsNaN { .. }
1376 }
1377 }
1378 ));
1379 }
1380
1381 #[test]
1382 fn test_complex_f64_pow_infinity_base_nan_exponent() {
1383 let base = Complex::new(f64::INFINITY, 0.0);
1384 let exponent = f64::NAN;
1385 let err = base.try_pow(&exponent).unwrap_err();
1386 assert!(matches!(
1387 err,
1388 PowComplexBaseRealExponentErrors::Input {
1389 source: PowComplexBaseRealExponentInputErrors::InvalidBaseAndExponent {
1390 error_base: ErrorsValidationRawComplex::InvalidRealPart {
1391 source: ErrorsValidationRawReal::IsPosInfinity { .. }
1392 },
1393 error_exponent: ErrorsValidationRawReal::IsNaN { .. },
1394 ..
1395 }
1396 }
1397 ));
1398 }
1399
1400 #[test]
1401 fn test_complex_f64_pow_ok_base_one_exponent() {
1402 let base = Complex::new(2.0, 3.0);
1403 let exponent = 1.0;
1404 let expected_result = Complex::new(2.0, 3.0);
1405 assert_eq!(Pow::pow(base, &exponent), expected_result);
1406 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1407 }
1408
1409 #[test]
1410 fn test_complex_f64_pow_zero_base_ok_exponent() {
1411 let base = Complex::new(0.0, 0.0);
1412 let exponent = 3.0;
1413 let expected_result = Complex::new(0.0, 0.0);
1414 assert_eq!(Pow::pow(base, &exponent), expected_result);
1415 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1416 }
1417
1418 #[test]
1419 fn test_complex_f64_pow_nan_base_ok_exponent() {
1420 let base = Complex::new(f64::NAN, 0.0);
1421 let exponent = 3.0;
1422 let result = base.try_pow(&exponent);
1423 assert!(result.is_err());
1424
1425 let base = Complex::new(0.0, f64::NAN);
1426 let result = base.try_pow(&exponent);
1427 assert!(result.is_err());
1428 }
1429
1430 #[test]
1431 fn test_complex_f64_pow_infinity_base_ok_exponent() {
1432 let base = Complex::new(f64::INFINITY, 0.0);
1433 let exponent = 3.0;
1434 let result = base.try_pow(&exponent);
1435 assert!(result.is_err());
1436
1437 let base = Complex::new(0.0, f64::INFINITY);
1438 let result = base.try_pow(&exponent);
1439 assert!(result.is_err());
1440 }
1441
1442 #[test]
1443 fn test_complex_f64_pow_ok_base_negative_exponent() {
1444 let base = Complex::new(2.0, 3.0);
1445 let exponent = -2.0;
1446 let expected_result = Complex::new(-0.029585798816568046, -0.07100591715976332);
1447 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1448 }
1449
1450 #[test]
1451 fn test_complex_f64_pow_negative_base_positive_exponent() {
1452 let base = Complex::new(-2.0, -3.0);
1453 let exponent = 3.0;
1454 let expected_result = Complex::new(46.0, -8.99999999999999);
1455 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1456 }
1457
1458 #[test]
1459 fn test_complex_f64_pow_negative_base_negative_exponent() {
1460 let base = Complex::new(-2.0, -3.0);
1461 let exponent = -3.0;
1462 let expected_result = Complex::new(0.02093764223941739, 0.004096495220755572);
1463 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1464 }
1465 }
1466 }
1467
1468 #[cfg(feature = "rug")]
1469 mod rug53 {
1470 use super::*;
1471 use rug::{Complex, Float};
1472
1473 mod real_base {
1474 use super::*;
1475
1476 #[test]
1477 fn test_realrug_pow_valid() {
1478 let base =
1479 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 2.0)).unwrap();
1480 let exponent =
1481 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 3.0)).unwrap();
1482 let expected_result =
1483 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 8.0)).unwrap();
1484 assert_eq!(base.clone().pow(&exponent), expected_result);
1485 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1486 }
1487
1488 #[test]
1489 fn test_realrug_pow_zero_exponent() {
1490 let base =
1491 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 2.0)).unwrap();
1492 let exponent =
1493 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
1494 let expected_result =
1495 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 1.0)).unwrap();
1496 assert_eq!(base.clone().pow(&exponent), expected_result);
1497 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1498 }
1499
1500 #[test]
1501 fn test_realrug_pow_one_exponent() {
1502 let base =
1503 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 2.0)).unwrap();
1504 let exponent =
1505 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 1.0)).unwrap();
1506 let expected_result =
1507 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 2.0)).unwrap();
1508 assert_eq!(base.clone().pow(&exponent), expected_result);
1509 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1510 }
1511
1512 #[test]
1513 fn test_realrug_pow_zero_base() {
1514 let base =
1515 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
1516 let exponent =
1517 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 3.0)).unwrap();
1518 let expected_result =
1519 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
1520 assert_eq!(base.clone().pow(&exponent), expected_result);
1521 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1522 }
1523
1524 #[test]
1525 fn test_realrug_pow_negative_exponent() {
1526 let base =
1527 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 2.0)).unwrap();
1528 let exponent =
1529 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -2.0)).unwrap();
1530 let expected_result =
1531 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.25)).unwrap();
1532 assert_eq!(base.clone().pow(&exponent), expected_result);
1533 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1534 }
1535
1536 #[test]
1537 fn test_realrug_pow_negative_base_positive_exponent() {
1538 let base =
1539 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -2.0)).unwrap();
1540 let exponent =
1541 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 3.0)).unwrap();
1542 let result = base.try_pow(&exponent);
1543 assert!(matches!(
1544 result,
1545 Err(PowRealBaseRealExponentErrors::Input { .. })
1546 ));
1547 }
1548
1549 #[test]
1550 fn test_realrug_pow_negative_base_negative_exponent() {
1551 let base =
1552 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -2.0)).unwrap();
1553 let exponent =
1554 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -3.0)).unwrap();
1555 let result = base.try_pow(&exponent);
1556 assert!(matches!(
1557 result,
1558 Err(PowRealBaseRealExponentErrors::Input { .. })
1559 ));
1560 }
1561 }
1562
1563 mod complex_base {
1564 use super::*;
1565
1566 #[test]
1567 fn test_complex_rug_float_pow_valid() {
1568 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1569 53,
1570 (Float::with_val(53, 2.0), Float::with_val(53, 3.0)),
1571 ))
1572 .unwrap();
1573 let exponent =
1574 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 2.0)).unwrap();
1575 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1576 53,
1577 (Float::with_val(53, -5.0), Float::with_val(53, 12.0)),
1578 ))
1579 .unwrap();
1580 assert_eq!(base.clone().pow(&exponent), expected_result);
1581 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1582 }
1583
1584 #[test]
1585 fn test_complex_rug_float_pow_zero_exponent() {
1586 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1587 53,
1588 (Float::with_val(53, 2.0), Float::with_val(53, 3.0)),
1589 ))
1590 .unwrap();
1591 let exponent =
1592 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
1593 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1594 53,
1595 (Float::with_val(53, 1.0), Float::with_val(53, 0.0)),
1596 ))
1597 .unwrap();
1598 assert_eq!(base.clone().pow(&exponent), expected_result);
1599 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1600 }
1601
1602 #[test]
1603 fn test_complex_rug_float_pow_one_exponent() {
1604 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1605 53,
1606 (Float::with_val(53, 2.0), Float::with_val(53, 3.0)),
1607 ))
1608 .unwrap();
1609 let exponent =
1610 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 1.0)).unwrap();
1611 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1612 53,
1613 (Float::with_val(53, 2.0), Float::with_val(53, 3.0)),
1614 ))
1615 .unwrap();
1616 assert_eq!(base.clone().pow(&exponent), expected_result);
1617 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1618 }
1619
1620 #[test]
1621 fn test_complex_rug_float_pow_zero_base() {
1622 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1623 53,
1624 (Float::with_val(53, 0.0), Float::with_val(53, 0.0)),
1625 ))
1626 .unwrap();
1627 let exponent =
1628 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 3.0)).unwrap();
1629 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1630 53,
1631 (Float::with_val(53, 0.0), Float::with_val(53, 0.0)),
1632 ))
1633 .unwrap();
1634 assert_eq!(base.clone().pow(&exponent), expected_result);
1635 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1636 }
1637
1638 #[test]
1639 fn test_complex_rug_float_pow_negative_exponent() {
1640 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1641 53,
1642 (Float::with_val(53, 2.0), Float::with_val(53, 3.0)),
1643 ))
1644 .unwrap();
1645 let exponent =
1646 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -2.0)).unwrap();
1647 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1648 53,
1649 (
1650 Float::with_val(53, -0.029585798816568046),
1651 Float::with_val(53, -0.07100591715976332),
1652 ),
1653 ))
1654 .unwrap();
1655 assert_eq!(base.clone().pow(&exponent), expected_result);
1656 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1657 }
1658
1659 #[test]
1660 fn test_complex_rug_float_pow_negative_base_positive_exponent() {
1661 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1662 53,
1663 (Float::with_val(53, -2.0), Float::with_val(53, -3.0)),
1664 ))
1665 .unwrap();
1666 let exponent =
1667 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 3.0)).unwrap();
1668 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1669 53,
1670 (Float::with_val(53, 46.0), Float::with_val(53, -9.0)),
1671 ))
1672 .unwrap();
1673 assert_eq!(base.clone().pow(&exponent), expected_result);
1674 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1675 }
1676
1677 #[test]
1678 fn test_complex_rug_float_pow_negative_base_negative_exponent() {
1679 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1680 53,
1681 (Float::with_val(53, -2.0), Float::with_val(53, -3.0)),
1682 ))
1683 .unwrap();
1684 let exponent =
1685 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -3.0)).unwrap();
1686 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1687 53,
1688 (
1689 Float::with_val(53, 2.0937642239417388e-2),
1690 Float::with_val(53, 4.096495220755576e-3),
1691 ),
1692 ))
1693 .unwrap();
1694 assert_eq!(base.clone().pow(&exponent), expected_result);
1695 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1696 }
1697 }
1698 }
1699 }
1700}
1701