Reputation: 1224
I am trying to use a nested for loop to evaluate function f(r) at every combination of 2D polar coordinates.
My current code is:
r = np.linspace(0, 5, 10)
phi = np.linespace(0,2*np.pi, 10)
for i in r:
for j in phi:
X = f(r) * np.cos(phi)
print X
When I run this as is it returns X as a 1D array of f(r) and cos(phi) is 1 (ie. phi = 0). However I want f(r) at every value of r, which is then multiplied by its corresponding phi value. This would be a 2D array (10 by 10) where by every combination of r and phi is evaluated.
If you have any suggestions about possible efficiencies I would appreciate it as eventually I will be running this with a resolution much greater than 10 (maybe as high as 10,000) and looping it many thousands of times.
Upvotes: 2
Views: 2087
Reputation: 7736
np.linspace
not np.linespace
.i
and j
are not even used in your inner loop. Right now, you're executing the same statement with the same arguments and the same result over and over again. You could have executed the inner statement only one single time, X
would be the same.r
and phi
, do your calculation and put it into the right field of your output array.def f(x):
return x
r = np.linspace(0, 5, 10)
phi = np.linspace(0, 2*np.pi, 10)
X = np.zeros((len(r), len(phi)))
for i in xrange(len(r)):
for j in xrange(len(phi)):
X[i,j] = f(r[i]) * np.cos(phi[j])
print X
P.S. Don't go with the solutions, that put the results into ordinary lists, stick with numpy arrays for mathematical problems.
Upvotes: 5
Reputation: 49803
Instead of assigning to X, you should be adding the most recent 1D array to it. (You'll need to initialize X before the outer loop.)
Edit: You don't need the inner loop; it's computing across all of phi (which is why you get the 1D array) repeatedly. (Note how it doesn't use j). That'll speed things up a bit, AND get you the correct answer!
Upvotes: 0
Reputation: 365697
When I run this as is it returns X as a 1D array of f(r) and cos(phi) is 1 (ie. phi = 0).
That's because you don't store, print, or do anything else with all those intermediate values you generate. All you do is rebind X
to the latest value over and over (forgetting whatever used to be in X
), so at the end, it's bound to the last one.
If you want all of those X
values, you have to actually store them in some way. For example:
Xs = []
for i in r:
for j in phi:
X = f(r) * np.cos(phi)
Xs.append[X]
Now, you'll have a list of each X
instead of just the last one.
Of course in general, the whole reason you use NumPy is to "vectorize" operations instead of looping in the first place. (This allows the loops and the arithmetic to be done in C/C++/Fortran/whatever instead of Python, typically making them an order of magnitude or so faster.) So, if you can rewrite your code to create a 2D array from your 1D array by broadcasting, instead of creating a list of 1D arrays, it will be better…
Upvotes: 1