3

I'm puzzled by Mathematica's responses to the following:

ClearAll[n]
#^2 & /@ Range[n]
#^2 & /@ Range[n] // StandardForm

Range1

It seems that even Mathematica (8.0) doesn't believe what it has just said:

#^2 & /@ Range[5]
Range[5^2]

Range2

Any thoughts about what is happening?

Edit:

The original context for this question was the following. I had written

PrimeOmega[Range[n]] - PrimeNu[Range[n]]

and since n was going to be very large (2^50), I thought I might save time by rewriting it as:

 PrimeOmega[#] - PrimeNu[#] &/@Range[n]

Thinking back, that probably wasn't such a good idea. (I could have used Module to 'compute' the Range only once.)

DavidC
  • 3,056
  • 1
  • 20
  • 30
  • 1
    Regarding the *edit* part - I am afraid you won't find a machine with enough memory to hold `Range[2^50]`. Do you really need *all* those numbers, and also at the same time? – Leonid Shifrin Oct 14 '11 at 15:43
  • @Leonid. Not at the same time. I suppose I could loop and keep a running total of the difference, say, by using `Sum`. – DavidC Oct 14 '11 at 16:09
  • Are you perhaps confusing Range[5^2] for Range[5]^2? As for 2^50, "What Leonid said". – Daniel Lichtblau Oct 14 '11 at 16:12
  • @David I see. If you only need the total of the difference, it will be faster to move in large chunks, say a few millions numbers or so. Or, alternatively, you can compile a loop to "C". But, I did a few experiments, and it seems that even for 10^4 first integers, you need about 0.5 sec. both ways. The bottleneck seems in the Prime - functions themselves. Whether or not one can implement them much faster by hand (say, using `Compile`, or writing in C and loading as dll), I don't know, but, to work for your numbers, they must be *very much* faster. – Leonid Shifrin Oct 14 '11 at 16:19
  • 2
    @LeonidShifrin It is FactorInteger behind the scenes that is the bottleneck. For numbers in that size range I doubt one will gain much unless it is by using similar methods but better tuning heuristics e.g. for cut-offs. Possibly of interest (coincidently from just two days ago): http://lists.apple.com/archives/scitech/2011/Oct/msg00009.html – Daniel Lichtblau Oct 14 '11 at 16:39
  • @Daniel Thanks for the explanation and the link. Pretty interesting. – Leonid Shifrin Oct 14 '11 at 16:44
  • @Daniel I was curious whether `PrimeOmega` and `PrimeNu` could work without having to first doing a complete `FactorInteger`. Your answer suggests they do need to know all of the factors. – DavidC Oct 14 '11 at 18:07
  • @DavidCarraher Right. I am not aware of any way to count prime factors in an integer, with or without multiplicity, other than actually finding the factorization. – Daniel Lichtblau Oct 14 '11 at 18:56
  • @Daniel I suppose only by magic, perhaps? – DavidC Oct 14 '11 at 19:01

2 Answers2

15

Since n is undefined, Range[n] evaluated to itself. Therefore, Map acts on it as on any other symbolic head, mapping your function on its elements - here it is just n

In[11]:= #^2 & /@ someHead[n]
Out[11]= someHead[n^2]

EDIT

Addressing the question in your edit - for numeric n, Range evaluates to a list all right, and you get the expected result (which is, Range[5]^2. It is all about the order of evaluation. To get Range[5^2], you could have used #^2&/@Unevaluated[Range[5]], in which case everything happens just like for symbolic n above) . In fact, Range issues an error message on non-numeric input. Also, it is tangential to the question, but functions like #^2& are Listable, and you don't have to map them.

Leonid Shifrin
  • 22,449
  • 4
  • 68
  • 100
  • @Mr. Wizard I have now 200 questions answered in mma tag, but 1 is community wiki. Life is tough... thanks for the upvote. – Leonid Shifrin Oct 14 '11 at 15:19
  • I see. We keep the anticipation just a little longer. – Mr.Wizard Oct 14 '11 at 15:20
  • I gather from your example with `someHead` that that issue lies not with the head, `Range`, but rather with `n`. I take your point about `Range` being `Listable`. – DavidC Oct 14 '11 at 15:26
  • @David, `Range` is indeed `Listable`, but I think the point is rather that `Power` is `Listable` and therefore `#^2&` is too. – Mr.Wizard Oct 14 '11 at 15:28
  • You know you could've gotten the badge a month ago if you just undeleted all your deleted, correct answers, right? – abcd Oct 14 '11 at 15:28
  • @David Yes, the example was just to show that this is what `Map` does, for a general expression. Most of the time, we use `Map` with lists, so it is easy to forget that it is defined on general expressions, for which it works in the same way as for lists (think about `FullForm`). For example, `Map[#^2&,a+b+c]` gives `{a^2+b^2+c^2}`. – Leonid Shifrin Oct 14 '11 at 15:30
  • @yoda Yes, I sure do. But I have certain rules regarding what to keep as an answer, and they are more important (for me) than getting a badge by a certain date. Call it stupid if you like :) – Leonid Shifrin Oct 14 '11 at 15:32
  • No no, by no means is it stupid and I respect you for that :) I'm merely referring to you keeping all of us at the edges of our seats with our popcorn bags now almost empty. It's like the classic frog in a well: two steps up, one step down ;) – abcd Oct 14 '11 at 15:35
  • @David Indeed, I meant what Mr.Wizard explained. – Leonid Shifrin Oct 14 '11 at 15:37
  • 1
    @yoda As always, the truth is simple. I am on the contract with the leading popcorn supplier to our SO tag, that's all. – Leonid Shifrin Oct 14 '11 at 15:39
  • @Mr.Wizard I added some context to the problem. – DavidC Oct 14 '11 at 15:40
  • @yoda. Please let me in on your thinking. – DavidC Oct 14 '11 at 16:11
  • 3
    @DavidCarraher I was referring to Leonid's comment that he's in cahoots with the popcorn suppliers, which is why he keeps deleting his answers on [so], further delaying his inevitable Gold badge, thereby keeping us all on the edge of our seats, leading us to consume more popcorn in anticipation of the big day, causing an increase in popcorn sales, which will eventually make its way back into his pocket. Phew! That was a mess. – abcd Oct 14 '11 at 16:22
  • @Leonid I think your counting is wrong. You already have 200 non-wiki answers: try http://stackoverflow.com/search?q=user%3A565518+wiki%3A0 ... your badge is going to be processed tonight – Dr. belisarius Oct 14 '11 at 17:38
  • @belisarius One of them is not in mma :) Hover on his mma 1.2k sign and it gives you the split – abcd Oct 14 '11 at 17:40
  • @yoda I'd NEVER thought that was an option :) – Dr. belisarius Oct 14 '11 at 17:48
  • @belisarius I wish. B.t.w., what was not an option? Me answering in the other tag, my affiliation with popcorn suppliers, or that hovering on the rep shows the split? – Leonid Shifrin Oct 14 '11 at 18:06
  • @Leonid Your affiliation with popcorn suppliers is obvious. The rest is unbelievable. – Dr. belisarius Oct 14 '11 at 18:13
