Как я могу заставить Mathematica связать функцию с двумя переменными в двух списках, используя методы функционального программирования? - PullRequest
4 голосов
/ 02 апреля 2010

Допустим, у меня есть функция f[x_, y_] и два списка l1, l2. Я хотел бы оценить f[x,y] для каждой пары x,y с x в l1 и y в l2, и я хотел бы сделать это без необходимости все пары вида {l1[[i]],l2[[j]]}.

По сути, мне нужно что-то вроде Map [Map [f [# 1, # 2] &, l1], l2], где # 1 принимает значения из l1, а # 2 принимает значения из l2, но это не так работа.

(Мотивация: я пытаюсь реализовать некоторые базовые программы на Haskell в Mathematica. В частности, я хотел бы иметь возможность кодировать программу на Haskell

isMatroid::[[Int]]->Bool
isMatroid b =and[or[sort(union(xs\\[x])[y]'elem'b|y<-ys]|xs<-b,ys<-b, xs<-x]

Я думаю, что смогу сделать все остальное, если смогу разобраться в исходном вопросе, но я бы хотел, чтобы код был похож на Haskell. Будем благодарны за любые предложения по внедрению кода, похожего на Haskell, в Mathematica.)

Ответы [ 3 ]

9 голосов
/ 02 апреля 2010

Чтобы оценить функцию f по всем парам из двух списков l1 и l2, используйте Outer:

In[1]:=  Outer[f, {a,b}, {x,y,z}]
Out[1]:= {{f[a,x],f[a,y],f[a,z]}, {f[b,x],f[b,y],f[b,z]}}

Outer по умолчанию работает на самом низком уровне из предоставленных списков; Вы также можете указать уровень с дополнительным аргументом:

In[2]:=  Outer[f, {{1, 2}, {3, 4}}, {{a, b}, {c, d}}, 1]
Out[2]:= {{f[{1,2},{a,b}], f[{1,2},{c,d}]}, {f[{3,4},{a,b}], f[{3,4},{c,d}]}}

Обратите внимание, что это создает вложенный список; Вы можете Flatten, если хотите.

Мой первоначальный ответ указывал на Thread и MapThread, которые представляют собой два способа применения функции к соответствующим парам из списков, например, MapThread[f,{a,b},{1,2}] == {f[a,1], f[b,2]}.

P.S. Я думаю, что, изучая эти вещи, вы найдете документацию очень полезной. Существует множество общих тематических страниц, например, применение функций к спискам и манипулирование списками . Они обычно связаны с разделом «подробнее» в нижней части конкретной документации. Это значительно облегчает поиск вещей, когда вы не знаете, как они будут называться.

3 голосов
/ 02 апреля 2010

Получить ответ на запрос OP о предложениях по внедрению кода, подобного Haskell, в Mathematica. Вот пара вещей, с которыми вам придется иметь дело:

  • Haskell оценивает лениво, по умолчанию Mathematica - нет, он очень хочет. Вам нужно бороться с Hold [] и его родственниками, чтобы писать лениво оценивающие функции, но это можно сделать. Вы также можете подорвать процесс оценки Mathematica и переделать его с помощью Пролога и Эпилога и тому подобное.
  • Система типов и проверка типов в Haskell, вероятно, более строгие, чем значения по умолчанию в Mathematica, но Mathematica обладает возможностями для реализации строгой проверки типов.

Я уверен, что есть намного больше, но я не очень знаком с Haskell.

0 голосов
/ 02 апреля 2010

В [1]: = список1 = диапазон [1, 5];

In [2]: = list2 = Range [6, 10];

В [3]: = (f @@ #) & / @ Transpose [{list1, list2}]

Out [3] = {f [1, 6], f [2, 7], f [3, 8], f [4, 9], f [5, 10]}

...