If I have two matrices a and b, is there any function I can find the matrix x, that when dot multiplied by a makes b? Looking for python solutions, for matrices in the form of numpy arrays.
This problem of finding X such as A*X=B is equivalent to search the "inverse of A", i.e. a matrix such as X = Ainverse * B.
For information, in math Ainverse is noted A^(-1) ("A to the power -1", but you can say "A inverse" instead).
In numpy, this is a builtin function to find the inverse of a matrix a:
import numpy as np
ainv = np.linalg.inv(a)
see for instance this tutorial for explanations.
You need to be aware that some matrices are not "invertible", most obvious examples (roughly) are:
matrix that are not square
matrix that represent a projection
numpy can still approximate some value in certain cases.
if A is a full rank, square matrix
import numpy as np
from numpy.linalg import inv
X = inv(A) # B
if not, then such a matrix does not exist, but we can approximate it
import numpy as np
from numpy.linalg import inv
X = inv(A.T # A) # A.T # B
Related
I am confused sometimes when I want to get an analytical expression in terms of certain variables. In the following case, one is a Numpy array (T) and the other is a Sympy matrix (X). I know it is not a good idea to directly multiply them, so I decide to convert T to a Sympy matrix. However, it takes ages to get the result for this large-sized matrix. Are there any more efficient ways? Thank you.
import numpy as np
import sympy as sp
T = np.random.rand(100, 5000)
x = sp.symbols('x:'+str(5000))
X = sp.Matrix(x)
W = sp.Matrix(T)
V = W * X
There are potentially more efficient ways to do this. One possibility if you want a "compiled" version of SymPy is to use SymEngine which is more limited in scope than SymPy but can do what you seem to be asking for faster than SymPy (It's basically a reimplementation of certain parts of SymPy in C++):
import numpy as np
import symengine as sp # <<-- changed import
T = np.random.rand(100, 5000)
x = sp.symbols('x:'+str(5000))
X = sp.Matrix(x)
W = sp.Matrix(T.tolist()) # Need tolist() here
V = W * X
This still takes a while but it is faster than SymPy. In any case though there is almost certainly a better way of approaching your actual problem than computing the illustrated matrix product. The matrix V here is really just an inefficient representation of the original numpy array T. I expect that whatever it is that you want to do with V could be done more directly with T.
I am trying to implement the QR decomposition via householder reflectors. While attempting this on a very simple array, I am getting weird numbers. Anyone who can tell me, also, why using the # vs * operator between vec and vec.T on the last line of the function definition gets major bonus points.
This has stumped two math/comp sci phds as of this morning.
import numpy as np
def householder(vec):
vec[0] += np.sign(vec[0])*np.linalg.norm(vec)
vec = vec/vec[0]
gamma = 2/(np.linalg.norm(vec)**2)
return np.identity(len(vec)) - gamma*(vec*vec.T)
array = np.array([1, 3 ,4])
Q = householder(array)
print(Q#array)
Output:
array([-4.06557377, -7.06557377, -6.06557377])
Where it should be:
array([5.09, 0, 0])
* is elementwise multiplication, # is matrix multiplication. Both have their uses, but for matrix calculations you most likely want the matrix product.
vec.T for an array returns the same array. A simple array only has one dimension, there is nothing to transpose. vec*vec.T just returns the elementwise squared array.
You might want to use vec=vec.reshape(-1,1) to get a proper column vector, a one-column matrix. Then vec*vec.T does "by accident" the correct thing. You might want to put the matrix multiplication operator there anyway.
I wonder if there's a function in numpy/scipy for 1d array circular convolution. The scipy.signal.convolve() function only provides "mode" but not "boundary", while the signal.convolve2d() function needs 2d array as input.
I need to do this to compare open vs circular convolution as part of a time series homework.
By convolution theorem, you can use Fourier Transform to get circular convolution.
import numpy as np
def conv_circ( signal, ker ):
'''
signal: real 1D array
ker: real 1D array
signal and ker must have same shape
'''
return np.real(np.fft.ifft( np.fft.fft(signal)*np.fft.fft(ker) ))
Since this is for homework, I'm leaving out a few details.
By the definition of convolution, if you append a signal a to itself, then the convolution between aa and b will contain inside the cyclic convolution of a and b.
E.g., consider the following:
import numpy as np
from scipy import signal
%pylab inline
a = np.array([1] * 10)
b = np.array([1] * 10)
plot(signal.convolve(a, b));
That is the standard convolution. Now this, however
plot(signal.convolve(a, np.concatenate((b, b))));
In this last figure, try to see where is the result of the circular convolution, and how to generalize this.
Code for this that you can copy-paste, in the spirit of StackOverflow:
n = a.shape[0]
np.convolve(np.tile(a, 2), b)[n:2 * n]
This assumes that a, b have the same shape.
I have 2 numpy arrays (say X and Y) which each row represents a point vector.
I would like to find the squared euclidean distances (will call this 'dist') between each point in X to each point in Y.
I would like the output to be a matrix D where D(i,j) is dist(X(i) , Y(j)).
I have the following python code based on : http://nonconditional.com/2014/04/on-the-trick-for-computing-the-squared-euclidian-distances-between-two-sets-of-vectors/
def get_sq_distances(X, Y):
a = np.sum(np.square(X),axis=1,keepdims=1)
b = np.ones((1,Y.shape[0]))
c = a.dot(b)
a = np.ones((X.shape[0],1))
b = np.sum(np.square(Y),axis=1,keepdims=1).T
c += a.dot(b)
c -= 2*X.dot(Y.T)
return c
I'm trying to avoid loops (should I?) and to use matrix multiplication in order to do a fast computation.
But I have the problem with "Memory Error" on large arrays. Maybe there is a better way to do this?
Scipy has the cdist function that does exactly what you want:
from scipy.spatial import distance
distance.cdist(X, Y, 'sqeuclidean')
The docs linked above have some good examples.
subtract lists, then square the list, then do sum.
import numpy as np
def get_sq_distances(a,b):
return np.sum(np.square(np.subtract(a,b)))
print(get_sq_distances([5,7,9],[4,5,6]))
Assume that I have an affinity matrix A and a diagonal matrix D. How can I compute the Laplacian matrix in Python with nympy?
L = D^(-1/2) A D^(1/2)
Currently, I use L = D**(-1/2) * A * D**(1/2). Is this a right way?
Thank you.
Please note that it is recommended to use numpy's array instead of matrix: see this paragraph in the user guide. The confusion in some of the responses is an example of what can go wrong... In particular, D**0.5 and the products are elementwise if applied to numpy arrays, which would give you a wrong answer. For example:
import numpy as np
from numpy import dot, diag
D = diag([1., 2., 3.])
print D**(-0.5)
[[ 1. Inf Inf]
[ Inf 0.70710678 Inf]
[ Inf Inf 0.57735027]]
In your case, the matrix is diagonal, and so the square root of the matrix is just another diagonal matrix with the square root of the diagonal elements. Using numpy arrays, the equation becomes
D = np.array([1., 2., 3.]) # note that we define D just by its diagonal elements
A = np.cov(np.random.randn(3,100)) # a random symmetric positive definite matrix
L = dot(diag(D**(-0.5)), dot(A, diag(D**0.5)))
Numpy allows you to exponentiate a diagonal "matrix" with positive elements and a positive exponent directly:
m = diag(range(1, 11))
print m**0.5
The result is what you expect in this case because NumPy actually applies the exponentiation to each element of the NumPy array individually.
However, it indeed does not allow you to exponentiate any NumPy matrix directly:
m = matrix([[1, 1], [1, 2]])
print m**0.5
produces the TypeError that you have observed (the exception says that the exponent must be an integer–even for matrices that can be diagonalized with positive coefficients).
So, as long as your matrix D is diagonal and your exponent is positive, you should be able to directly use your formula.
Well, the only problem I see is that if you are using Python 2.6.x (without from __future__ import division), then 1/2 will be interpreted as 0 because it will be considered integer division. You can get around this by using D**(-.5) * A * D**.5 instead. You can also force float division with 1./2 instead of 1/2.
Other than that, it looks correct to me.
Edit:
I was trying to exponentiate a numpy array, not a matrix before, which works with D**.5. You can exponentiate a matrix element-wise using numpy.power. So you would just use
from numpy import power
power(D, -.5) * A * power(D, .5)
Does numpy have square root function for matrixes? Then you could do sqrt(D) instead of (D**(1/2))
Maybe the formula should realy be written
L = (D**(-1/2)) * A * (D**(1/2))
Based on previous comment this formula should work in case of D being diagonal matrix (I have not chance to prove it now).