6

Slightly off topic, but you can improve the speed by redefining in terms of FactorInteger, which then is only called once per input.

f1[n_] := PrimeOmega[Range[n]] - PrimeNu[Range[n]]
f2[n_] := With[{fax=FactorInteger[#]}, Total[fax[[All,2]]]-Length[fax]]& /@ Range[n]

Example:

In[27]:= Timing[pdiff1 = f1[2^20];]
Out[27]= {37.730264, Null}

In[28]:= Timing[pdiff2 = f2[2^20];]
Out[28]= {9.364576, Null}

In[29]:= pdiff1===pdiff2
Out[29]= True

Daniel Lichtblau

Daniel Lichtblau
  • 6,854
  • 1
  • 23
  • 30
  • +1 These results really surprised me. I would have thought just the opposite! – DavidC Oct 14 '11 at 18:09
  • 1
    @DavidCarraher [You mean pdigg2===pdiff1???] In seriousness, what surprises me is that they seem to be a factor of 4 rather than 2 apart. I have confirmed (for at least a couple of cases) that PrimeOmega and PrimeNu each call FactorInteger exactly one time, so I do not see why that first is 4x slower. And it happens even if I reverse the order, so it is not a caching phenomenon in any respect. – Daniel Lichtblau Oct 14 '11 at 18:58