2016-11-06 4 views
2

私は、4つの射影点のクロスレシオを計算するために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, 0, 1, -1のクロスレシオは、-1である必要があります。

また、2つの数値の比率で表される点を扱いたいと思います。 (1,0)Infinityを表すことになりつつ(1 1)ことなど

、数1だろう、私はいつものケースバックの定義に落ち、それで間に合わせるが、私は、これは良いデザインを学ぶ良い機会かもしれ感じることができました。

私はPython 2.7とSagemathモジュールを使用しています。これを実装する方法に関するアドバイスはありますか?

答えて

1

私はこれを試してみた:

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)]) 

これは、入力に同次座標を使用しますので、あなたは、2要素ベクトルをINOUTと思います。また、その結果を2要素のベクトルとして同次座標で返します。したがって、無限の交差比をきれいに記述することができます。あなたの代わりに、いくつかのフィールドの要素として結果が必要な場合は、だけではなく、ベクトルコンストラクタの分割を使用します。

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

個人的に私は、多くの場合、4つの同一線上の点の複比を必要とするので、私は私の式に接尾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との任意のポイントない同一線上ましょう、あなたはこれら4点の複比を得ます。または、より一般的には、a,b,c,dが同一線上にない場合は、これらを接続する4本の線のクロスレシオをxに設定します。これは多くのシナリオで有用です。

1

最高ののは、射影ラインで作業することです。ここ

ドキュメントは役に立つヒントが含まれています。ここでは 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)