Reputation: 101
This is related to another question I have except there I am looking for a vectorized/broadcasting solution.
Here I am hoping to try using np.fromfunction
but am having issues.
# L1 and L2 will range from 0 to 3 typically, sometimes up to 5
# all of the following are dummy values but match correct `type`
L1, L2, x1, x2, fac = 2, 3, 2.0, 4.5, 2.3
saved_values = np.random.uniform(high=75.0, size=[max(L1,L2) + 1, max(L1,L2) + 1])
facts = np.random.uniform(high=65.0, size=[L1 + L2 + 1])
val = 0
for i in range(L1+1):
sf = saved_values[L1][i] * x1 ** (L1 - i)
for j in range(L2 + 1):
m = i + j
if m % 2 == 0:
num = sf * facts[m] / (2 * fac) ** (m / 2)
val += saved_values[L2][j] * x1 ** (L1 - j) * num
rather than use a double for loop, which is not vectorized and potentially slower (being vectorized is more important for me), I would like to use np.fromfunction
to fill a matrix with the necessary values
matrix = np.fromfunction(lambda i, j:
saved_values[L1][i] * x1 ** (L1 - i) *
saved_values[L2][j] * x2 ** (L2 - j) *
facts[i+j] / (2 * fac) **( (i+j) / 2),
(L1+1,L2+1)
)
This generates the double for loop matrix, I then need to go over it and make anything that would fail (i+j) % 2 == 0
have a zero value, and then sum all elements in the matrix.
I get the following error
Traceback (most recent call last):
File "main.py", line 54, in <module>
(L1+1,L2+1)
File "/usr/lib/python3/dist-packages/numpy/core/numeric.py", line 1808, in fromfunction
return function(*args,**kwargs)
File "main.py", line 53, in <lambda>
facts[i+j] / (2 * fac) **( (i+j) / 2),
IndexError: arrays used as indices must be of integer (or boolean) type
Upvotes: 0
Views: 885
Reputation: 30991
As I suppose, you think that the function passed as the first parameter to np.fromfunction is called several times, for each combination of i and j.
Unfortunately, this is not the case. To see the actual way how it operates, make such experiment:
def myFun(i, j):
print(f'myFun:\n{i.shape}\n{i}\n{j.shape}\n{j}')
rv = i + j
return rv
I deliberately put a trace printout, to show what I mean.
Then run it:
np.fromfunction(myFun, (2, 3))
The result is:
myFun:
(2, 3)
[[0. 0. 0.]
[1. 1. 1.]]
(2, 3)
[[0. 1. 2.]
[0. 1. 2.]]
array([[0., 1., 2.],
[1., 2., 3.]])
The first part is the printout, occuring only once and the second - the actual result. Note that:
So the conclusions are that:
Upvotes: 4