mathhook_core/algebra/complex/
operations.rs1use crate::core::Expression;
7use crate::expr;
8use crate::simplify::Simplify;
9
10pub trait ComplexOperations {
15 fn complex_add(&self, other: &Expression) -> Expression;
27
28 fn complex_subtract(&self, other: &Expression) -> Expression;
40
41 fn complex_multiply(&self, other: &Expression) -> Expression;
53
54 fn complex_divide(&self, other: &Expression) -> Expression;
66
67 fn complex_conjugate(&self) -> Expression;
78
79 fn complex_modulus(&self) -> Expression;
90
91 fn complex_argument(&self) -> Expression;
102
103 fn to_polar_form(&self) -> (Expression, Expression);
114
115 fn is_real(&self) -> bool;
126
127 fn is_imaginary(&self) -> bool;
138
139 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.clone(),
251 Expression::pow(denominator.clone(), expr!(-1)),
252 ])
253 .simplify(),
254 Expression::mul(vec![
255 num_data.imag.clone(),
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.clone(),
293 Expression::pow(denominator.clone(), expr!(-1)),
294 ])
295 .simplify(),
296 Expression::mul(vec![
297 num_data.imag.clone(),
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}