在Mathematica中可能有内置函数或更好更快的方法
func[l_, g_, f_] := g @@ f @@@ Transpose[{Most[l], Rest[l]}]
可以用来做这样的事情
l = {a, b, c, d}
func[l, Plus, (#1 - #2)^2 &]
我不知道这种功能的正确名称。折叠拉链类型的东西。
更新 很多解决方案。谢谢大家。
使用
Partition[l, 2, 1]
而不是
Transpose[{Most[l], Rest[l]}]
肯定会让它更清晰。
我试图在函数上运行时序,但是我得到了奇怪的结果:
func1[l_, g_, f_] := g @@ f @@@ Transpose[{Most[l], Rest[l]}]
func2[l_, g_, f_] := g @@ f @@@ Partition[l, 2, 1]
func3[l_, g_, f_] := g @@ ListConvolve[{1, 1}, l, {-1, 1}, {}, Times, f]
func4[l_, g_, f_] := g @@ Thread[f[Most@l, Rest@l]]
func5[l_, g_, f_] := g @@ f /@ Partition[l, 2, 1]
func6[l_, g_, f_] := g @@ Thread[f[Most[l], Rest[l]]]
func7[l_, f_, g_] := Inner[f, Sequence @@ Partition[l, Length[l] - 1, 1], g]
func8[l_, g_, f_] := g @@ MapThread[f, Partition[l, Length[l] - 1, 1]]
functions = {func1, func2, func3, func4, func5, func6, func7, func8}
input = Table[ToExpression["x" <> ToString[i]], {i, 1, 1000000}];
inputs = Table[Take[input, i*100000], {i, 1, 10}];
Table[
If[i == j == 0, "",
If[j == 0, functions[[i]],
If[i == 0, Length[inputs[[j]]],
Timing[functions[[i]][inputs[[j]]]][[1]]]]],
{i, 0, Length[functions]}, {j, 0, Length[inputs]}] // Transpose // TableForm
答案 0 :(得分:6)
如果您想要完全复制func
功能的内容,我唯一能想到的就是将Transpose[Most[l],Rest[l]]
替换为Partition
:
func2[l_,g_,f_]:=g@@f@@@Partition[l,2,1]
如果你真的想要“内置”的东西,那么你可以通过攻击来攻击ListConvolve
func3[l_,g_,f_]:=g@@ListConvolve[{1,1},l,{-1,1},{},Times,f]
检查所有这些是否有效:
Through[{func,func2,func3}[l,Plus,(#1-#2)^2&]]
Out[19]= {(a-b)^2+(b-c)^2+(c-d)^2,(a-b)^2+(b-c)^2+(c-d)^2,(a-b)^2+(b-c)^2+(c-d)^2}
最后,如果这是您正在寻找的答案,我建议您按Total[Differences[l]^2]
计算它
Out[14]= (-a+b)^2+(-b+c)^2+(-c+d)^2
答案 1 :(得分:4)
每当你看到像f@@@Transpose[{args}]
这样的内容时,你应该想到Thread[]
。这在The semantics of Mathematica's Thread function中进行了讨论。
所以我能做的最好的就是
func[l_, g_, f_] := g @@ Thread[f[Most[l], Rest[l]]]
但是Most[l], Rest[l]
结构仍然看起来很丑陋且效率低下。可能有一种更有效的方法 - 但也许这可以像在Mathematica中那样紧凑。
答案 2 :(得分:3)
相当于(不是说它更好):
func[l_, g_, f_] := g @@ Thread[f[Most@l, Rest@l]]
或几乎
func[l_, g_, f_] := g @@ f /@ Partition[l, 2, 1]
但最后一个需要
func[l, Plus, (#[[1]] + #[[2]])^2 &]
这显然是次等的
答案 3 :(得分:3)
这不是一个答案,而是一个更好的计时例程的建议。此
timeAvg[func_] := Module[{
x = 0, y = 0, timeLimit = 0.1, p, q,
iterTimes = Power[10, Range[0, 10]]},
Catch[
If[(x = First[Timing[(y++; Do[func, {#}]);]]) > timeLimit,
Throw[{x, y}]
] & /@ iterTimes
] /. {p_, q_} :> p/iterTimes[[q]]
];
Attributes[timeAvg] = {HoldAll};
会很快计算出平均运行时间,例如,
timeAvg@func1[l, Plus, (#1 - #2)^2 &]
为l
尝试不同的长度会得到以下结果
其中N是l
中元素的数量。 Thread[]
是明显的赢家。
答案 4 :(得分:2)
我认为这只是一个广义的内积(广义点积),以Transpose
/ Most
/ Rest
位为模,所以你也可以使用Inner
:
func[lis_, f_, g_] := Inner[f, Sequence@@Partition[list, Length[lis]-1, 1], g]
In[90]:= func[l,Plus,(#-#2)^2&]
Out[90]= (a - b)^2 + (b - c)^2 + (c - d)^2
还有MapThread
,我提到完整性:
func2[lis_, g_, f_] := g @@ MapThread[f, Partition[lis, Length[lis]-1, 1]]
In[94]:= func2[l, Plus, (# - #2)^2 &]
Out[94]= (a - b)^2 + (b - c)^2 + (c - d)^2
如果您总是在列表中产生差异,Differences
或ListConvolve
可能会更快,正如其他人所提到的那样。
与Perl一样,TMTOWTDI in Mathematica也是如此,因为你问题的所有答案都显示出来了!