how can I ensure the following definition to be associative?
Unprotect[Times];
a_ f[x_] + b_ f[y_] ^:= f[a x + b y]
Protect[Times];
gives me
a f[x] + b f[y] + c f[z]
f[a x + b y] + c f[z]
I'd like it to be
f[a x + b y + c z]
f[a x + b y] + c f[z]
is not the same as
1 * f[a x + b y] + c f[z]
so the pattern
a_ f[x] + b_ f[y]
does not match it. But if you use a_.
then it's replaced with the default value (1, for Times
) if the multiplier is omitted. So then it will match.
However, you observe that if c == 1
, then it doesn't work again. This is understandable, since if c == 1
, the expression
f[a x + b y] + f[z]
does not contain Times
at level 1 anymore. I suggest using more granular rules:
a_ f[x_] ^:= f[a x]
f[x_] + f[y_] ^:= f[x + y]
This achieves two things: the upvalue is attached to f
and not to system symbols, and it solves the problem you mentioned in the comments.
c==1
a variant of the first case, now with the two multipliers omitted? And shouldn't then the two multipliers be replaced with their default values? Or did I get it completely wrong what you tried to point out? Edit Or can only be one default value be replaced at a time?
$\endgroup$
Commented
Sep 11, 2018 at 9:28
UpValue
in your attempt is associated with Times
. I replace scriptcapitalN with just N
for brevity: N[x] + b N[y]
is Plus[N[x], Times[b, N[y]]]
. Times
is present at level 1 of the expression, so MMA checks UpValues
for the symbol Times
. However, N[x] + N[y]
is Plus[N[x], N[y]]
, so MMA has no waying of realizing that it has to apply the UpValue
defined for Times
. So it doesn't even get round to doing that and attempting to substitute default values in the process.
$\endgroup$
a_
andb_
likea_.
andb_.
, otherwise\[ScriptCapitalN][a x + b y]
does not match the pattern ofmultiplier_ \[ScriptCapitalN][a x + b y]
$\endgroup$Times
vs.Plus
was of course wrong. $\endgroup$['\\\\\\[ScriptCapitalN\\]', 'f'],
on line 599 =D $\endgroup$