Given any n x n matrix of real coefficients A, we can define a bilinear form bA : Rn x Rn → R by
bA(x, y) = xTAy ,
and a quadratic form qA : Rn → R by
qA(x) = bA(x, x) = xTAx .
(For most common applications of quadratic forms qA, the matrix A is symmetric, or even symmetric positive definite, so feel free to assume that either one of these is the case, if it matters for your answer.)
(Also, FWIW, bI and qI (where I is the n x n identity matrix) are, respectively, the standard inner product, and squared L2-norm on Rn, i.e. xTy and xTx.)
Now suppose I have two n x m matrices, X and Y, and an n x n matrix A. I would like to optimize the computation of both bA(x,i, y,i) and qA(x,i) (where x,i and y,i denote the i-th column of X and Y, respectively), and I surmise that, at least in some environments like numpy, R, or Matlab, this will involve some form of vectorization.
The only solution I can think of requires generating diagonal block matrices [X], [Y] and [A], with dimensions mn x m, mn x m, and mn x mn, respectively, and with (block) diagonal elements x,i, y,i, and A, respectively. Then the desired computations would be the matrix multiplications [X]T[A][Y] and [X]T[A][X]. This strategy is most definitely uninspired, but if there is a way to do it that is efficient in terms of both time and space, I'd like to see it. (It goes without saying that any implementation of it that does not exploit the sparsity of these block matrices would be doomed.)
Is there a better approach?
My preference of system for doing this is numpy, but answers in terms of some other system that supports efficient matrix computations, such as R or Matlab, may be OK too (assuming that I can figure out how to port them to numpy).
Thanks!
Of course, computing the products XTAY and XTAX would compute the desired bA(x,i, y,i) and qA(x,i) (as the diagonal elements of the resulting m x m matrices), along with the O(m2) irrelevant bA(x,i, y,j) and bA(x,i, x,j), (for i ≠ j), so this is a non-starter.
A bilinear form B such that B(v, w) = 0 ⇐⇒ B(w, v) = 0 for all v, w ∈ V is called reflexive. Given a reflexive bilinear form and a subset S of V , we may write ⊥L(S) = ⊥R(S) = S⊥. If W is a subspace of V then we call W⊥ the orthogonal complement of W.
A large class of examples of bilinear forms arise as follows: if V = Fn, then for any matrix A ∈ Mn×n(F), the map ΦA(v, w) = vT Aw is a bilinear form on V . x1x2 + 2x1y2 + 3x2y1 + 4y1y2 . on V , the associated matrix of Φ with respect to β is the matrix [Φ]β ∈ Mn×n(F) whose (i, j)-entry is the value Φ(βi,βj).
A bilinear form B is said to be symmetric if B(v, w) = B(w, v) for all v, w ∈ V , and it is said to be positive definite if B(v, v) ≥ 0 for all v ∈ V , with equality if and only if v = 0. It is important to see what bilinear forms look like in terms of a basis. Let B be a bilinear form.
For every quadratic form f, there exists a unique symmetric bilinear form b such that f(x) = b(x, x) for every x ∈ V. whenever b is a symmetric bilinear form b satisfying f(x) = b(x, x) for every x ∈ V.
Here's a solution in numpy that should give you what you're looking for:
((np.matrix(X).T*np.matrix(A)).A * Y.T.A).sum(1)
This does matrix multiplication for XT * A, then does element-by-element array multiplication to multiply by YT. The rows of the resulting array are then summed to yield a 1-D array.
It's not entirely clear what you're trying to achieve, but in R, you use crossprod
to form cross-products: given matrices X
and Y
with compatible dimensions, crossprod(X, Y)
returns XTY. Similarly, matrix multiplication is achieved with the %*%
operator: X %*% Y
returns the product XY. So you can get XTAY as crossprod(X, A %*% Y)
without having to worry about the mechanics of matrix multiplication, loops, or whatever.
If your matrices have a particular structure that allows optimising the computations (symmetric, triangular, sparse, banded, ...), you could look at the Matrix
package, which has some support for this.
I haven't used Matlab, but I'm sure it would have similar functions for these operations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With