7

他の誰かが書いた、MATLAB の次のコード行があります。

c=a.'/b

それを Python に翻訳する必要があります。a、b、および c はすべて配列です。コードをテストするために現在使用しているディメンションは次のとおりです。

a: 18x1、
b: 25x18、

これにより、寸法が 1x25 の c が得られます。

配列は正方形ではありませんが、そうであればコードが失敗することは望ましくありません。この行が(数学的に)何をしているのか、そしてPythonでそれを行う方法を誰かが正確に説明できますか? (つまり、Python に存在する場合、MATLAB の組み込み関数 mrdivide と同等ですか?)

4

5 に答える 5

9

この線

c = a.' / b

cの方程式cb=aT解を計算します。Numpyには、これを直接行う演算子はありません。代わりに、 cTについてbT c T = a解き、結果を転置する必要があります

c = numpy.linalg.lstsq(b.T, a.T)[0].T
于 2009-06-17T18:41:38.080 に答える
9

シンボルは、関数/を呼び出す MATLAB の行列右除算演算子です。mrdivideドキュメントから、行列の右除算は次のように行列の左除算に関連しています。

B/A = (A'\B')'

Aが正方行列の場合、B/Aほぼ等しいB*inv(A)(ただし、別のより堅牢な方法で計算されます)。それ以外の場合x = B/Aは、過決定または過決定の方程式系 に対する最小二乗法での解x*A = Bです。連立方程式を解くために使用されるアルゴリズムの詳細については、こちらを参照してください。通常、LAPACKBLASなどのパッケージは内部で使用されます。

PythonのNumPy パッケージlstsqには、連立方程式の最小二乗解を計算するためのルーチンが含まれています。mrdivideこのルーチンにより、MATLAB で関数を使用した場合と同等の結果が得られる可能性がありますが、正確である可能性は低いです。各関数で使用される基礎となるアルゴリズムの違いにより、結果が互いにわずかに異なる可能性があります (つまり、一方が 1.0 の値を返し、もう一方が 0.999 の値を返す場合があります)。このエラーの相対的なサイズは、解く方程式の特定のシステムに大きく依存して、最終的に大きくなる可能性があります。

を使用するlstsqには、問題を少し調整する必要がある場合があります。cB = aの形式の方程式を解きたいようです。ここで、Bは 25 行 18 列、aは 1 行 18 列、cは 1 行 25 列です。両辺に転置を適用すると、式B T c T = a Tが得られます。これは、より標準的な形式です (つまり、Ax = b )。への引数lstsqは、(この順序で) B T (18 行 25 列の配列) およびT ( 18 要素の配列) でなければなりません。25 要素の配列 ( c Tlstsq )を返す必要があります。

注: NumPy は 1 行 N 列または N 行 1 列の配列を区別しませんが、MATLAB は確実に違います。適切な配列を使用しないと怒鳴られます。

于 2009-06-16T14:07:57.420 に答える
5

Matlab ではA.'、A 行列を転置することを意味します。数学的には、コードで達成されるのは A T /B です。


Python (または任意の言語) で行列除算を実装する方法 (注: フォームの単純な除算について説明します。この例では、最初に A Tを実行し、次に A TA/B /Bを実行する必要があります。これは非常に簡単です。 Python で転置操作を行う |left-as-an-exercise :)|)

行列方程式 C*B=A があります (C を A/B として見つけたい)

右除算 (/) は次のとおりです。

C *(B *B T )=A *B T

次に、反転して C を分離します (B *B T )

つまり、

C = A *B T* (B *B T )' ----- [1]

したがって、Python (または任意の言語) で行列除算を実装するには、次の 3 つの方法を取得します。

  • 行列の乗算
  • 行列転置
  • 逆行列

[1] のように除算を行うためにそれらを繰り返し適用します。

A T /Bのみを実行する必要があるため、3 つの基本的な方法を実装した後の最終的な操作は次のようになります。

A T* B T* (B *B T )'

注: 演算子の優先順位の基本ルールを忘れないでください :)

于 2009-06-16T14:07:05.643 に答える
1

[編集済み] Suvesh が指摘したように、以前は完全に間違っていました。ただし、numpy は、彼の投稿で示した手順を簡単に実行できます。

A = numpy.matrix(numpy.random.random((18, 1))) # as noted by others, your dimensions are off
B = numpy.matrix(numpy.random.random((25, 18)))
C = A.T * B.T * (B * B.T).I
于 2009-06-16T14:34:35.387 に答える