Tabel di atas indeks array
Saya ingin menggeneralisasi tabel berikut menjadi penjumlahan $s[1], \ldots, s[N]$ dan $t[1], \ldots t[N]$, di mana setiap variabel berjumlah $\{-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}} ]
Ekspresi bergantung pada kedua larik $s$ dan $t$ dengan cara yang rumit.
Pada dasarnya, alih-alih menuliskan jumlah pada setiap indeks array $s[1], s[2], s[3], t[1], t[2], t[3]$, bagaimana saya bisa menulis ini secara umum tergantung pada parameter N?
Jawaban
Saya pikir ini menjadi inti atau pertanyaan Anda:
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 *)
Berikut adalah cara evaluasi-kebocoran gratis: (yaitu akan bekerja bahkan jika s[1]dll memiliki nilai di luar 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}}]] *)
Seperti disebutkan dalam komentar di atas, Anda harus menghapus Holdagar tabel dapat mengevaluasi. Untuk melihat bagaimana ini bekerja, saya menunjukkan beberapa langkah individual dari ekspresi di atas:
(* 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}}] *)
Jika Anda tidak peduli dengan kebocoran evaluasi, ini sudah cukup:
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}}]] *)
Sekali lagi, Anda harus menghapus penangguhan di kode Anda yang sebenarnya.
Anda juga dapat mempertimbangkan untuk menggunakan Arrayjika Anda dapat mengubah cara variabel digunakan:
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]}}} *)
Di sini, fungsinya fhanya mendapatkan nilai dari s[…]dan t[…]secara berurutan.
@Alan telah memberikan cara yang elegan untuk menyelesaikan masalah tersebut.
Di sini kami hanya menyebutkan ekspresi aslinya:
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}}]
setara dengan
Outer[expr, {-1, 1}, {-1, 1}, {-1, 1}, {-1, 1}, {-1, 1}, {-1, 1}]