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