I'm trying to modify Plus
but am running into trouble with it being Listable
:
ClearAll[f, g, h]
Attributes[f] = {Listable};
h /: f[x_h, l_List] := 0
h /: g[x_h, l_List] := 0
f[h[1], {1, 1}] (* {f[h[1], 1], f[h[1], 1]}, not OK I want 0 *)
g[h[1], {1,1}] (* 0 as expected *)
How can I make the UpValue (or equivalent) have higher priority than the listability?
EDIT:
I ended up wanting to do this again and figured I'd fix the Plus
properly.
Here it is working using Sashas answer and Mr.Wizards $Pre
method:
$Pre =.
ClearAll[myPlus]; Attributes[myPlus] = {Orderless};
Unprotect[InterpolatingFunction]; UpValues[InterpolatingFunction] = {};
InterpolatingFunction /:
myPlus[y_InterpolatingFunction[t_Symbol], l_List] :=
Interpolation[
MapThread[List, {y["Grid"], l + # & /@ y["ValuesOnGrid"]}],
InterpolationOrder -> First[y["InterpolationOrder"]]][t]
myPlus[other__] := +other
$Pre = Function[x, Unevaluated@x /. Plus -> myPlus, HoldAllComplete];
Protect[InterpolatingFunction];
y = Interpolation[Table[{i, RandomReal[{0, 1}, 2]}, {i, 1, 10}]];
ParametricPlot[{y[t], y[t] - {1, 1}}, {t, 1, 10}]
e:f[_, l_List]:=Thread@Unevaluated@e
or something similar, but that depends on the case at hand $\endgroup$f
isPlus
, my bad. $\endgroup$$Pre
and$Post
to fool the evaluator, but you cannot do that). Just programListable like f[x_, l_List] := Thread[f, {x, l}];
and all is good. $\endgroup$