Tabelle über Array-Indizes

Nov 02 2020

Ich möchte die folgende Tabelle auf eine Zusammenfassung verallgemeinern $s[1], \ldots, s[N]$ und $t[1], \ldots t[N]$, wobei jede Variable summiert $\{-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}} ]

Der Ausdruck hängt von beiden Arrays ab $s$ und $t$ auf eine komplizierte Weise.

Grundsätzlich, anstatt die Summen über jeden der Array-Indizes zu schreiben $s[1], s[2], s[3], t[1], t[2], t[3]$, wie kann ich das in Abhängigkeit von einem Parameter N allgemein schreiben?

Antworten

4 Alan Nov 02 2020 at 19:47

Ich denke, das kommt zum Kern oder zu Ihrer Frage:

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

Hier ist ein leckagefreier Auswertungsweg: (dh es funktioniert auch dann, wenn s[1]usw. Werte außerhalb von haben 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}}]] *)

Wie im obigen Kommentar erwähnt, müssen Sie das entfernen Hold, damit die Tabelle ausgewertet wird. Um zu sehen, wie dies funktioniert, zeige ich einige der einzelnen Schritte des obigen Ausdrucks:

(* 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}}] *)

Wenn Sie sich nicht für Bewertungslecks interessieren, reicht dies aus:

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

Auch hier müssten Sie die Sperrung in Ihrem eigentlichen Code entfernen.

Sie können auch in Betracht ziehen, zu verwenden, Arraywenn Sie die Art und Weise ändern können, in der die Variablen verwendet werden:

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

Hier ferhält die Funktion einfach die Werte von s[…]und t[…]nacheinander.

2 cvgmt Nov 03 2020 at 07:11

@ Alan haben einen eleganten Weg gegeben, um das Problem zu lösen.

Hier erwähnen wir nur, dass der ursprüngliche Ausdruck:

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

ist äquivalent zu

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