compute matrix product for multiple inputs - python

I am trying to compute a transform given by b = A*x. A is a (3,4) matrix. If x is one (4,1) vector the result is b (3,1).
Instead, for x I have a bunch of vectors concatenated into a matrix and I am trying to evaluate the transform for each value of x. So x is (20, 4). How do I broadcast this in numpy such that I get 20 resulting values for b (20,3)?
I could loop over each input and compute the output but it feels like there must be a better way using broadcasting.
Eg.
A = [[1,0,0,0],
[2,0,0,0],
[3,0,0,0]]
if x is:
x = [[1,1,1,1],
[2,2,2,2]]
b = [[1,2,3],
[2,4,6]]
Each row of x is multiplied with A and result is stored as a row in b.

numpy dot
import numpy as np
A = np.random.normal(size=(3,4))
x = np.random.normal(size=(4,20))
y = np.dot(A,x)
print y.shape
Result: (3, 20)
And of course if you want (20,3) you can use np.transpose()

Related

nested operations on two numpy arrays, one 2d and one 1d

Say I have one 2d numpy array X with shape (3,3) and one numpy array Y with shape (3,) where
X = np.array([[0,1,2],
[3,4,5],
[1,9,2]])
Y = np.array([[1,0,1]])
How can I create a numpy array, Z for example, from multiplying X,Y element-wise and then summation row-wise?
multiplying element-wise would yield: 0,0,2, 3,0,5, 1,0,2
then, adding each row would yield:
Z = np.array([2,8,3])
I have tried variations of
Z = np.sum(X * Y) --> adds all elements of entire array, not row-wise.
I know I can use a forloop but the dataset is very large and so I am trying to find a more efficient numpy-specific way to perform the operation. Is this possible?
You can do the following:
sum_row = np.sum(X*Y, axis=1) # axis=0 for columnwise

How can I ensure a numpy array to be either a 2D row- or column vector?

Is there a numpy function to ensure a 1D- or 2D- array to be either a column or row vector?
For example, I have either one of the following vectors/lists. What is the easiest way to convert any of the input into a column vector?
x1 = np.array(range(5))
x2 = x1[np.newaxis, :]
x3 = x1[:, np.newaxis]
def ensureCol1D(x):
# The input is either a 0D list or 1D.
assert(len(x.shape)==1 or (len(x.shape)==2 and 1 in x.shape))
x = np.atleast_2d(x)
n = x.size
print(x.shape, n)
return x if x.shape[0] == n else x.T
assert(ensureCol1D(x1).shape == (x1.size, 1))
assert(ensureCol1D(x2).shape == (x2.size, 1))
assert(ensureCol1D(x3).shape == (x3.size, 1))
Instead of writing my own function ensureCol1D, is there something similar already available in numpy that ensures a vector to be column?
Your question is essentially how to convert an array into a "column", a column being a 2D array with a row length of 1. This can be done with ndarray.reshape(-1, 1).
This means that you reshape your array to have a row length of one, and let numpy infer the number of rows / column length.
x1 = np.array(range(5))
print(x1.reshape(-1, 1))
Output:
array([[0],
[1],
[2],
[3],
[4]])
You get the same output when reshaping x2 and x3. Additionally this also works for n-dimensional arrays:
x = np.random.rand(1, 2, 3)
print(x.reshape(-1, 1).shape)
Output:
(6, 1)
Finally the only thing missing here is that you make some assertions to ensure that arrays that cannot be converted are not converted incorrectly. The main check you're making is that the number of non-one integers in the shape is less than or equal to one. This can be done with:
assert sum(i != 1 for i in x1.shape) <= 1
This check along with .reshape let's you apply your logic on all numpy arrays.

Square array from linear array python

I would like to get a square matrix B from a linear vector A such that B = A * transpose(A). A is a numpy array and np.shape(A) returns (10,). I would like B to be a (10,10) array. I tried B = np.matmut(A, A[np.newaxis]) but I get an error :
shapes (10,) and (1,10) not aligned: 10 (dim 0) != 1 (dim 0)
you can do this using outer:
import numpy as np
vector = np.arange(10)
np.outer(vector, vector)
The solution is a little ugly, but it does what you need.
import numpy as np
vector = np.array([1,2,3,4,5,6,7,8,9,10],)
matrix = np.dot(vector[:,None],vector[None,:])
print(matrix)
You can also do the following:
import numpy as np
vector = np.array([1,2,3,4,5,6,7,8,9,10],)
matrix = vector*vector[:,None]
print(matrix)
The issue comes from the fact that transposing a one dimensional array does not have the effect you might expect.
Variation on outer product:
a = A.reshape(-1, 1) # make sure it's a column vector
B = a # a.T

Numpy inner product of 2 column vectors

How can I take an inner product of 2 column vectors in python's numpy
Below code does not work
import numpy as np
x = np.array([[1], [2]])
np.inner(x, x)
It returned
array([[1, 2],
[2, 4]])`
instead of 5
The inner product of a vector with dimensions 2x1 (2 rows, 1 column) with another vector of dimension 2x1 (2 rows, 1 column) is a matrix with dimensions 2x2 (2 rows, 2 columns). When you take the inner product of any tensor the inner most dimensions must match (which is 1 in this case) and the result is a tensor with the dimensions matching the outter, i.e.; a 2x1 * 1x2 = 2x2.
What you want to do is transpose both such that when you multiply the dimensions are 1x2 * 2x1 = 1x1.
More generally, multiplying anything with dimensions NxM by something with dimensionsMxK, yields something with dimensions NxK. Note the inner dimensions must both be M. For more, review your matrix multiplication rules
The np.inner function will automatically transpose the second argument, thus when you pass in two 2x1, you get a 2x2, but if you pass in two 1x2 you will get a 1x1.
Try this:
import numpy as np
x = np.array([[1], [2]])
np.inner(np.transpose(x), np.transpose(x))
or simply define your x as row vectors initially.
import numpy as np
x = np.array([1,2])
np.inner(x, x)
i think you mean to have:
x= np.array([1,2])
in order to get 5 as output, your vector needs to be 1xN not Nx1 if you want to apply np.inner on it
Try the following it will work
np.dot(np.transpose(a),a))
make sure col_vector has shape (N,1) where N is the number of elements
then simply sum one to one multiplication result
np.sum(col_vector*col_vector)

Combine matrices - numpy

I have four numpy matrix, each which shape is (2544, 2544). I wish to combine them to create a matrix which is (2544, 2544) by adding the corresponding elements from each. How can I do this? For example if I had this matrix:
x = [1,2
3,4]
y = [4,3
2,2]
my desired output would be:
d = [5,5
5,6]
Suppose your matrix are identified as a tuple matrices = (A,B,C,D).
Just aggregate them ABCD=np.dstack(matrices). then sum the result : ABCD.sum(axis=2).
I've edited my answer to reflect your specific question, but if you define your variables as matrices, you can simply add the variables as long as they are the same shape. Some example code is seen below:
import numpy as np
x = np.matrix([[1,2],[3,4]])
y = np.matrix([[4,3],[2,2]])
d = x + y
print d
which returns:
[[5 5]
[5 6]]

Categories