NumPy 1.8 gufuncs, , . np.linalg.pinv gufunc-ed, np.linalg.svd , - , . , gupinv :
def gu_pinv(a, rcond=1e-15):
a = np.asarray(a)
swap = np.arange(a.ndim)
swap[[-2, -1]] = swap[[-1, -2]]
u, s, v = np.linalg.svd(a)
cutoff = np.maximum.reduce(s, axis=-1, keepdims=True) * rcond
mask = s > cutoff
s[mask] = 1. / s[mask]
s[~mask] = 0
return np.einsum('...uv,...vw->...uw',
np.transpose(v, swap) * s[..., None, :],
np.transpose(u, swap))
, :
a = np.random.rand(50, 40, 30, 6)
b = np.empty(a.shape[:-1] + (3, 3), dtype=a.dtype)
b[..., 0, :] = a[..., :3]
b[..., 1:, 0] = a[..., 1:3]
b[..., 1, 1:] = a[..., 3:5]
b[..., 2, 1:] = a[..., 4:]
b[1, 2, 3, 2] = b[1, 2, 3, 0] + b[1, 2, 3, 1]
pi = gu_pinv(b)
, , , , :
>>> np.allclose(pi[0, 0, 0], np.linalg.pinv(b[0, 0, 0]))
True
>>> np.allclose(pi[1, 2, 3], np.linalg.pinv(b[1, 2, 3]))
True
50 * 40 * 30 = 60,000 -:
In [2]: %timeit pi = gu_pinv(b)
1 loops, best of 3: 422 ms per loop
, (4x) , np.linalg.inv, , , :
In [8]: %timeit np.linalg.inv(b)
10 loops, best of 3: 98.8 ms per loop