6

大きなスパース行列を反転する必要があります。行列の反転から逃れることはできません。唯一の近道は、主対角要素のアイデアを取得し、非対角要素を無視することです(私はむしろそうではありませんが、解決策としては受け入れられます)。

反転する必要のある行列は通常大きく(40000 * 40000)、ゼロ以外の対角線はほんの一握りです。私の現在のアプローチは、すべてをスパースに構築してから、

posterior_covar = np.linalg.inv ( hessian.todense() )

これには明らかに長い時間と十分なメモリが必要です。

ヒントはありますか、それとも忍耐力の問題か、問題を小さくするだけですか?

4

1 に答える 1

8

スパースモジュールには明示的な逆メソッドがあるとは思いませんが、スパースソルバーはあります。このおもちゃの例のようなものが機能します:

>>> a = np.random.rand(3, 3)
>>> a
array([[ 0.31837307,  0.11282832,  0.70878689],
       [ 0.32481098,  0.94713997,  0.5034967 ],
       [ 0.391264  ,  0.58149983,  0.34353628]])
>>> np.linalg.inv(a)
array([[-0.29964242, -3.43275347,  5.64936743],
       [-0.78524966,  1.54400931, -0.64281108],
       [ 1.67045482,  1.29614174, -2.43525829]])

>>> a_sps = scipy.sparse.csc_matrix(a)
>>> lu_obj = scipy.sparse.linalg.splu(a_sps)
>>> lu_obj.solve(np.eye(3))
array([[-0.29964242, -0.78524966,  1.67045482],
       [-3.43275347,  1.54400931,  1.29614174],
       [ 5.64936743, -0.64281108, -2.43525829]])

結果が入れ替わっていることに注意してください!

逆行列もスパースであると予想され、最後のソルブからの密な戻り値がメモリに収まらない場合は、一度に1行(列)を生成し、ゼロ以外の値を抽出して、スパースを構築することもできます。それらからの逆行列:

>>> for k in xrange(3) :
...     b = np.zeros((3,))
...     b[k] = 1
...     print lu_obj.solve(b)
... 
[-0.29964242 -0.78524966  1.67045482]
[-3.43275347  1.54400931  1.29614174]
[ 5.64936743 -0.64281108 -2.43525829]
于 2013-02-27T17:54:30.640 に答える