4

For most functions in Mathematica, passing them a list will call the function on each element of the list. For example:

ExampleFunction1[x_] := x + 1
ExampleFunction1[{1, 2, 3}] 
(* {2, 3, 4} *)

But things change when you use Max[]. For example if I have this function:

ExampleFunction2[x_] := Max[x, 4] 

If I pass this a single number x, it will return either x or 4, whichever is larger, but, as documented, if i pass it a list like this:

ExampleFunction2[{1, 3, 7}] 

It will return 7. Instead I'd like it to return { 4, 4, 7}.

How can I make my function so that Max uses an element of a list as its argument instead of the entire list?

Artes
  • 57,212
  • 12
  • 157
  • 245
David
  • 213
  • 1
  • 4

2 Answers2

7

Plus is Listable while Max is not , look at Attributes :

Attributes @ Max
{Flat, NumericFunction, OneIdentity, Orderless, Protected}

Attributes is Listable as well so this will be more informative : Attributes@{Plus, Max, Attributes}.

Moreover :

ExampleFunction2[x_] := Max[x, 4]
Attributes @ ExampleFunction2
{}

In order to make your function ExampleFunction2 working as you'd like you can set Attributes to it using SetAttributes (it won't change Attributes of Max) :

SetAttributes[ ExampleFunction2, Listable]
Attributes @ {ExampleFunction2, Max}
{{Listable}, {Flat, NumericFunction, OneIdentity, Orderless, Protected}}

then it works nicely :

ExampleFunction2[{1, 3, 7}]
{4, 4, 7}
Artes
  • 57,212
  • 12
  • 157
  • 245
  • Alternatively, Block[{Max}, SetAttributes[Max, Listable]; etc] – Rojo Oct 21 '12 at 20:29
  • @Rojo just remember that will fail with packed arrays, e.g. x = Developer`ToPackedArray@{1, 2, 3, 4, 5, 6, 7}; Block[{Max}, SetAttributes[Max, Listable]; Max[x, 4] ] returns 7. (Yes, I could have used Range but I want to make packing explicit.) – Mr.Wizard Oct 21 '12 at 20:35
  • @Mr.Wizard, true, bad memory. I hope that get's fixed in V9 and I hope V9 happens some time soon – Rojo Oct 21 '12 at 20:41
6

If you want to use Max just map it over the function:

ExampleFunction2[x_] := Max[#, 4] & /@ x

ExampleFunction2[{1,3,7}]

(*{4,4,7}*)

The only catch here, is you want your argument to be a list.

Also, if you have a multi-dimensional list, try:

ExampleFunction3[x_] := Map[Max[#, 4] &, x, {First@Dimensions@x}]

ExampleFunction3[{{1, 3, 7}, {2, 4, 8}}]

(*{{4, 4, 7}, {4, 4, 8}}*)
kale
  • 10,922
  • 1
  • 32
  • 69