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