5
$\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$
2
  • 1
    $\begingroup$ Do you know about Distribute? e.g. Distribute[f[a + b + c]] $\endgroup$ Commented Feb 14, 2018 at 22:59
  • $\begingroup$ @MikeHoneychurch wow, thank you! Good to know! $\endgroup$ Commented Feb 14, 2018 at 23:31

1 Answer 1

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.

$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.