I am running this program:
def f2d(x,y):
# condition
if 4*x**2 y**2 <= 4:
return np.sin(x*y)
else:
return 0
def my_prog(function,n):
x = np.random.uniform(low=-1, high= 1, size=(n))
y = np.random.uniform(low=-2, high= 2, size=(n))
f = function(x,y)
return (f,n)
(f,n) = my_prog(f2d,5)
and I get this error:
The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
It's not very clear: I don't understand how I could insert a.any()
or a.all()
within the program I made, where should I do it, and why...
My goal was just to have f
created as a 1D array (just as x
and y
are 1D arrays) and containing np.sin(x*y)
if condition is fulfilled, or 0
if condition is not fulfilled, as requested in def f2d(x,y)
?
So, it looks like a kind of element wise manipulation of arrays x
and y
under a certain condition. But I can't see why it doesn't work. Should I first create f
as an empty array? Does the problem come from there?
CodePudding user response:
if-clause is expecting a truthy-value but 4*x**2 y**2 <= 4
is shape (5,) boolean array. To get it to work, you should either convert it to a single truthy-value or iterate over it, depending on what you're trying to do. However, for the purpose of your task, you could use numpy.where
to select values depending on the condition. In this case, select from np.sin(x*y)
if the condition is satisfied, 0 otherwise.
def f2d(x,y):
# condition
return np.where(4*x**2 y**2 <= 4, np.sin(x*y), 0)
Test run:
>>> my_prog(f2d,5)
(array([0.02896101, 0.34900898, 0. , 0. , 0.15721751]), 5)
CodePudding user response:
The problem is under # condition
, after comparing the operation result with 4, you will get a Boolean array, but the Boolean array cannot be converted to a true value, so you get an error, like this:
>>> np.arange(8) < 5
array([ True, True, True, True, True, False, False, False])
>>> if np.arange(8) < 5:
... pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()