Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing complex number comparison in Python?

I know that comparison operators with complex numbers can't be defined in general. That is why python throws a TypeError exception when trying to use out-of-the-box complex comparison. I understand why this is the case (please don't go off topic trying to explain why two complex numbers can't be compared).

That said, in this particular case I would like to implement complex number comparison based on their magnitudes. In other words, for z1 and z2 complex values, then z1 > z2 if-and-only-if abs(z1) > abs(z2), where abs() implements complex number magnitude, as in numpy.abs().

I have come up with a solution (at least I think I have) as follows:

import numpy as np

class CustomComplex(complex):
    def __lt__(self, other):
        return np.abs(self) < np.abs(other)
    def __le__(self, other):
        return np.abs(self) <= np.abs(other)
    def __eq__(self, other):
        return np.abs(self) == np.abs(other)
    def __ne__(self, other):
        return np.abs(self) != np.abs(other)
    def __gt__(self, other):
        return np.abs(self) > np.abs(other)
    def __ge__(self, other):
        return np.abs(self) >= np.abs(other)

complex = CustomComplex

This seems to work, but I have a few questions:

  1. Is this the way to go or is there a better alternative?
  2. I would like my package to transparently work with the built-in complex data type as well as numpy.complex. How can this be done elegantly, without code duplication?
like image 862
jorgeh Avatar asked Jun 20 '14 19:06

jorgeh


People also ask

How do you compare two complex numbers in Python?

If you want to do such comparisons on normal complex numbers, you must define and use your own comparison functions instead of the normal operators. Or just use abs(a) < abs(b) which is clear and not terribly verbose.

How do you implement complex numbers in Python?

Python complex number can be created either using direct assignment statement or by using complex () function. Complex numbers which are mostly used where we are using two real numbers.

How do you compare complex numbers?

Among any two integers or real numbers one is larger, another smaller. But you can't compare two complex numbers. (a + ib) < (c + id), provided either a < c or a = c and b < d.

How do you implement complex numbers?

To add two complex numbers , add the real part to the real part and the imaginary part to the imaginary part. To subtract two complex numbers, subtract the real part from the real part and the imaginary part from the imaginary part. To multiply two complex numbers, use the FOIL method and combine like terms .

Is there a comparison operator for complex numbers in Python?

I know that comparison operators with complex numbers can't be defined in general. That is why python throws a TypeError exception when trying to use out-of-the-box complex comparison. I understand why this is the case (please don't go off topic trying to explain why two complex numbers can't be compared).

What is a complex number in Python?

For instance, an electric circuit which is defined by voltage (V) and current (C) are used in geometry, scientific calculations and calculus. From above results, we can see python complex numbers are of type complex. Each complex number consist of one real part and one imaginary part.

How do you create a complex class in Python?

We can explore that concept by utilizing built-in mathematical operations to create our own complex class in Python. To start off, we need to initialize our complex number: As we've stated previously, complex numbers are created from a real and an imaginary number.

How do I compare two complex numbers with each other?

If you want to do such comparisons on normal complex numbers, you must define and use your own comparison functions instead of the normal operators. Or just use abs (a) < abs (b) which is clear and not terribly verbose. Thanks for contributing an answer to Stack Overflow!


1 Answers

I'm afraid I'm going to be off topic (yes I fully read your post :-) ). Ok, Python do allow you to try to compare complex numbers that way because you can define separately all operators even if I strongly advice you not to redefine __eq__ like you did : you are saying 1 == -1 !

IMHO the problem lies there and will spring at your face at one moment (or at the face of anyone who would use your package) : when using equalities and inequalities, ordinary mortals (and most python code) do simple assumptions like -1 != 1, and (a <= b) && (b <= a) implies a == b. And you simply cannot have those 2 assumptions be true at the same time for pure mathematical reasons.

Another classic assumption is a <= b is equivalent to -b <= -a. But with you pre-order a <= b is equivalent to -a <= -b !

That being said, I'll try to answer to your 2 questions :

  • 1: IMHO it is a harmfull way (as dicussed above), but I have no better alternative ...
  • 2: I think a mixin could be an elegant way to limit code duplication

Code example (based on your own code, but not extensively tested):

import numpy as np

class ComplexOrder(Object):
    def __lt__(self, other):
        return np.absolute(self) < np.absolute(other)
    # ... keep want you want (including or not eq and ne)
    def __ge__(self, other):
        return np.absolute(self) >= np.absolute(other)

class OrderedComplex(ComplexOrder, complex):
    def __init__(self, real, imag = 0):
        complex.__init__(self, real, imag)

class NPOrderedComplex64(ComplexOrder, np.complex64):
    def __init__(self, real = 0):
        np.complex64.__init__(self, real)
like image 102
Serge Ballesta Avatar answered Sep 23 '22 21:09

Serge Ballesta