【发布时间】:2017-07-26 09:59:59
【问题描述】:
我正在寻找一种有效的方法来使用 python 确定两个浮点数的最大公约数。该例程应具有以下布局
gcd(a, b, rtol=1e-05, atol=1e-08)
"""
Returns the greatest common divisor of a and b
Parameters
----------
a,b : float
two floats for gcd
rtol, atol : float, optional
relative and absolute tolerance
Returns
-------
gcd : float
Greatest common divisor such that for x in [a,b]:
np.mod(x,gcd) < rtol*x + atol
.. _PEP 484:
https://www.python.org/dev/peps/pep-0484/
"""
例子:有理数和无理数的gcd
gcd(1., np.pi, rtol=0, atol=1e-5) 应该返回(大致)1e-5,因为
In [1]: np.mod(np.pi,1e-5)
Out[1]: 2.6535897928590063e-06
In [2]: np.mod(1.,1e-5)
Out[2]: 9.9999999999181978e-06
我更喜欢使用库实现,而不是自己编写。 fractions.gcd 函数在这里似乎不适合我,因为我不想使用分数,而且它(显然)没有公差参数。
【问题讨论】:
-
你能准确定义浮点数的最大公约数是什么意思吗?一对整数的 GCD 是众所周知且易于理解的事情。该定义很容易扩展到有理数,因此将浮点数视为有理数给出了对浮点数有效的 GCD 定义。但是鉴于您在这里包含宽容,我怀疑这就是您所追求的。一些示例可能会有所帮助。
-
比如1和pi的gcd是多少?
-
可能你必须自己实现它。你可以在 scipy/numpy 邮件列表中询问这个 SO 问题,我猜你可以在那里取得更大的成功。
-
我不确定这是否可以以一种漂亮的方式完成。多分辨率网格搜索可能是您的朋友。提供的示例:根据您的首选定义,gcd(1., np.pi, rtol=0, atol=1e-5) 大约不是 1e-5,因为大约 1e-4 已经击败了您。例如尝试 0.00010006。而且我很确定我可以找到一个适合您需要的更大的,如果我可以自己写整个网格搜索
-
请注意,
fractions.gcd无论如何都是纯 python 实现。如果您对atol有一个很好的定义,那么将其合并到您自己的版本中应该很简单