Reputation: 2426
I have a large numpy array, arr
, of shape (N, D, M, D)
where D
is either two or three. The array can be thought of as a block of (D,D)
matrices blocked together in the N
and M
dimensions. I wish to take the determinant of each of these (D,D)
matrices:
out = np.empty((N,M))
for i in xrange(N):
for j in xrange(M):
out[i,j] = np.linalg.det(arr[i,:,j,:])
The only problem is that np.linalg.det
does not special-case small matrices and so does a complete BLAS call and LU factorization for each block. Indeed, for a 2 by 2 matrix np.linalg.det
takes ~40us on my recent Core i7 system. What are my options for improving the performance of this fragment?
Upvotes: 1
Views: 1280
Reputation: 151017
To clarify duffymo's point, you can easily exploit the block structure with your own function, using vectorized numpy
operations. Whether this gives you a speedup may depend on how large M and N are:
>>> a = numpy.arange(2 * 2 * 2 * 2).reshape(2, 2, 2, 2)
>>> a[:,0,:,0] * a[:,1,:,1] - a[:,1,:,0] * a[:,0,:,1]
array([[-4, -4],
[-4, -4]])
>>> a = numpy.arange(2 * 3 * 2 * 3).reshape(2, 3, 2, 3)
>>> a[:,0,:,0] * a[:,1,:,1] * a[:,2,:,2] + \
a[:,0,:,1] * a[:,1,:,2] * a[:,2,:,0] + \
a[:,0,:,2] * a[:,1,:,0] * a[:,2,:,1] - \
a[:,0,:,0] * a[:,1,:,2] * a[:,2,:,1] - \
a[:,0,:,1] * a[:,1,:,0] * a[:,2,:,2] - \
a[:,0,:,2] * a[:,1,:,1] * a[:,2,:,0]
array([[0, 0],
[0, 0]])
Upvotes: 3
Reputation: 308823
You don't need LU decomposition to calculate the determinant of 2x2 or 3x3 matricies. The formulas are well known. Why not write your own functions and call them?
Upvotes: 1