Matrix divide by zero warning - numpy

I am new in Python and I am facing the following error in the code:
import numpy as np
A = np.empty([2, 2], dtype = float)
Z = np.empty([2, 2], dtype = float)
Z = [[2.0, 0.0], [0.0, 3.0]]
A = [[1, -1], [1, -2]]
print(np.divide(A, np.power(Z, 2)))
These code gives the following result:
[[ 0.25 -inf], [inf -0.22222222]]
But I know, using a calculator, that the correct answer should be:
[[ 0.25 -0.25], [ 0.111111 -0.22222222]]
In short, thhis operation gives me the following error:
RuntimeWarning: divide by zero encountered in true_divide

You are element-wise dividing A by Z^2:
A:
[[1, -1], [1, -2]]
Z^2:
[[4.0, 0.0], [0.0, 9.0]]
A/Z^2:
[[ 0.25 -inf], [inf -0.22222222]]
The output is correct. You receive the warning (and not an error) of division by 0 because there are 0s in Z^2 in denominator that result in infs in output. Your calculator output is not what your code does.

Related

numpy eigen decomposition produce unexpected output?

According to documentation of numpy.linalg.eig and what I understand about eigen decomposition, the following code :
a = [[1,1],[-1,-1]]
w, v = np.linalg.eig(a)
c = a#v
print(c)
print(w)
should produce :
[[√2,0],[-√2,0]]
[4,0]
but instead it produced :
[[ 1.11022302e-16+1.11022302e-16j 1.11022302e-16-1.11022302e-16j]
[-1.11022302e-16-1.11022302e-16j -1.11022302e-16+1.11022302e-16j]]
[-3.25176795e-17+1.57009246e-16j -3.25176795e-17-1.57009246e-16j]
so where was I wrong?
With matrix a
a = np.array([[ 1, 1],\
[-1, -1]])
your two eigenvalues should theoretically be w_th=[0,0], so :
w
>>> array([-3.25176795e-17+1.57009246e-16j, -3.25176795e-17-1.57009246e-16j])
is just some zero +/- round-off error in complex form. Concerning the eigenvectors, these are v_th=[[1,1],[-1,-1]] but numpy.linalg.eig normalized them to be unitary length (e.g. for the first one np.linalg.norm(v[:,0],2) = 0.99...), which means it just gave you an approximation of [[1/sqrt(2),1/sqrt(2)],[-1/sqrt(2),-1/sqrt(2)]] :
v
>>> array([[ 0.70710678+0.00000000e+00j, 0.70710678-0.00000000e+00j],
[-0.70710678+1.11022302e-16j, -0.70710678-1.11022302e-16j]])
Knowing all of the above, you can now verify it numerically by comparing both sides of the equation :
np.allclose(a#v,w*v)
>>> True
or with theorical values, i.e. "without" round-off errors :
a#np.asarray(v_th)
>>> array([[0, 0],
[0, 0]])
np.asarray(w_th)*np.asarray(v_th)
>>> array([[0, 0],
[0, 0]])
so there is nothing unexpected from numpy output here, seems just that your analytical eigenvalues [4,0] are false.

Eigenvector normalization in numpy

I'm using the linalg in numpy to compute eigenvalues and eigenvectors of matrices of signed reals.
I've read this previous question but still don't grasp the normalization of eigenvectors.
Here is an example straight off Wikipedia:
import numpy as np
from numpy import linalg as la
a = np.matrix([[2, 1], [1, 2]], dtype=np.float)
eigh_vals, eigh_vects = np.linalg.eig(a)
print 'eigen_values='
print eigh_vals
print 'eigen_vectors='
print eigh_vects
The eigenvalues are 1 and 3.
For eigenvectors we expect scalar multiples of [1, -1] and [1, 1], which I get:
eig_vals=
[ 3. 1.]
eig_vets=
[[ 0.70710678 -0.70710678]
[ 0.70710678 0.70710678]]
I understand the 1/sqrt(2) factor is to have the norm=1 but why?
Can normalization be 'switched off'?
Thanks!
The key message for the first eigenvector in the Wikipedia article is
Any non-zero vector with v1 = −v2 solves this equation.
So the actual solution is V1 = [x, -x]. Picking the vector V1 = [1, -1] may be pleasing to the human eye, but it is just as aritrary as picking a vector V1 = [104051, -104051] or any other real value.
Actually, picking V1 = [1, -1] / sqrt(2) is the least arbitrary. Of all the possible vectors for V1, it's the only one that is of unit length.
However if instead of unit length you prefer the first value to be 1, you can do
eigh_vects /= eigh_vects[:, 0]
import numpy as np
import sympy as sp
v = sp.Matrix([[2, 1], [1, 2]])
v_vec = v.eigenvects()
v_vec is a list contains 2 tuples:
[(1, 1, [Matrix([
[-1],
[ 1]])]), (3, 1, [Matrix([
[1],
[1]])])]
1 and 3 is the two eigenvalues. The '1' behind 1 & 3 is the number of the eigenvalues. In each tuple, the third element is the eigenvector of each eigenvalue. It is a Matrix object in sp. You can convert a Matrix object to the np array.
v_vec1 = np.array(v_vec[0][2], dtype=float)
v_vec2 = np.array(v_vec[1][2], dtype=float)
print('v_vec1 =', v_vec1)
print('v_vec2 =', v_vec2)
Here is the normalized eigenvectors you would get:
v_vec1 = [[-1. 1.]]
v_vec2 = [[1. 1.]]
If sympy is an option for you, it appears to normalize less aggressively:
import sympy
a = sympy.Matrix([[2, 1], [1, 2]])
a.eigenvects()
# [(1, 1, [Matrix([
# [-1],
# [ 1]])]), (3, 1, [Matrix([
# [1],
# [1]])])]

How to use numpy array divide?

In [2]: x = np.array([5,4,3,2])
In [3]: y = np.array([2,2,2,2])
Both are int format and when I use x/y, the output are floor int of every element.
How to divide each element and get the float result. For example : 2.5, 2, 1.5, 1.
You can use np.true_divide -
np.true_divide(x,y)
Sample run -
In [53]: x = np.array([5,4,3,2])
In [54]: y = np.array([2,2,2,2])
In [55]: np.true_divide(x,y)
Out[55]: array([ 2.5, 2. , 1.5, 1. ])
Alternatively, you can also use from __future__ import division, but this will keep the divisions as floating one for the rest of the session -
In [56]: x/y
Out[56]: array([2, 2, 1, 1])
In [57]: from __future__ import division
In [58]: x/y
Out[58]: array([ 2.5, 2. , 1.5, 1. ])

Is this how adding a python list to numpy arrary is expected to work?

Adding a python list to a numpy array produces the same result as adding a python float to a numpy array. If the array is cast as a list when it is added, the then it behaves like extend() as I was hoping the first calculation would behave. Is there a good reason why the behavior is the same adding a list vs float to an array?
In [3]: [-3.0] + numpy.linspace(0, 2, 5)
Out[3]: array([-3. , -2.5, -2. , -1.5, -1. ])
In [4]: -3.0 + numpy.linspace(0, 2, 5)
Out[4]: array([-3. , -2.5, -2. , -1.5, -1. ])
In [5]: [-3.0] + list(numpy.linspace(0, 2, 5))
Out[5]: [-3.0, 0.0, 0.5, 1.0, 1.5, 2.0]

Transpose of a vector using numpy

I am having an issue with Ipython - Numpy. I want to do the following operation:
x^T.x
with and x^T the transpose operation on vector x. x is extracted from a txt file with the instruction:
x = np.loadtxt('myfile.txt')
The problem is that if i use the transpose function
np.transpose(x)
and uses the shape function to know the size of x, I get the same dimensions for x and x^T. Numpy gives the size with a L uppercase indice after each dimensions. e.g.
print x.shape
print np.transpose(x).shape
(3L, 5L)
(3L, 5L)
Does anybody know how to solve this, and compute x^T.x as a matrix product?
Thank you!
What np.transpose does is reverse the shape tuple, i.e. you feed it an array of shape (m, n), it returns an array of shape (n, m), you feed it an array of shape (n,)... and it returns you the same array with shape(n,).
What you are implicitly expecting is for numpy to take your 1D vector as a 2D array of shape (1, n), that will get transposed into a (n, 1) vector. Numpy will not do that on its own, but you can tell it that's what you want, e.g.:
>>> a = np.arange(4)
>>> a
array([0, 1, 2, 3])
>>> a.T
array([0, 1, 2, 3])
>>> a[np.newaxis, :].T
array([[0],
[1],
[2],
[3]])
As explained by others, transposition won't "work" like you want it to for 1D arrays.
You might want to use np.atleast_2d to have a consistent scalar product definition:
def vprod(x):
y = np.atleast_2d(x)
return np.dot(y.T, y)
I had the same problem, I used numpy matrix to solve it:
# assuming x is a list or a numpy 1d-array
>>> x = [1,2,3,4,5]
# convert it to a numpy matrix
>>> x = np.matrix(x)
>>> x
matrix([[1, 2, 3, 4, 5]])
# take the transpose of x
>>> x.T
matrix([[1],
[2],
[3],
[4],
[5]])
# use * for the matrix product
>>> x*x.T
matrix([[55]])
>>> (x*x.T)[0,0]
55
>>> x.T*x
matrix([[ 1, 2, 3, 4, 5],
[ 2, 4, 6, 8, 10],
[ 3, 6, 9, 12, 15],
[ 4, 8, 12, 16, 20],
[ 5, 10, 15, 20, 25]])
While using numpy matrices may not be the best way to represent your data from a coding perspective, it's pretty good if you are going to do a lot of matrix operations!
For starters L just means that the type is a long int. This shouldn't be an issue. You'll have to give additional information about your problem though since I cannot reproduce it with a simple test case:
In [1]: import numpy as np
In [2]: a = np.arange(12).reshape((4,3))
In [3]: a
Out[3]:
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
In [4]: a.T #same as np.transpose(a)
Out[4]:
array([[ 0, 3, 6, 9],
[ 1, 4, 7, 10],
[ 2, 5, 8, 11]])
In [5]: a.shape
Out[5]: (4, 3)
In [6]: np.transpose(a).shape
Out[6]: (3, 4)
There is likely something subtle going on with your particular case which is causing problems. Can you post the contents of the file that you're reading into x?
This is either the inner or outer product of the two vectors, depending on the orientation you assign to them. Here is how to calculate either without changing x.
import numpy
x = numpy.array([1, 2, 3])
inner = x.dot(x)
outer = numpy.outer(x, x)
The file 'myfile.txt' contain lines such as
5.100000 3.500000 1.400000 0.200000 1
4.900000 3.000000 1.400000 0.200000 1
Here is the code I run:
import numpy as np
data = np.loadtxt('iris.txt')
x = data[1,:]
print x.shape
print np.transpose(x).shape
print x*np.transpose(x)
print np.transpose(x)*x
And I get as a result
(5L,)
(5L,)
[ 24.01 9. 1.96 0.04 1. ]
[ 24.01 9. 1.96 0.04 1. ]
I would be expecting one of the two last result to be a scalar instead of a vector, because x^T.x (or x.x^T) should give a scalar.
b = np.array([1, 2, 2])
print(b)
print(np.transpose([b]))
print("rows, cols: ", b.shape)
print("rows, cols: ", np.transpose([b]).shape)
Results in
[1 2 2]
[[1]
[2]
[2]]
rows, cols: (3,)
rows, cols: (3, 1)
Here (3,) can be thought as "(3, 0)".
However if you want the transpose of a matrix A, np.transpose(A) is the solution. Shortly, [] converts a vector to a matrix, a matrix to a higher dimension tensor.