4
$\begingroup$

Here is a related question, but not quite what I'm after.

I would like to define a function f[x_] that has the distributive attribute, such that:

f[a+b+c]

f[a]+f[b]+f[c]

Of course I could do

f[Plus[x_,y___]]:=f[x]+f[Plus[y]]

but I suspect that this would be much slower than an actual Attribute. Unfortunately, I cannot find Distributive in the list of allowed attributes.

How should one define such a property to make sure that it performs as efficiently as possible?

$\endgroup$
  • 1
    $\begingroup$ Do you know about Distribute? e.g. Distribute[f[a + b + c]] $\endgroup$ – Mike Honeychurch Feb 14 '18 at 22:59
  • $\begingroup$ @MikeHoneychurch wow, thank you! Good to know! $\endgroup$ – Kagaratsch Feb 14 '18 at 23:31
3
$\begingroup$
f[x__Plus] := Plus @@ (f /@ (List @@ x))

This is also about the same speed as:

f[x__Plus] := Map[f, x]

Which is also about the same speed as:

f[x__Plus] := Distribute[Unevaluated[f[x]]]

You can test the efficiency of this like so:

var = Sum[a[i], {i, 1, 100000}];
AbsoluteTiming[f[var];]

I am reasonably sure there isn't an attribute based solution, and I believe that most of the built-in functions that aren't coded in C rely on pattern matching to manage the distributive property. The trick here is to avoid relying on pattern matching more often than necessary: this splits out every summand in a single replacement.

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.