Closed sangyx closed 4 years ago
Hello. I think you’re confusing what np.positive
and np.negative
do. They correspond to +x
and -x
, regardless of the value of x
. So np.positive(-5) = -5
and np.negative(-5) = +5
. Your derivative for np.sign
is also slightly incorrect, unfortunately, as it’s undefined at x == 0
. So it should be np.broadcast_to(np.where(x[0] == 0, float('nan'), 0), x[1].shape)
.
The second part is due to the product rule where the input is a function of the input. So you apply the chain rule f’(x) * d/dx g(f(x))
where f(x)
is x[0]
, g(x)
is np.sign(x)
in this case, and f’(x)
is x[1]
here.
What you’re suggesting is true for np.abs
, however.
Sorry for that. I can't guess the usage of the two functions and I should open an issue for this before the pr. I will try to complete the np.abs
. But I think there is another problem. np.exp2
calculates 2**p for all p in the input array. But the code to calculate the derivative for it is :
register_diff(np.exp2, lambda x: x[1] * np.log(2) * np.exp(x[0]))
It should be:
register_diff(np.exp2, lambda x: x[1] * np.log(2) * np.power(2, x[0]))
Ah, yes. That’s a mistake on my part, same for exp10
. You can go ahead and fix that. I’d replace np.power(2, x)
with np.exp2(x)
, but the rest seems good.
Hi, when I complete the np.abs
as:
register_diff(np.sign, lambda x: np.broadcast_to(np.where(x[0] == 0, float('nan'), 0), x[1].shape))
register_diff(np.absolute, lambda x: x[1] * np.where(np.sign(x[0]) == 0, float('nan'), np.sign(x[0])))
The diff of np.abs is fine. But the diff of np.sign
encounter a problem:
PS F:\OneDrive - sjtu.edu.cn\Project\GSOC\udiff\src> python .\test.py
<DiffArray, name=unbound, arr=
[2. 3. 0.]
>
<DiffArray, name=unbound, arr=
[ 1. -1. nan]
>
Traceback (most recent call last):
File ".\test.py", line 12, in <module>
y = np.sign(x)
File "F:\OneDrive - sjtu.edu.cn\Project\GSOC\udiff\src\udiff\_uarray_plug.py", line 65, in __ua_function__
diff_arr = global_registry[a[0]](*a[1:], **kw)
File "F:\OneDrive - sjtu.edu.cn\Project\GSOC\udiff\src\udiff\_builtin_diffs.py", line 32, in <lambda>
register_diff(np.sign, lambda x: np.broadcast_to(np.where(x[0] == 0, float('nan'), 0), x[1].shape))
File "D:\Python\lib\site-packages\unumpy\_multimethods.py", line 105, in f
return globals()[name](self, other)
File "F:\OneDrive - sjtu.edu.cn\Project\GSOC\udiff\src\udiff\_uarray_plug.py", line 65, in __ua_function__
diff_arr = global_registry[a[0]](*a[1:], **kw)
KeyError: <ufunc 'equal'>
But I don't know how to complete the diff of np.equal
.
Hmm. Try x[0].arr
.
Thx, the pr have committed.
Thanks @sangyx. This is in!
Hi, I found a bug in np.positive and np.negative. The diff calculate in the source is incorrect:
If we suppose that
x = [1, -1]
, then they = np.positive(x)=[1, 1]
. We can see thaty = x
if x > 0 andy=-x
if x < 0. So the diff of y should bey=sign(x)=[1, -1]