1

正方行列をピボットして LU 分解するコードを見つけたのですが、理解できないものがあります。

def pivotize(m):
    """Creates the pivoting matrix for m."""
    n = len(m)
    ID = [[float(i == j) for i in xrange(n)] for j in xrange(n)]
    for j in xrange(n):
        row = max(xrange(j, n), key=lambda i: abs(m[i][j]))
        if j != row:
            ID[j], ID[row] = ID[row], ID[j]
    return ID

まず、ID の行は単なる恒等行列ではないでしょうか。これを行う利点はありますか?

第二に、行の行がよくわかりません。ラムダはテキスト内の関数を定義するために使用され、i の値が提供されると M_ij の値を返すだけであることは知っています (j の値は for ループに依存します)。しかし、i とは何ですか?

xrange は range に似ていませんか? しかし、それはここで何を返しますか?

関数 max と組み合わせるとどうなるでしょうか。比較されている max 関数内のものが何であるかはわかりません。

この質問が愚かに聞こえる場合は申し訳ありません。私はプログラミングにかなり慣れていません

4

2 に答える 2

2

xrangerangeメモリを効率的に処理するために使用される Python2 コンストラクトです。range実際にリストを作成する前に、forループが実行されます。xrangeただし、ジェネレーターです。つまり、完全なリストを作成せずに、要求されたときに一度に 1 つの値を吐き出します。

IDは実際には恒等行列です。あなたはそこにいます。これは、 boolean を float の value に変換できる巧妙なトリックです1.0

次に、スニペットは残りのすべての行を実行し、元のマトリックスでその行の最大値を見つけますrow = max(xrange(j, n), key=lambda i: abs(m[i][j]))。そこには 2 番目の優れたトリックがあり、maxジェネレーターを含む反復可能なオブジェクトを操作できることに注意してください。lambdaその行のキーワードは、「無名関数」として知られているものを示しています。

詳細: 匿名関数は、識別子にバインドされていない関数です。スニペットの Lambda 関数は 1 つの値を取り、iマトリックスの位置で絶対値を返しますm[i][j]。関数の入力として送信される値は、ジェネレータによって提供されxrange(j, n)ます。

max次に、実際に比較するものとしてラムダ関数の戻り値を取ります。たとえば、python3 では 2 つの異なる型を比較す​​ることはできません。つまり、string > int を比較すると、次のようになりTypeError: unorderable types: str() > int()ます。ただし、リストに数値が含まれていることが確実な場合は、形式が異なるだけで、次のようにすることができます。

>>> l = ["1", "2", 3, 4]
>>> max(l, key=lambda x: int(x))
4
>>> min(l, key=lambda x: int(x))
'1' #type 'str'

これは、実際に比較された値がkey関数の戻り値であることを示していますが、実際に生成された値は元の入力値です。

行の最大値が見つかると、最大値のみが対角線上に残るように、単位行列内ID[j], ID[row] = ID[row], ID[j]の他のすべての行を代入によって「回転」します。

これにより、LU 分解の次のステップで小さすぎる数による除算を防ぐことができます。

見返りに得られるのは、回転された元の行列ではありませんが、元の行列を乗算した変換行列である1.0s とs の行列は、ピボットされた行列になります。0.0

これは、メモリを節約し、Python でのパフォーマンスを向上させる、非常に適切に記述された関数のようです。うまくいけば、私はこれを正しく行いました。

于 2015-03-05T00:08:07.643 に答える