2
$\begingroup$

While I use the & all the time when doing a mapping, such as

someFunction[#] &/@ somelist

I don't really understand what it's doing.

I wanted to generate a list of RandomReal numbers. I realize that the RandomReal function itself could create such a list, but I wanted to see how the Array function handled it. So at first I tried:

Array[RandomReal[], 3]

and got

{0.211826[1], 0.211826[2], 0.211826[3]}

Then I tried:

Array[RandomReal[] &, 3]

This gave me what I wanted:

{0.748657, 0.422851, 0.247495}

I also saw that if I tried:

Array[RandomReal[#] &, 3]

It seemed to map RandomReal onto the list {1,2,3} - even though I didn't use /@.

Can someone explain to me what's happening with this syntax? Even though I can use it, I don't understand why, or how it works.

$\endgroup$
  • $\begingroup$ Array[expr, 3] generates {expr[1], expr[2], expr[3]} after evaluating expr, just like Map[expr, Range[3]] as you noticed. If expr is a function, then expr[1] etc. will be evaluated. If expr is RandomReal[], it first evaluates to a random number like 0.211826, which is then used as if the number were a function. You probably wanted Table[RandomReal[], 3]. Table holds its argument, so it will be evaluated three separate times, yielding three different random numbers. (Basically, I'm thinking it's Array that's confusing you, not &, but I could be wrong.) $\endgroup$ – Michael E2 Apr 13 '18 at 17:23
5
$\begingroup$

Array[f,3] is basically equivalent to Map[f,{1,2,3}]. Since Array does not have any Holding attribute, it first evaluates the first argument. Evaluating RandomReal[] yields a single random number. So Array[RandomReal[], 3] does this:

f=RandomReal[]
Map[f,{1,2,3}]

0.211826

{0.211826[1], 0.211826[2], 0.211826[3]}

Next: Array[RandomReal[] &, 3]. Now, we have

f = RandomReal[]&.

FullForm[f] shows that this is f = Function[RandomReal[]]. Function has the HoldAll attribute so that RandomReal[] gets not evaluated until f is called with an argument. So f[1], f[2], f[3] will all yield a different random number (between 0 and 1). Hence Array[RandomReal[]&,3] returns a list of three random numbers.

The third one: Array[RandomReal[#]&, 3]

Well, RandomReal is already a function (not a Function, though) and so f = RandomReal[#]& is equivalent to Array[RandomReal[#1]&, 3]. That means no matter how many arguments you supply to f, it will only use the first one and hand it over to RandomReal. When called with a single argument like in RandomReal[3], RandomReal will return a random number between 0 and 3. So, Array[RandomReal, 3] returns a list of random numbers in which the first one is between 0 and 1, the second one is between 0 and 2, and the third one is between 0 and 3. I use SeedRandom in the following in order to highlight that:

SeedRandom[123]
Array[RandomReal, 3]

{0.455719, 1.95565, 2.82964}

What you probably want is obtaining a list of 3 random numbers between, say, -1 and 1. To this end, you should use the two-argument version of RandomReal:

RandomReal[{-1,1},3]
$\endgroup$
  • $\begingroup$ Thank you - I didn't get that the & basically added function. I see now that If I do Function[RandomReal[]] it gives me what I want. $\endgroup$ – Mitchell Kaplan Apr 13 '18 at 17:29
  • $\begingroup$ You're welcome! $\endgroup$ – Henrik Schumacher Apr 13 '18 at 17:38

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.