在Python中实现复数比较?
我知道,通常不能定义复数的比较运算符。这就是为什么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
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