mathhook_core/algebra/complex/
operations.rs

1//! ComplexOperations trait for complex arithmetic operations
2//!
3//! Provides trait methods for performing arithmetic operations on complex numbers
4//! represented as expressions with symbolic real and imaginary parts.
5
6use crate::core::Expression;
7use crate::expr;
8use crate::simplify::Simplify;
9
10/// Trait for complex number operations
11///
12/// Provides methods for performing arithmetic and other operations on complex numbers
13/// represented as expressions with symbolic real and imaginary parts.
14pub trait ComplexOperations {
15    /// Add two complex expressions
16    ///
17    /// # Examples
18    ///
19    /// ```rust
20    /// use mathhook_core::{Expression, ComplexOperations, expr};
21    ///
22    /// let z1 = Expression::complex(expr!(3), expr!(4));
23    /// let z2 = Expression::complex(expr!(1), expr!(2));
24    /// let result = z1.complex_add(&z2);
25    /// ```
26    fn complex_add(&self, other: &Expression) -> Expression;
27
28    /// Subtract two complex expressions
29    ///
30    /// # Examples
31    ///
32    /// ```rust
33    /// use mathhook_core::{Expression, ComplexOperations, expr};
34    ///
35    /// let z1 = Expression::complex(expr!(5), expr!(3));
36    /// let z2 = Expression::complex(expr!(2), expr!(1));
37    /// let result = z1.complex_subtract(&z2);
38    /// ```
39    fn complex_subtract(&self, other: &Expression) -> Expression;
40
41    /// Multiply two complex expressions
42    ///
43    /// # Examples
44    ///
45    /// ```rust
46    /// use mathhook_core::{Expression, ComplexOperations, expr};
47    ///
48    /// let z1 = Expression::complex(expr!(3), expr!(4));
49    /// let z2 = Expression::complex(expr!(1), expr!(2));
50    /// let result = z1.complex_multiply(&z2);
51    /// ```
52    fn complex_multiply(&self, other: &Expression) -> Expression;
53
54    /// Divide two complex expressions
55    ///
56    /// # Examples
57    ///
58    /// ```rust
59    /// use mathhook_core::{Expression, ComplexOperations, expr};
60    ///
61    /// let z1 = Expression::complex(expr!(6), expr!(8));
62    /// let z2 = Expression::complex(expr!(3), expr!(4));
63    /// let result = z1.complex_divide(&z2);
64    /// ```
65    fn complex_divide(&self, other: &Expression) -> Expression;
66
67    /// Get the complex conjugate
68    ///
69    /// # Examples
70    ///
71    /// ```rust
72    /// use mathhook_core::{Expression, ComplexOperations, expr};
73    ///
74    /// let z = Expression::complex(expr!(3), expr!(4));
75    /// let conjugate = z.complex_conjugate();
76    /// ```
77    fn complex_conjugate(&self) -> Expression;
78
79    /// Get the modulus (absolute value)
80    ///
81    /// # Examples
82    ///
83    /// ```rust
84    /// use mathhook_core::{Expression, ComplexOperations, expr};
85    ///
86    /// let z = Expression::complex(expr!(3), expr!(4));
87    /// let modulus = z.complex_modulus();
88    /// ```
89    fn complex_modulus(&self) -> Expression;
90
91    /// Get the argument (angle in radians)
92    ///
93    /// # Examples
94    ///
95    /// ```rust
96    /// use mathhook_core::{Expression, ComplexOperations, expr};
97    ///
98    /// let z = Expression::complex(expr!(1), expr!(1));
99    /// let argument = z.complex_argument();
100    /// ```
101    fn complex_argument(&self) -> Expression;
102
103    /// Convert to polar form (magnitude, angle)
104    ///
105    /// # Examples
106    ///
107    /// ```rust
108    /// use mathhook_core::{Expression, ComplexOperations, expr};
109    ///
110    /// let z = Expression::complex(expr!(3), expr!(4));
111    /// let (magnitude, angle) = z.to_polar_form();
112    /// ```
113    fn to_polar_form(&self) -> (Expression, Expression);
114
115    /// Check if the expression is real
116    ///
117    /// # Examples
118    ///
119    /// ```rust
120    /// use mathhook_core::{Expression, ComplexOperations, expr};
121    ///
122    /// let z = Expression::complex(expr!(5), expr!(0));
123    /// assert!(z.is_real());
124    /// ```
125    fn is_real(&self) -> bool;
126
127    /// Check if the expression has an imaginary component
128    ///
129    /// # Examples
130    ///
131    /// ```rust
132    /// use mathhook_core::{Expression, ComplexOperations, expr};
133    ///
134    /// let z = Expression::complex(expr!(3), expr!(4));
135    /// assert!(z.is_imaginary());
136    /// ```
137    fn is_imaginary(&self) -> bool;
138
139    /// Check if the expression is pure imaginary
140    ///
141    /// # Examples
142    ///
143    /// ```rust
144    /// use mathhook_core::{Expression, ComplexOperations, expr};
145    ///
146    /// let z = Expression::complex(expr!(0), expr!(5));
147    /// assert!(z.is_pure_imaginary());
148    /// ```
149    fn is_pure_imaginary(&self) -> bool;
150}
151
152impl ComplexOperations for Expression {
153    fn complex_add(&self, other: &Expression) -> Expression {
154        match (self, other) {
155            (Expression::Complex(a), Expression::Complex(b)) => Expression::complex(
156                Expression::add(vec![a.real.clone(), b.real.clone()]).simplify(),
157                Expression::add(vec![a.imag.clone(), b.imag.clone()]).simplify(),
158            ),
159            _ => Expression::function("undefined", vec![]),
160        }
161    }
162
163    fn complex_subtract(&self, other: &Expression) -> Expression {
164        match (self, other) {
165            (Expression::Complex(a), Expression::Complex(b)) => Expression::complex(
166                Expression::add(vec![
167                    a.real.clone(),
168                    Expression::mul(vec![expr!(-1), b.real.clone()]),
169                ])
170                .simplify(),
171                Expression::add(vec![
172                    a.imag.clone(),
173                    Expression::mul(vec![expr!(-1), b.imag.clone()]),
174                ])
175                .simplify(),
176            ),
177
178            (Expression::Complex(a), real_expr) => Expression::complex(
179                Expression::add(vec![
180                    a.real.clone(),
181                    Expression::mul(vec![expr!(-1), real_expr.clone()]),
182                ])
183                .simplify(),
184                a.imag.clone(),
185            ),
186
187            (real_expr, Expression::Complex(b)) => Expression::complex(
188                Expression::add(vec![
189                    real_expr.clone(),
190                    Expression::mul(vec![expr!(-1), b.real.clone()]),
191                ])
192                .simplify(),
193                Expression::mul(vec![expr!(-1), b.imag.clone()]).simplify(),
194            ),
195
196            _ => Expression::add(vec![
197                self.clone(),
198                Expression::mul(vec![expr!(-1), other.clone()]),
199            ]),
200        }
201    }
202
203    fn complex_multiply(&self, other: &Expression) -> Expression {
204        match (self, other) {
205            (Expression::Complex(a), Expression::Complex(b)) => {
206                let ac = Expression::mul(vec![a.real.clone(), b.real.clone()]).simplify();
207                let bd = Expression::mul(vec![a.imag.clone(), b.imag.clone()]).simplify();
208                let ad = Expression::mul(vec![a.real.clone(), b.imag.clone()]).simplify();
209                let bc = Expression::mul(vec![a.imag.clone(), b.real.clone()]).simplify();
210
211                Expression::complex(
212                    Expression::add(vec![ac, Expression::mul(vec![expr!(-1), bd]).simplify()])
213                        .simplify(),
214                    Expression::add(vec![ad, bc]).simplify(),
215                )
216            }
217
218            (Expression::Complex(a), real_expr) => Expression::complex(
219                Expression::mul(vec![a.real.clone(), real_expr.clone()]).simplify(),
220                Expression::mul(vec![a.imag.clone(), real_expr.clone()]).simplify(),
221            ),
222
223            (real_expr, Expression::Complex(b)) => Expression::complex(
224                Expression::mul(vec![real_expr.clone(), b.real.clone()]).simplify(),
225                Expression::mul(vec![real_expr.clone(), b.imag.clone()]).simplify(),
226            ),
227
228            _ => Expression::mul(vec![self.clone(), other.clone()]),
229        }
230    }
231
232    fn complex_divide(&self, other: &Expression) -> Expression {
233        match (self, other) {
234            (Expression::Complex(_a), Expression::Complex(b)) => {
235                let conjugate = Expression::complex(
236                    b.real.clone(),
237                    Expression::mul(vec![expr!(-1), b.imag.clone()]),
238                );
239
240                let numerator = self.complex_multiply(&conjugate);
241                let denominator = Expression::add(vec![
242                    Expression::pow(b.real.clone(), expr!(2)),
243                    Expression::pow(b.imag.clone(), expr!(2)),
244                ])
245                .simplify();
246
247                match numerator {
248                    Expression::Complex(num_data) => Expression::complex(
249                        Expression::mul(vec![
250                            num_data.real,
251                            Expression::pow(denominator.clone(), expr!(-1)),
252                        ])
253                        .simplify(),
254                        Expression::mul(vec![
255                            num_data.imag,
256                            Expression::pow(denominator, expr!(-1)),
257                        ])
258                        .simplify(),
259                    ),
260                    _ => Expression::mul(vec![numerator, Expression::pow(denominator, expr!(-1))]),
261                }
262            }
263
264            (Expression::Complex(a), real_expr) => Expression::complex(
265                Expression::mul(vec![
266                    a.real.clone(),
267                    Expression::pow(real_expr.clone(), expr!(-1)),
268                ])
269                .simplify(),
270                Expression::mul(vec![
271                    a.imag.clone(),
272                    Expression::pow(real_expr.clone(), expr!(-1)),
273                ])
274                .simplify(),
275            ),
276
277            (real_expr, Expression::Complex(b)) => {
278                let conjugate = Expression::complex(
279                    b.real.clone(),
280                    Expression::mul(vec![expr!(-1), b.imag.clone()]),
281                );
282                let numerator = real_expr.complex_multiply(&conjugate);
283                let denominator = Expression::add(vec![
284                    Expression::pow(b.real.clone(), expr!(2)),
285                    Expression::pow(b.imag.clone(), expr!(2)),
286                ])
287                .simplify();
288
289                match numerator {
290                    Expression::Complex(num_data) => Expression::complex(
291                        Expression::mul(vec![
292                            num_data.real,
293                            Expression::pow(denominator.clone(), expr!(-1)),
294                        ])
295                        .simplify(),
296                        Expression::mul(vec![
297                            num_data.imag,
298                            Expression::pow(denominator, expr!(-1)),
299                        ])
300                        .simplify(),
301                    ),
302                    _ => Expression::mul(vec![numerator, Expression::pow(denominator, expr!(-1))]),
303                }
304            }
305
306            _ => Expression::mul(vec![
307                self.clone(),
308                Expression::pow(other.clone(), expr!(-1)),
309            ]),
310        }
311    }
312
313    fn complex_conjugate(&self) -> Expression {
314        match self {
315            Expression::Complex(data) => Expression::complex(
316                data.real.clone(),
317                Expression::mul(vec![expr!(-1), data.imag.clone()]).simplify(),
318            ),
319            _ => self.clone(),
320        }
321    }
322
323    fn complex_modulus(&self) -> Expression {
324        match self {
325            Expression::Complex(data) => Expression::function(
326                "sqrt",
327                vec![Expression::add(vec![
328                    Expression::pow(data.real.clone(), expr!(2)),
329                    Expression::pow(data.imag.clone(), expr!(2)),
330                ])
331                .simplify()],
332            ),
333            _ => Expression::function("abs", vec![self.clone()]),
334        }
335    }
336
337    fn complex_argument(&self) -> Expression {
338        match self {
339            Expression::Complex(data) => {
340                Expression::function("atan2", vec![data.imag.clone(), data.real.clone()])
341            }
342            _ => expr!(0),
343        }
344    }
345
346    fn to_polar_form(&self) -> (Expression, Expression) {
347        (self.complex_modulus(), self.complex_argument())
348    }
349
350    fn is_real(&self) -> bool {
351        match self {
352            Expression::Complex(data) => data.imag.is_zero(),
353            _ => true,
354        }
355    }
356
357    fn is_imaginary(&self) -> bool {
358        match self {
359            Expression::Complex(data) => !data.imag.is_zero(),
360            _ => false,
361        }
362    }
363
364    fn is_pure_imaginary(&self) -> bool {
365        match self {
366            Expression::Complex(data) => data.real.is_zero() && !data.imag.is_zero(),
367            _ => false,
368        }
369    }
370}