在Python中实现复数比较?

在Python中实现复数比较?,python,numpy,complex-numbers,Python,Numpy,Complex Numbers,我知道,通常不能定义复数的比较运算符。这就是为什么python在尝试使用现成的复杂比较时抛出TypeError异常的原因。我理解为什么会这样(请不要离题去解释为什么两个复数不能比较) 这就是说,在这个特殊的例子中,我想根据它们的大小实现复数比较。换句话说,对于z1和z2复数值,则z1>z2当且仅当abs(z1)>abs(z2),其中abs()实现复数量级,如numpy.abs() 我提出了一个解决方案(至少我认为我有),如下所示: 将numpy导入为np 类CustomComplex(compl

我知道,通常不能定义复数的比较运算符。这就是为什么python在尝试使用现成的复杂比较时抛出
TypeError
异常的原因。我理解为什么会这样(请不要离题去解释为什么两个复数不能比较)

这就是说,在这个特殊的例子中,我想根据它们的大小实现复数比较。换句话说,对于
z1
z2
复数值,则
z1>z2
当且仅当
abs(z1)>abs(z2)
,其中
abs()
实现复数量级,如
numpy.abs()

我提出了一个解决方案(至少我认为我有),如下所示:

将numpy导入为np
类CustomComplex(complex):
定义(自身、其他):
返回np.abs(自身)=np.abs(其他)
复杂=自定义复杂
这似乎有效,但我有几个问题:

  • 这是一条路还是有更好的选择
  • 我希望我的包能够透明地处理内置的
    complex
    数据类型以及
    numpy.complex
    。如何在不重复代码的情况下优雅地完成这项工作

  • 我担心我会偏离主题(是的,我完全阅读了你的帖子:-)。好的,Python确实允许您尝试以这种方式比较复数,因为您可以单独定义所有运算符,即使我强烈建议您不要像您那样重新定义
    \uuuuueq\uuuuu
    :您正在说
    1==-1


    我想问题就在那里,并且会在某一时刻出现在你面前(或者任何使用你的软件包的人面前):当使用等式和不等式时,普通人(以及大多数python代码)会做一些简单的假设,比如
    -1!=根据您的要求,我将放弃这可能是一个坏主意的所有理由

    这是一条路还是有更好的选择

    当普通的
    abs
    接受复数且速度更快时,无需使用numpy。如果您想减少代码(但这可能会更慢),在
    functools
    中还有一个方便的
    total_排序
    ,它可以很好地用于这种简单的比较:


    您还覆盖了相等运算符。我假设这是您想要的行为?有趣的问题,我没有一个知情的答案,但加上1。我也认为这是合理的。尽管同意@Eikenberg的观点,您不需要定义
    \uuuuuuuueq\uuuuuu>和
    \uune\uuuuuu
    ,但这实际上取决于您想做什么。如果您想做的话如果你需要做数字运算,我只会在比较之前使用
    np.abs
    (在复杂数组的情况下).有些人会告诉你,你只需要明确地定义
    \uu lt\uuu
    \uuuu eq\uuuu
    ——所有其他的都可以用这两个词来定义……注意,从数学的角度看,你定义的不是顺序关系,而只是一个前序。这种关系是自反的(a+1。当您注意到Python的包含是基于相等测试时,问题只会变得更糟。因此,如果复数比较以这种方式工作,那么[3+4j]
    中的
    5将给出
    True
    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)
    
    from functools import total_ordering
    @total_ordering
    class CustomComplex(complex):
        def __eq__(self, other):
            return abs(self) == abs(other)
        def __lt__(self, other):
            return abs(self) < abs(other)
    
    >>> CustomComplex(1+7j) < 2+8j
    True
    
    >>> timeit.timeit('abs(7+6j)')
    0.10257387161254883
    >>> timeit.timeit('np.abs(7+6j)', 'import numpy as np')
    1.6638610363006592