2017-06-09 11 views
3

私はPythonプロジェクトに取り組んでnumpyを利用しています。私はしばしば行列のクロネッカー積を恒等行列で計算しなければなりません。これらは私のコードでかなり大きなボトルネックですので、それらを最適化したいと思います。私が取るべき製品は2種類あります。最初のものは次のとおりです。効率的なKroneckerプロダクト、単位行列と規則的な行列 - NumPy/Python

np.kron(np.eye(N), A) 

この1つは、単純にscipy.linalg.block_diagを使用して最適化することが非常に簡単です。この製品は、次のものと同等です。

la.block_diag(*[A]*N) 

これは約10倍高速です。しかし、私は2番目の種類の製品を最適化する方法については不明です:

np.kron(A, np.eye(N)) 

同様のトリックを使用できますか?

答えて

2

出力配列4Dを初期化し、Aから値を割り当てます。そのような割り当ては値をブロードキャストし、これがNumPyで効率を得る場所です。

関数として入れ
# Get shape of A 
m,n = A.shape 

# Initialize output array as 4D 
out = np.zeros((m,N,n,N)) 

# Get range array for indexing into the second and fourth axes 
r = np.arange(N) 

# Index into the second and fourth axes and selecting all elements along 
# the rest to assign values from A. The values are broadcasted. 
out[:,r,:,r] = A 

# Finally reshape back to 2D 
out.shape = (m*N,n*N) 

- -

従って、溶液がそうようになる単に第一および第二及び3と同様のために沿って操作を入れ替える、np.kron(np.eye(N), A)をシミュレートするために

def kron_A_N(A, N): # Simulates np.kron(A, np.eye(N)) 
    m,n = A.shape 
    out = np.zeros((m,N,n,N),dtype=A.dtype) 
    r = np.arange(N) 
    out[:,r,:,r] = A 
    out.shape = (m*N,n*N) 
    return out 

と第4軸 -

def kron_N_A(A, N): # Simulates np.kron(np.eye(N), A) 
    m,n = A.shape 
    out = np.zeros((N,m,N,n),dtype=A.dtype) 
    r = np.arange(N) 
    out[r,:,r,:] = A 
    out.shape = (m*N,n*N) 
    return out 

タイミング -

In [174]: N = 100 
    ...: A = np.random.rand(100,100) 
    ...: 

In [175]: np.allclose(np.kron(A, np.eye(N)), kron_A_N(A,N)) 
Out[175]: True 

In [176]: %timeit np.kron(A, np.eye(N)) 
1 loops, best of 3: 458 ms per loop 

In [177]: %timeit kron_A_N(A, N) 
10 loops, best of 3: 58.4 ms per loop 

In [178]: 458/58.4 
Out[178]: 7.842465753424658 
+1

ああ、ありがとう!参考までに、テストでは6〜7倍のスピードアップが得られます。 – user3930598

+0

@ user3930598お役立ち情報鉱山を追加しました。そこにも同様に見えます。 – Divakar

関連する問題