Tabelle über Array-Indizes
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
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 *)
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.
@ 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}]