在Python中实现复数比较?

jor*_*geh 8 python numpy complex-numbers

我知道一般情况下无法定义具有复数的比较运算符.这就是为什么python TypeError在尝试使用开箱即用的复杂比较时抛出异常的原因.我明白为什么会这样(请不要试图解释为什么两个复数不能比较).

也就是说,在这种特殊情况下,我想根据它们的大小来实现复数比较.换句话说,对于z1z2复杂值,则z1 > z2当且仅假设abs(z1) > abs(z2),其中abs()实现了复数幅值,如在numpy.abs().

我想出了一个解决方案(至少我认为我有)如下:

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
Run Code Online (Sandbox Code Playgroud)

这似乎有效,但我有几个问题:

  1. 这是要走的路还是有更好的选择?
  2. 我希望我的包透明地使用内置complex数据类型以及numpy.complex.如何在没有代码重复的情况下优雅地完成这项工作?

Ser*_*sta 5

我担心我会偏离主题(是的,我完全阅读你的帖子:-)).好吧,巨蟒也让你尝试这种方式比较复杂的数字,因为你可以单独定义所有的运营商,即使我强烈建议你重新定义__eq__像你这样:你1 == -1!

恕我直言,这个问题就在那里,并且会在某个时刻(或者在任何使用你的软件包的人面前)涌现:当使用平等和不等式时,普通凡人(以及大多数python代码)会做出简单的假设,例如-1 != 1,(a <= b) && (b <= a)暗示a == b.出于纯粹的数学原因,你根本无法同时将这两个假设归为真.

另一个经典假设a <= b是等同于-b <= -a.但与你预订a <= b相当于-a <= -b!

话虽这么说,我会试着回答你的两个问题:

  • 1:恕我直言,这是一种有害的方式(如上所述),但我没有更好的选择......
  • 2:我认为mixin可能是一种限制代码重复的优雅方式

代码示例(基于您自己的代码,但未经过广泛测试):

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)
Run Code Online (Sandbox Code Playgroud)