在Mathematica中映射两个参数函数

时间:2011-05-29 13:44:33

标签: wolfram-mathematica

我想存档:

Map2[f,{a,b,c,d}]
{f[a,b], f[b,c], f[c,d]}

但出于某种原因,我只能想到迭代方法。

功能方式是什么?

编辑:

使用它,就是生成图形示例。如果给出了数字列表,则下面生成它意味着什么的图表,以顺序访问所有节点。

例如:

Map2 = # @@@ Partition[#2, 2, 1] &;
MG[elems_] := Graph[Map2[DirectedEdge, elems]]
nrs = RandomInteger[{1, 15}, 20]
MG[nrs]

{10,13,9,7,13,3,5,1,15,10,15,6,14,3,1,2,11,4,8,5}

径向布局:

enter image description here

6 个答案:

答案 0 :(得分:11)

最简单:

Map2 = # @@@ Partition[#2, 2, 1] &;

或者,可能使用更少的内存,但运行速度稍慢:

Map2[f_, lst_] := Developer`PartitionMap[f @@ # &, lst, 2, 1]

另外,请注意与DifferencesAccumulate相关的内容。


其他方式:

Inner[#, Most@#2, Rest@#2, List] &

请注意,在这一个List中可能是一个不同的功能。

MapThread[#, {Most@#2, Rest@#2}] &

Most@MapThread[#, {#2, RotateLeft@#2}] &

Rest@MapThread[#, {RotateRight@#2, #2}] &

Table[# @@ #2[[i ;; i + 1]], {i, Length@#2 - 1}] &

现在,时间安排。我将使用Timo's timeAvg

f1 = # @@@ Partition[#2, 2, 1] &;
f2[f_, lst_] := Developer`PartitionMap[f @@ # &, lst, 2, 1]
f3 = Inner[#, Most@#2, Rest@#2, List] &;
f4 = MapThread[#, {Most@#2, Rest@#2}] &;
f5 = Most@MapThread[#, {#2, RotateLeft@#2}] &;
f6 = Table[# @@ #2[[i ;; i + 1]], {i, Length@#2 - 1}] &;

timings = 
  Table[
   list = RandomReal[99, 10^i];
   func = Plus;
   timeAvg[#[func, list]] & /@ {f1, f2, f3, f4, f5, f6},
   {i, 6}
  ];

TableForm[timings, 
 TableHeadings -> {10^Range@6, {"f1", "f2", "f3", "f4", "f5", "f6"}}]

ListLogPlot[timings\[Transpose], Joined -> True]

enter image description here

enter image description here

表格左侧的数字是每次运行的实数列表的长度。

请注意,图表是对数的。

以下是处理最长列表时使用的内存字节数(1,000,000):

enter image description here


完成上述时间后,我发现我可以通过取消f6Apply)来加快@@的速度。它现在显然是较长列表中最快的。我不会将它添加到上面的表中,因为它已经足够广泛了,但这是函数及其时间:

f7 = Table[#2[[i]] ~#~ #2[[i + 1]], {i, Length@#2 - 1}] &;

enter image description here

答案 1 :(得分:9)

正如Mathematica cookbook映射中所解释的,可以使用ListConvole函数优雅地解决移动子列表上的函数:

Map2[f_, l_List] := ListConvolve[{1, 1}, l, {-1, 1}, {}, #2 &, f]

In[11]:= Map2[f, {a, b, c, d}]
Out[11]= {f[a, b], f[b, c], f[c, d]}

Mr.Wizard在这里,按照sakra的要求添加比较时间。

enter image description here

enter image description here

答案 2 :(得分:7)

我喜欢:

Map2[f_, l_List]:= MapThread[f, {Most@l, Rest@l}]

In[988]:= Map2[f,{a,b,c,d}]
Out[988]= {f[a,b],f[b,c],f[c,d]}

答案 3 :(得分:6)

我最近重新阅读了您的问题并看到了您的Graph[ ]申请。

我认为这样做的自然方式是:

f[l_] := Graph[Thread[Most@l -> Rest@l]]

所以

f[{10, 13, 9, 7, 13, 3, 5, 1, 15, 10, 15, 6, 14, 3, 1, 2, 11, 4, 8, 5}]  

enter image description here

答案 4 :(得分:2)

遵循belisarius的主导,并解决您的Graph申请,这应该更快一点:

f = Inner[Rule, Most@#, Rest@#, Composition[Graph, List]] &;

答案 5 :(得分:0)

哇,我看到了其他解决方案,它们看起来相当复杂和混淆。这很容易理解,至少如果你喜欢更实用的方法:

MapApplyImpl[fun_] := Function[{args}, Apply[fun, args]]
MapApply[fun_, argList_] := Map[MapApplyImpl[fun], argList]

和一个用法示例:

ff := Function[{t, phi}, t*phi]
MapApply[ff, {{0, Pi/4}, {(Pi/4)/(10^3) , 0}, {(2*Pi/(10^3)), 
   Pi/4}}]