Таблица над индексами массива

Nov 02 2020

Я хочу обобщить следующую таблицу для суммирования по $s[1], \ldots, s[N]$ а также $t[1], \ldots t[N]$, где сумма каждой переменной превышает $\{-1, 1\}$.

Table[ expr , {s[1], {-1, 1}}, {s[2], {-1, 1}},  {s[3], {-1, 1}}, {t[1], {-1, 1}}, t[2], {-1, 1}}, {t[3], {-1, 1}} ]

Выражение зависит от обоих массивов $s$ а также $t$ каким-то сложным образом.

По сути, вместо того, чтобы записывать суммы по каждому из индексов массива $s[1], s[2], s[3], t[1], t[2], t[3]$, как я могу написать это в общем виде в зависимости от параметра N?

Ответы

4 Alan Nov 02 2020 at 19:47

Я думаю, это касается сути вашего вопроса:

Clear[s, t]
n = 3;
vars = Join[Array[Indexed[s, #] &, n], Array[Indexed[t, #] &, n]];
vals = Tuples[{-1, 1}, 2 n];  (* the possible configs *)
rules = Thread[Rule[vars, #]] & /@ vals;  (* rules linking vars to each config *)
vars /. rules  (* an expression in the vars, at each config *)
3 LukasLang Nov 02 2020 at 18:44

Вот способ без утечки оценки: (т.е. он будет работать, даже если s[1]и т. Д. Имеют значения за пределами Table)

n = 3;
Replace[
  Join[s /@ Hold @@ Range@n, t /@ Hold @@ Range@n],
  v_ :> {v, {-1, 1}},
  1
  ] /.
 Hold[s___] :> Hold@Table[(*remove Hold to evaluate*)
    expr,
    s
    ]
(* Hold[
 Table[expr, {s[1], {-1, 1}}, {s[2], {-1, 1}}, {s[3], {-1, 1}}, {t[
    1], {-1, 1}}, {t[2], {-1, 1}}, {t[3], {-1, 1}}]] *)

Как отмечено в комментарии выше, вам нужно удалить, Holdчтобы таблица оценивалась. Чтобы увидеть, как это работает, я покажу некоторые из отдельных шагов приведенного выше выражения:

(* list of s "variables" *)
s /@ Hold @@ Range@n
(* Hold[s[1], s[2], s[3]] *)

(* combine with t "variables" *)   
Join[s /@ Hold @@ Range@n, t /@ Hold @@ Range@n]
(* Hold[s[1], s[2], s[3], t[1], t[2], t[3]] *)

(* insert the iterator specifications *)
Replace[
 Join[s /@ Hold @@ Range@n, t /@ Hold @@ Range@n],
 v_ :> {v, {-1, 1}},
 1
 ]
(* Hold[{s[1], {-1, 1}}, {s[2], {-1, 1}}, {s[3], {-1, 1}}, {t[
   1], {-1, 1}}, {t[2], {-1, 1}}, {t[3], {-1, 1}}] *)

Если вас не волнуют утечки оценок, этого достаточно:

n = 3;
Hold@Table[expr, ##] & @@ (
  {#, {-1, 1}} & /@ Join[s /@ Range@n, t /@ Range@n]
  )
(* Hold[
 Table[expr, {s[1], {-1, 1}}, {s[2], {-1, 1}}, {s[3], {-1, 1}}, {t[
    1], {-1, 1}}, {t[2], {-1, 1}}, {t[3], {-1, 1}}]] *)

Опять же, вам нужно удалить удержание в вашем фактическом коде.

Вы также можете подумать об использовании, Arrayесли можете изменить способ использования переменных:

n = 3;
Array[f[##] &, ConstantArray[2, n], {-1, 1}]
(* {{{f[-1, -1, -1], f[-1, -1, 1]}, {f[-1, 1, -1], 
   f[-1, 1, 1]}}, {{f[1, -1, -1], f[1, -1, 1]}, {f[1, 1, -1], 
   f[1, 1, 1]}}} *)

Здесь функция fпросто последовательно получает значения s[…]и t[…].

2 cvgmt Nov 03 2020 at 07:11

@Alan дал элегантный способ решить проблему.

Здесь мы просто упоминаем, что исходное выражение:

Table[expr[s1, s2, s3, t1, t2, t3], {s1, {-1, 1}}, {s2, {-1, 1}}, {s3, {-1, 1}}, {t1, {-1,1}}, {t2, {-1, 1}}, {t3, {-1, 1}}]

эквивалентно

Outer[expr, {-1, 1}, {-1, 1}, {-1, 1}, {-1, 1}, {-1, 1}, {-1, 1}]