Mathematica's puzzling interpretation of #^2 & /@ Range[n]
I'm puzzled by Mathematica's responses to the following:
ClearAll[n]
#^2 & /@ Range[n]
#^2 & /@ Range[n] // StandardForm
It seems that even Mathematica (8.0) doesn't believe what it has just said:
#^2 & /@ Range[5]
Range[5^2]
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 Modu开发者_JAVA百科le to 'compute' the Range only once.)
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.
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
精彩评论