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:
complex
data type as well as numpy.complex
. How can this be done elegantly, without code duplication?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.
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.
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.
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 .
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).
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.
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.
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!
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 :
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With