【问题标题】:Mathematica's puzzling interpretation of #^2 & /@ Range[n]Mathematica 对#^2 & /@ Range[n] 的令人费解的解释
【发布时间】:2011-10-14 15:05:28
【问题描述】:

我对 Mathematica 对以下问题的回应感到困惑:

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

似乎连 Mathematica (8.0) 都不相信它刚才说的话:

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

对正在发生的事情有什么想法吗?

编辑:

这个问题的原始上下文如下。我写过

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

由于 n 将非常大(2^50),我想我可以通过将其重写为来节省时间:

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

回想起来,这可能不是一个好主意。 (我本可以使用 Module 只“计算”一次 Range。)

【问题讨论】:

  • 关于 edit 部分 - 恐怕你找不到一台内存足够容纳Range[2^50] 的机器。你真的需要所有这些数字吗?
  • @Leonid。不是同时。我想我可以通过使用Sum 循环并保持差异的总和。
  • 您是否将 Range[5^2] 与 Range[5]^2 混淆了?至于 2^50,“列昂尼德说的话”。
  • @David 我明白了。如果您只需要差的总和,那么大块移动会更快,比如几百万个数字左右。或者,或者,您可以将循环编译为“C”。但是,我做了一些实验,似乎即使对于 10^4 个第一个整数,你也需要大约 0.5 秒。双向。瓶颈似乎在 Prime 中 - 功能本身。是否可以手动更快地实现它们(例如,使用Compile,或者用 C 编写并加载为 dll),我不知道,但是,要为您的数字工作,它们必须 非常快得多
  • @LeonidShifrin 幕后的 FactorInteger 是瓶颈。对于该大小范围内的数字,我怀疑除非使用类似的方法但更好地调整启发式方法,否则会获得很多收益。用于截止。可能感兴趣(巧合的是两天前):lists.apple.com/archives/scitech/2011/Oct/msg00009.html

标签: wolfram-mathematica range


【解决方案1】:

由于n 未定义,Range[n] 对其自身求值。因此,Map 作用于它就像作用于任何其他符号头,将你的函数映射到它的元素上 - 这里只是 n

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

编辑

在您的编辑中解决问题 - 对于数字 nRange 评估为一个列表,您会得到预期的结果(即Range[5]^2。这完全取决于评估的顺序。要得到Range[5^2],你可以使用#^2&/@Unevaluated[Range[5]],在这种情况下,一切都会像上面的符号n一样发生)。事实上,Range 在非数字输入上发出错误消息。此外,它与问题相切,但 #^2& 之类的函数是 Listable,您不必映射它们。

【讨论】:

  • @Mr.向导 我现在在 mma 标记中回答了 200 个问题,但其中 1 个是社区 wiki。生活很艰难...感谢您的支持。
  • 我明白了。我们将期待再延长一点。
  • 我从您与someHead 的示例中得知,问题不在于头部Range,而在于n。我同意你关于RangeListable 的观点。
  • @yoda 一如既往,事实很简单。我与领先的爆米花供应商签订了 SO 标签的合同,仅此而已。
  • @DavidCarraher 我指的是 Leonid 的评论,即他与爆米花供应商勾结,这就是为什么他不断删除他在 Stack Overflow 上的答案,进一步推迟了他不可避免的金徽章,从而让我们大家继续我们座位的边缘,导致我们为了迎接重要的日子而消耗更多的爆米花,导致爆米花销量增加,最终将回到他的口袋里。呸!那是一团糟。
【解决方案2】:

有点离题,但您可以通过重新定义 FactorInteger 来提高速度,然后每个输入只调用一次。

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

例子:

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

丹尼尔·利希特布劳

【讨论】:

  • +1 这些结果真让我吃惊。我的想法正好相反!
  • @DavidCarraher [你的意思是 pdigg2===pdiff1???] 说真的,让我吃惊的是它们似乎是 4 倍而不是 2 倍。我已经确认(至少在几个案例中)PrimeOmega 和 PrimeNu 都准确地调用了 FactorInteger 一次,所以我不明白为什么第一次要慢 4 倍。即使我颠倒顺序也会发生这种情况,所以它在任何方面都不是缓存现象。
猜你喜欢
  • 1970-01-01
  • 2010-10-01
  • 2012-10-31
  • 2012-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-07
  • 2020-10-30
相关资源
最近更新 更多