计算交比

Computing the cross ratio

我想在python中写一个函数来计算四个投影点的交叉比,我想知道是否有一个优雅简洁的实现来处理无限的情况。

交叉比率的简单实现如下所示:

ratio = lambda a,b,c: (a-c)/(b-c)
cross_ratio = lambda a,b,c,d: ratio(a,b,c)/ratio(a,b,d)

但是当其中一个输入是 Infinity 时,这会失败。这不应该发生,而是我们希望无穷大 "cancel out each other" 并给我们一个简单的比率。

例如Infinity, 0, 1, -1的交叉比应该是-1.

此外,我想处理以两个数字的比率表示的点数。因此 (1 1) 将是数字 1,而 (1,0) 将代表 Infinity,等等

我总是可以退回到案例定义并凑合使用,但我觉得这可能是一个学习好的设计的好机会。

我正在使用 Python 2.7 和 Sagemath 模块。关于如何实施这个的任何建议?

我会试试这个:

def det2(a, b): return a[0]*b[1] - a[1]*b[0]
def cr2(a, b, c, d): return vector([det2(a,c)*det2(b,d), det2(a,d)*det2(b,c)])

这将在输入上使用齐次坐标,因此您将输入二元向量。它还会 return 它的结果是齐次坐标,作为二元向量,因此您可以获得无限交叉比的清晰描述。如果您需要将结果作为某个字段的元素,只需使用除法而不是向量构造函数:

def cr2(a, b, c, d): return (det2(a,c)*det2(b,d))/(det2(a,d)*det2(b,c))

我在公式中加了后缀2,因为我个人经常需要平面共线的四个点的交比。在那种情况下,我会使用

def det3(a, b, c):
  return matrix([a,b,c]).det() # Or spell this out, if you prefer
def cr3(a, b, c, d, x):
  return vector([det3(a,c,x)*det3(b,d,x), det3(a,d,x)* det3(b,c,x)])

现在让 xa,b,c,d 共线的任何点,您就可以得到这四个点的交比。或者更一般地说,如果 a,b,c,d 不共线,您将得到连接它们与 x 的四条线的交叉比,这对许多场景很有用,其中许多场景涉及二次曲线。

最好是使用投影线。

此处的文档包含有用的提示: http://doc.sagemath.org/html/en/reference/schemes/sage/schemes/projective/projective_space.html

这是交叉比率的实现,并附有示例。

sage: P = ProjectiveSpace(1, QQ)
sage: oo, zero, one = P(1, 0), P(0, 1), P(1, 1)
sage: tm = P.point_transformation_matrix
sage: def cross_ratio(a, b, c, d):
....:     a, b, c, d = P(a), P(b), P(c), P(d)
....:     m = tm([a, b, c], [oo, zero, one])
....:     return P(list(m*vector(list(d))))
....: 
sage: cross_ratio(oo, zero, one, 1/2)
(1/2 : 1)
sage: cross_ratio(1, 2, 3, 4)
(4/3 : 1)