deep_causality_num/complex/complex_number/
ops.rs1use crate::{Complex, DivisionAlgebra, One, RealField, Zero};
6
7impl<T: RealField> Complex<T> {
8 #[inline]
10 pub fn norm(&self) -> T {
11 self.norm_sqr().sqrt()
12 }
13
14 #[inline]
16 pub fn arg(&self) -> T {
17 self.im.atan2(self.re)
18 }
19
20 #[inline]
22 pub fn powi(&self, n: i32) -> Self {
23 if n == 0 {
24 return Self::one();
25 }
26 let mut res = Self::one();
27 let mut base = *self;
28 let mut n_abs = n.abs();
29
30 while n_abs > 0 {
31 if n_abs % 2 == 1 {
32 res *= base;
33 }
34 base = base * base;
35 n_abs /= 2;
36 }
37
38 if n < 0 { res._inverse_impl() } else { res }
39 }
40
41 #[inline]
43 pub fn powf(&self, n: T) -> Self {
44 let r_pow_n = self.norm().powf(n);
46 let n_theta = self.arg() * n;
47 Self::new(r_pow_n * n_theta.cos(), r_pow_n * n_theta.sin())
48 }
49
50 #[inline]
52 pub fn powc(&self, n: Self) -> Self {
53 (n * self.ln()).exp()
55 }
56
57 #[inline]
59 pub fn sqrt(self) -> Self {
60 if self.is_zero() {
61 return Self::zero();
62 }
63 let norm = self.norm();
64 let half = T::one() / (T::one() + T::one());
65 let re_sqrt = ((norm + self.re) * half).sqrt();
66 let im_sqrt = ((norm - self.re) * half).sqrt();
67
68 if self.im >= T::zero() {
69 Self::new(re_sqrt, im_sqrt)
70 } else {
71 Self::new(re_sqrt, -im_sqrt)
72 }
73 }
74
75 #[inline]
77 pub fn exp(self) -> Self {
78 let exp_re = self.re.exp();
80 Self::new(exp_re * self.im.cos(), exp_re * self.im.sin())
81 }
82
83 #[inline]
85 pub fn ln(self) -> Self {
86 Self::new(self.norm().ln(), self.arg())
88 }
89
90 #[inline]
92 pub fn sin(self) -> Self {
93 Self::new(
94 self.re.sin() * self.im.cosh(),
95 self.re.cos() * self.im.sinh(),
96 )
97 }
98
99 #[inline]
101 pub fn cos(self) -> Self {
102 Self::new(
103 self.re.cos() * self.im.cosh(),
104 -self.re.sin() * self.im.sinh(),
105 )
106 }
107
108 #[inline]
110 pub fn tan(self) -> Self {
111 self.sin() / self.cos()
112 }
113
114 #[inline]
116 pub fn sinh(self) -> Self {
117 Self::new(
118 self.re.sinh() * self.im.cos(),
119 self.re.cosh() * self.im.sin(),
120 )
121 }
122
123 #[inline]
125 pub fn cosh(self) -> Self {
126 Self::new(
127 self.re.cosh() * self.im.cos(),
128 self.re.sinh() * self.im.sin(),
129 )
130 }
131
132 #[inline]
134 pub fn tanh(self) -> Self {
135 self.sinh() / self.cosh()
136 }
137}