Bug introduced in 8 or earlier and fixed in 10.4.0
Bug isn't present in version 5.2
I don't think I quite understand how Except works.
I want to define $f(a,b) = (a-b)\ln(a-b)$, with the special case $f(a,a)=0$. Except, the function shouldn't evaluate if either $a$ or $b$ is zero.
I tried:
ClearAll[f]
f[Except[0, a_], Except[0, a_]] := 0;
f[Except[0, a_], Except[0, b_]] := (a - b) Log[a - b];
But for some reason DownValues[f] only reports one definition:
DownValues[f]
(* { HoldPattern[ f[Except[0, a_], Except[0, b_]]] :> (a - b) Log[a - b] } *)
This is bad because if the user inputs f[x,x], I get Infinity::indet errors.
Question What did I do wrong, and how do I make definitions with Except?
Answer
Another way to get two definitions is to only use Except on the first argument for the case where the arguments are identical.
Clear[f]
f[Except[0, a_], a_] := 0
f[Except[0, a_], Except[0, b_]] := (a - b) Log[a - b]
Annoyingly it doesn't matter the order for the definitions it comes out like this:
DownValues@f
(* {HoldPattern[f[Except[0, a_], Except[0, b_]]] :> (a - b) Log[a - b],
HoldPattern[f[Except[0, a_], a_]] :> 0} *)
So in order to get the right behaviour you have to do
DownValues[f] = Reverse@DownValues@f
(* {HoldPattern[f[Except[0, a_], a_]] :> 0,
HoldPattern[f[Except[0, a_], Except[0, b_]]] :> (a - b) Log[a - b]} *)
Now
f[3, 1]
f[3,0]
f[2,2]
f[0,0]
gives
2 Log[2]
f[3,0]
0
f[0,0]
Comments
Post a Comment