私は、線形システムを解くためのさまざまな方法のランタイムを比較しています。私は奇妙なパターンを見つけました。私がテストしているソリューションの方法は、la.solve()
,la.inv()
、la.lu_factor_solve()
です。なぜscipy.linalgのメソッドは9x9行列で遅く実行されますか?
import scipy.linalg as la
import numpy as np
from time import time
from matplotlib import pyplot as plt
N = 20 # up to NxN matrix
T = 100 # run T times
inv_time, solve_time = [[] for _ in range(20)], [[] for _ in range(20)]
lu_factor_solve, lu_just_solve = [[] for _ in range(20)], [[] for _ in range(20)]
for _ in range(T):
for n in range(1, N + 1):
A = np.random.rand(n, n)
b = np.random.rand(n, 1)
np.dot(la.inv(A), b) # the first time through is always slow,
la.solve(A, b) # so we run it once to get it out of the way
start = time()
np.dot(la.inv(A), b)
end = time()
inv_time[n - 1].append(end - start)
start = time()
la.solve(A, b)
end = time()
solve_time[n - 1].append(end - start)
start = time()
la.lu_solve(la.lu_factor(A), b)
end = time()
lu_factor_solve[n - 1].append(end - start)
temp = la.lu_factor(A)
start = time()
la.lu_solve(temp, b)
end = time()
lu_just_solve[n - 1].append(end - start)
inv_time = np.mean(np.array(inv_time), axis=1)
solve_time = np.mean(np.array(solve_time), axis=1)
lu_factor_solve = np.mean(np.array(lu_factor_solve), axis=1)
lu_just_solve = np.mean(np.array(lu_just_solve), axis=1)
# do some plots
plt.plot(range(1, N + 1), inv_time, '-o', label='by inverse')
plt.plot(range(1, N + 1), solve_time, '-o', label='by la.solve()')
plt.plot(range(1, N + 1), lu_factor_solve, '-o', label='by lu factor solve')
plt.yscale('log')
plt.plot(range(1, N + 1), lu_just_solve, '-o', label='just la.lu_solve()')
plt.legend()
plt.show()
はこれらがランダム行列A
と1から20までn
の値に対してA = np.random.rand(n, n)
とb = np.random.rand(n, 1)
によって生成列ベクトルb
上で実行されている私は、プログラムを実行するたびに、それは9x9の行列に解を求めることを、私を見つけました以下に示すように、他のサイズの行列よりもはるかに低速です。赤い線は、la.lu_solve()
の実行に必要な時間を示しています。ここでT = 1
と結果のグラフである:
これは、このサイズのためのいくつかの最適化ができない、9x9の行列について固有の何かをしなければならないんマトリックス、または別の何か?
:
コードは、プロットを再現します。だから、あるn + 1がいくつかのn(n = 2^x)よりずっとゆっくりと解決されるいくつかのケースがあります。しかし、これは単なる直感であり、分析は容易ではないかもしれません。 – sascha
そしてそれはより奇妙になる:それは私がそれを実行するたびに起こるが、私が100回それを実行して平均値を得ると、n = 9でバンプさえもない非常に正規化されたグラフが得られる。 –
この場合は、ベンチマークが難しい(気になるキャッシュ)ので、おそらくいくつかのコードを表示する必要があります。 – sascha