Reputation: 19164
I am working on conversion of code from matlab to python.
for values,
N = 100
V = [[ -7.94627203e+01 -1.81562235e+02 -3.05418070e+02 -2.38451033e+02][ 9.43740653e+01 1.69312771e+02 1.68545575e+01 -1.44450299e+02][ 5.61599000e+00 8.76135909e+01 1.18959245e+02 -1.44049237e+02]]
V is numpy array.
for i = 1:N
L(i) = sqrt(norm(v(:,i)));
if L(i) > 0.0001
q(:,i) = v(:,i)/L(i);
else
q(:,i) = v(:,i)*0.0001;
end
end
I have converted this code to :
L = []
q = []
for i in range(1, (N +1)):
L.insert((i -1),np.sqrt( np.linalg.norm(v[:, (i -1)])))
if L[(i -1)] > 0.0001:
q.insert((i -1), (v[:, (i -1)] / L[(i -1)]).tolist())
else:
q.insert((i -1), (v[:, (i -1)] * 0.0001).tolist())
q = np.array(q)
return q, len_
But, in matlab the resultant dimensions are 3 x 4 but I am getting 4 x 3 in python. Can anyone let me know where I am doing mistake?
Upvotes: 1
Views: 89
Reputation: 114851
You are inserting lists of length 3 into q
. When you finish the loop that creates q
, q
is a list of 4 items, where each item is a list of length 3. So np.array(q)
creates an array with shape 4x3. You could change the second-to-last line to this:
q = np.array(q).T
Or, you can use numpy more effectively to eliminate all the explicit for
loops. For example, if you are using numpy 1.8, the norm
function accepts an axis
argument.
Here's vectorized version of your code.
First, some setup for this example.
In [152]: np.set_printoptions(precision=3)
In [153]: np.random.seed(111)
Create some data to work with.
In [154]: v = 5e-9 * np.random.randint(0, 3, size=(3, 4))
In [155]: v
Out[155]:
array([[ 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00],
[ 1.000e-08, 5.000e-09, 1.000e-08, 1.000e-08],
[ 1.000e-08, 0.000e+00, 5.000e-09, 0.000e+00]])
Compute the square root of the norms of the columns by using the argument axis=0
in numpy.linalg.norm
.
In [156]: L = np.sqrt(np.linalg.norm(v, axis=0))
In [157]: L
Out[157]: array([ 1.189e-04, 7.071e-05, 1.057e-04, 1.000e-04])
Use numpy.where
to select the values by which the columns of v
are to be divided to create q
.
In [158]: scale = np.where(L > 0.0001, L, 1000.0)
In [159]: scale
Out[159]: array([ 1.189e-04, 1.000e+03, 1.057e-04, 1.000e+03])
q
is has shape (3, 4), and scale
has shape (4,), so we can use broadcasting to divide each column of q
by the corresponding value in scale
.
In [160]: q = v / scale
In [161]: q
Out[161]:
array([[ 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00],
[ 8.409e-05, 5.000e-12, 9.457e-05, 1.000e-11],
[ 8.409e-05, 0.000e+00, 4.729e-05, 0.000e+00]])
Repeated here are the three lines of the vectorized code:
L = np.sqrt(np.linalg.norm(v, axis=0))
scale = np.where(L > 0.0001, L, 1000.0)
q = v / scale
Upvotes: 1