Numpy inner product of 2 column vectors - python

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)

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

Element wise divide like MATLAB's ./ operator?

I am trying to normalize some Nx3 data. If X is a Nx3 array and D is a Nx1 array, in MATLAB, I can do
Y = X./D
If I do the following in Python, I get an error
X = np.random.randn(100,3)
D = np.linalg.norm(X,axis=1)
Y = X/D
ValueError: operands could not be broadcast together with shapes (100,3) (100,)
Any suggestions?
Edit: Thanks to dm2.
Y = X/D.reshape((100,1))
Another way is to use scikitlearn.
from sklearn import preprocessing
Y = preprocessing.normalize(X)
From numpy documentation on array broadcasting:
When operating on two arrays, NumPy compares their shapes
element-wise. It starts with the trailing (i.e. rightmost) dimensions
and works its way left. Two dimensions are compatible when
they are equal, or
one of them is 1
Both of your arrays have the same first dimension, but your X array is 2-dimensional, while your D array is 1-dimensional, which means the shapes of these two arrays do not meet the requirements to be broadcast together.
To make sure they do, you could reshape your D array into a 2-dimensional array of shape (100,1), which would satisfy the requirements to broadcast: rightmost dimensions are 3 and 1 (one of them is 1) and the other dimensions are equal (100 and 100).
So:
Y = X/D.reshape((-1,1))
or
Y = X/D.reshape((100,1))
or
Y = X/D[:,np.newaxis]
Should give you the result you're after.

Sum a 3d numpy array for the third dimension only

I need the code in python
for example i have a numpy array sized (x,y,z)
i want to sum it into an array of (x,y), sum z only
z was an array of number, after sum he become a number to finaly get a 2d matrix
You can specify the axis on which the sum will be performed for the numpy function sum:
import numpy as np
res = np.sum(arr, axis=2)
# np.sum(arr, axis=-1) is equivalent in this case

Python: Functions of arrays that return arrays of the same shape

Note: I'm using numpy
import numpy as np
Given 4 arrays of the same (but arbitrary) shape, I am trying to write a function that forms 2x2 matrices from each corresponding element of the arrays, finds the eigenvalues, and returns two arrays of the same shape as the original four, with its elements being eigenvalues (i.e. the resulting arrays would have the same shape as the input, with array1 holding all the first eigenvalues and array2 holding all the second eigenvalues).
I tried doing the following, but unsurprisingly, it gives me an error that says the array is not square.
temp = np.linalg.eig([[m1, m2],[m3, m4]])[0]
I suppose I can make an empty temp variable in the same shape,
temp = np.zeros_like(m1)
and go over each element of the original arrays and repeat the process. My problem is that I want this generalised for arrays of any arbitrary shape (need not be one dimensional). I would guess that finding the shape of the arrays and designing loops to go over each element would not be a very good way of doing it. How do I do this efficiently?
Construct a 2x2x... array:
temp = np.array([[m1, m2], [m3, m4]])
Move the first two dimensions to the end for a ...x2x2 array:
for _ in range(2):
temp = np.rollaxis(temp, 0, temp.ndim)
Call np.linalg.eigvals (which broadcasts) for a ...x2 array of eigenvalues:
eigvals = np.linalg.eigvals(temp)
And split this into an array of first eigenvalues and an array of second eigenvalues:
eigvals1, eigvals2 = eigvals[..., 0], eigvals[..., 1]

Python 3d array times 1d vector

I'm trying to multiply a [12x256x256] array with a [12] array. The idea is taht the first one is a stack of 12 [256x256] arrays and the 2nd one is a stack of 1d scalars. So if the 2nd array is [1,2,3,4,...,12], then I want to multiply the first layer of the 3d one by 1, the 2nd layer by 2, etc.
How can I do this?
You can add new axises and multiply them.
import numpy as np
a = np.ones((12,256,256))
b = np.array(range(12))+1
c = a * b[:, np.newaxis, np.newaxis]
In numpy you can do
# let m be 12x256x256, n be 12
m = np.array(m)
n = np.array(n)
(m.swapaxes(0,2) * n).swapaxes(2,0)

Categories