I am trying to implement a calculation for the Schur Complement of a symmetric matrix. The equation for this value is:
M = A - B^T C B
Where A, B, C are block components of the matrix
S = (A | B^T)
(B | C )
Suppose I have defined numpy arrays for A, B and C:
- A is a 3x3 Matrix
- B is a 3x2 Matrix
- C is a 2x2 matrix
I have performed the operation to obtain S using numpy:
M = A - np.matmul(B.T, np.matmul(C, B))
Assuming this is the correct operation, is there a more pythonic way to write this code?
Kind regards!
Edit:
Were I using Python 3.5+, then the @ solution suggested would be ideal.
The reason for my question is that, if one was doing a complex set of matrix multiplications, using nested np.matmult() or np.dot() becomes very difficult to read without defining new variables in each step.
For example, for the equation M = A^-1 - C^TXC
becomes
np.linalg.inv(A) - np.dot(C.T, np.dot(X,C))
or
np.linalg.inv(A) - np.matmult(C.T, np.matmult(X,C))
The nesting makes it harder to check the operator order is correct, since:
np.linalg.inv(A) - np.matmult(C.T, np.matmult(X,C)) != np.linalg.inv(A) - np.matmult(C.T, np.matmult(C,X))
(in most cases)
By contrast:
np.linalg.inv(A) - C.T @ X @ C
Clearly allows the reader to know what is going on in this line of code and to check the operator order.