TensorFlow: Efficient way to compute reduce-sum block-matrix multiplications - numpy

I have the following equation:
Where M is a [Dx3] matrix and V is a [DxD] matrix. Each of these forms a [3x3] block in a larger [3Kx3K] matrix, indexed by i, j. For now, I'm wondering if anyone has come across doing a reduce-sum of this form in TensorFlow - I'm still getting used to the API structure!

Related

Calculating covariance of a 3-dim matrix using einsum

I've got an array of time series data of shape (2466, 2498, 9) ((asset, date, feature)).
I've got 9 features, on which I want to do PCA to reduce the dimensionality on this axis.
I'm struggling to calculate the covariance matrix, Z = X.T # X.
I think I want to express this as an einsum, but I'm not sure how. I'm certainly interested in other methods as well, as the purpose of this is to learn numpy, rather than actually solve a problem.
Edit: This is my (apparently wrong) attempt so far:
np.einsum('ijk,ijl->ijkl',myData, myData)`
(This just hangs my system.)
Edit 2:
I've come to understand that I should be using np.linalg.svd for this problem.

Implementation of Isotropic squared exponential kernel with numpy

I've come across a from scratch implementation for gaussian processes:
http://krasserm.github.io/2018/03/19/gaussian-processes/
There, the isotropic squared exponential kernel is implemented in numpy. It looks like:
The implementation is:
def kernel(X1, X2, l=1.0, sigma_f=1.0):
sqdist = np.sum(X1**2, 1).reshape(-1, 1) + np.sum(X2**2, 1) - 2 * np.dot(X1, X2.T)
return sigma_f**2 * np.exp(-0.5 / l**2 * sqdist)
consistent with the implementation of Nando de Freitas: https://www.cs.ubc.ca/~nando/540-2013/lectures/gp.py
However, I am not quite sure how this implementation matches the provided formula, especially in the sqdist part. In my opinion, it is wrong but it works (and delivers the same results as scipy's cdist with squared euclidean distance). Why do I think it is wrong? If you multiply out the multiplication of the two matrices, you get
which equals to either a scalar or a nxn matrix for a vector x_i, depending on whether you define x_i to be a column vector or not. The implementation however gives back a nx1 vector with the squared values.
I hope that anyone can shed light on this.
I found out: The implementation is correct. I just was not aware of the fuzzy notation (in my opinion) which is sometimes used in ML contexts. What is to be achieved is a distance matrix and each row vectors of matrix A are to be compared with the row vectors of matrix B to infer the covariance matrix, not (as I somehow guessed) the direct distance between two matrices/vectors.

sparse matrix multiplication involving inverted matrix

I have two large square sparse matrices, A & B, and need to compute the following: A * B^-1 in the most efficient way. I have a feeling that the answer involves using scipy.sparse, but can't for the life of me figure it out.
After extensive searching, I have run across the following thread: Efficient numpy / lapack routine for product of inverse and sparse matrix? but can't figure out what the most efficient way would be.
Someone suggested using LU decomposition which is built into the sparse module of scipy, but when I try and do LU on sample matrix is says the result is singular (although when I just do a * B^-1 i get an answer). I have also heard someone suggest using linalg.spsolve(), but i can't figure out how to implement this as it requires a vector as the second argument.
If it helps, once I have the solution s.t. A * B^-1 = C, i only need to know the value for one row of the matrix C. The matrices will be roughly 1000x1000 to 1500x1500.
Actually 1000x1000 matrices are not that large. You can compute the inverse of such a matrix using numpy.linalg.inv(B) in less than 1 second on a modern desktop computer.
But you can be much more efficient if you rewrite your problem taking into account the fact that you only need one row of C (this is actually very often the case).
Let us write d_i = [0 0 0 ... 0 1 0 ... 0 ], a vector with only one one on the i-th element.
You can write, if ^t denotes the transpose :
AB^-1 = C <=> A = CB <=> A^t = B^t C^t
For the i-th row :
A^t d_i = B^t C^t d_i <=> a_i = B^t c_i
So you have a linear inverse problem which can be solved using numpy.linalg.solve
ci = np.linalg.solve(B.T, a[i])

Check how fast numpy.linalg.lstsq is finding convergence

I have a question concerning NumPy module linalg.lstsq(a,b). There is any possibility to check how fast this method is finding convergence? I mean some of characteristics which indicate how fast computation is going to convergence?
Thank you in advanced for brain storm.
The Numpy function linalg.lstsq uses singular value decomposition (SVD) to solve the least-square problem. Thus, if your matrix A is n by n, it will require n^3 flops.
More precisely, I think that the function uses the Householder Bidiagonalization to compute the SVD and so, if your matrix is m by n, the complexity will be O(max(m, n) * min(m, n)^2).

Can I do eigenfaces with 32bit and numpy?

I am currently trying to implement eigenfaces with numpy, but it seems to struggle with my 32bit Linux system (I use 32bit because of the formerly bad support for flash and java in 64bit, my processor is 64bit…), because when trying to multiply two vectors to get a matrix (vector * transposed vector) numpy gives me
ValueError: broadcast dimensions too large.
I read that this is due to too little memory and could be solved with 64bit. Is there some way to circumvent this? The matrix would be 528000*528000 elements. According to my paper this big matrix is needed for the covariance matrix (suming up all these huge matrices and then dividing it by the number of matrices).
My piece of code looks like this (I do not understand why numpy gives me a matrix anyway, because for my matrix knowledge it looks the wrong way round (horizontal*vertical), but it worked with examples of smaller size):
tmp = []
for face in faces: # just an array of all face vectors (len = 528000)
diff = np.subtract(averageFace, face)
diff = np.asmatrix(diff)
tmp.append(np.multiply(diff, np.transpose(diff)))
C = np.divide(np.sum(tmp, axis=0), len(tmp))
As pv already elaborated, it's not really practically feasible to try to produce such huge covariance matrix.
But please note that eigenvectors (explained in your drexel link) of phi* phi^T and phi^T* phi are related and this is the key to make the problem more manageable. See more on this topic in Eigenface.