내부 점 방식을 사용하여 대형 스파 스 비선형 시스템을 해결하는 코드를 최적화하려고합니다. 업데이트 단계에서 헤 시안 행렬 H
, 그래디언트 g
을 계산 한 다음 d
을 H * d = -g
으로 풀어 새로운 검색 방향을 얻습니다.A.T * diag (b) * A + C 형태의 희소 행렬을 만드는 가장 빠른 방법은?
헤 시안 매트릭스 형태의 대칭 삼중 대각 구조를 갖는다 : * DIAG (B) * (A)에서
을 + C
I는 상기 특정 기능에 line_profiler
을 실행 한 질문 :
Line # Hits Time Per Hit % Time Line Contents
==================================================
386 def _direction(n, res, M, Hsig, scale_var, grad_lnprior, z, fac):
387
388 # gradient
389 44 1241715 28220.8 3.7 g = 2 * scale_var * res - grad_lnprior + z * np.dot(M.T, 1./n)
390
391 # hessian
392 44 3103117 70525.4 9.3 N = sparse.diags(1./n ** 2, 0, format=FMT, dtype=DTYPE)
393 44 18814307 427597.9 56.2 H = - Hsig - z * np.dot(M.T, np.dot(N, M)) # slow!
394
395 # update direction
396 44 10329556 234762.6 30.8 d, fac = my_solver(H, -g, fac)
397
398 44 111 2.5 0.0 return d, fac
출력을 보면 H
은 훨씬 비용이 많이 드는 단계입니다. 실제로는 새로운 방향을 위해 실제로 해결하는 것보다 훨씬 오래 걸립니다.
Hsig
및 M
모두 CSC 스파 스 매트릭스이며, n
는 밀도 벡터이며 z
는 스칼라이다. 사용하고있는 해답은 H
이 CSC 또는 CSR 스파 스 매트릭스가되어야합니다. 여기
def original(Hsig, M, n, z):
N = sparse.diags(1./n ** 2, 0, format='csc')
H = - Hsig - z * np.dot(M.T, np.dot(N, M)) # slow!
return H
타이밍 : 여기
import numpy as np
from scipy import sparse
def make_toy_data(nt=200000, nc=10):
d0 = np.random.randn(nc * (nt - 1))
d1 = np.random.randn(nc * (nt - 1))
M = sparse.diags((d0, d1), (0, nc), shape=(nc * (nt - 1), nc * nt),
format='csc', dtype=np.float64)
d0 = np.random.randn(nc * nt)
Hsig = sparse.diags(d0, 0, shape=(nc * nt, nc * nt), format='csc',
dtype=np.float64)
n = np.random.randn(nc * (nt - 1))
z = np.random.randn()
return Hsig, M, n, z
그리고 H
을 구성하는 내 원래의 접근 방법이있다 :
%timeit original(Hsig, M, n, z)
# 1 loops, best of 3: 483 ms per loop
빠른 방법이 있습니까 이 행렬?
내 NumPy는 'np.dot (M.T, np.dot (N, M))'을 허용하지 않습니다. 그것은 당신의 기계에서 확실히 작동합니까? 'N.dot (M) '하고 싶니? – YXD
@MrE 아마도 버전 문제라고 생각됩니다. - numpy.dot()는 8 개월 전 [이 커밋] (https://github.com/scipy/scipy/pull/2732)의 스파 스 매트릭스에 대해 재정의됩니다. –
당신은 단지'Hsig - z * M.T * (N * M)'이라는'점 '을 필요로하지 않지만, 그것이 더 빠르다는 것을 모른다. – HYRY