I think you're assuming that your function is being called n * n
times, each time with a new pair of possible indices 0..n. Try printing the values to see what's going on:
>>> import numpy as np
>>> n = 3
>>> def f(i, j):
... print(i)
... print(j)
... return n if i==j else (i+1) + (j+1)
>>> np.fromfunction(f, (n,n), dtype=int)
[[0 0 0]
[1 1 1]
[2 2 2]]
[[0 1 2]
[0 1 2]
[0 1 2]]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "...\Python\Python311\site-packages\numpy\core\numeric.py", line 1866, in fromfunction
return function(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "<stdin>", line 4, in f
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Instead, the function is being called just once with a meshgrid of the possible indices!
In the ... if i == j else ...
part, after i
and j
have been compared, you're left with a boolean array with both True and False values, so numpy is unsure what to do.
Instead, rely on np.where
for this kind of if-else
logic, and possibly use a little bit of broadcasting for efficiency:
>>> xs, ys = np.indices((n, n), sparse=True)
>>> np.where(np.eye(n), n, xs + ys + 2)
array([[5, 3, 4, 5, 6],
[3, 5, 5, 6, 7],
[4, 5, 5, 7, 8],
[5, 6, 7, 5, 9],
[6, 7, 8, 9, 5]])