Подтвердить что ты не робот

Отображение двух аргументов в 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

4b9b3361

Ответ 1

Проще всего:

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

Или, возможно, используя меньше памяти, но немного медленнее:

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

Кроме того, помните Differences и Accumulate, которые связаны.


Другие способы:

Inner[#, [email protected]#2, [email protected]#2, List] &

Обратите внимание, что в этом List может быть другой функцией.

MapThread[#, {[email protected]#2, [email protected]#2}] &

[email protected][#, {#2, [email protected]#2}] &

[email protected][#, {[email protected]#2, #2}] &

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

Теперь, тайминги. Я воспользуюсь Timo timeAvg.

f1 = # @@@ Partition[#2, 2, 1] &;
f2[f_, lst_] := Developer`PartitionMap[f @@ # &, lst, 2, 1]
f3 = Inner[#, [email protected]#2, [email protected]#2, List] &;
f4 = MapThread[#, {[email protected]#2, [email protected]#2}] &;
f5 = [email protected][#, {#2, [email protected]#2}] &;
f6 = Table[# @@ #2[[i ;; i + 1]], {i, [email protected]#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^[email protected], {"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


После выполнения вышеописанных таймингов я обнаружил, что быстрее f6 можно сделать, исключив Apply (@@). Теперь он является самым быстрым в более длинных списках. Я не добавлю его в таблицу выше, потому что это уже достаточно широко, но вот функция и ее тайминги:

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

enter image description here

Ответ 2

Как объяснено в кулинарная книга Mathematica отображение функции над движущимся подсписком может быть элегантно решено с помощью 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 здесь, добавляя сравнительные тайминги, как того требует сакра.

enter image description here

enter image description here

Ответ 4

Недавно я перечитал ваш вопрос и увидел ваше приложение Graph[ ].

Я думаю, что естественный способ сделать это:

f[l_] := Graph[Thread[[email protected] -> [email protected]]]

Итак,

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

Ответ 5

Следуя примеру belisarius и обращаясь к вашему приложению Graph, это должно быть немного быстрее:

f = Inner[Rule, [email protected]#, [email protected]#, Composition[Graph, List]] &;

Ответ 6

Ничего себе, я видел другие решения, и они кажутся довольно сложными и запутанными. Это намного проще понять, по крайней мере, если вам нравится более функциональный подход:

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}}]