Tabla sobre índices de matriz

Nov 02 2020

Quiero generalizar la siguiente tabla a una suma de $s[1], \ldots, s[N]$ y $t[1], \ldots t[N]$, donde cada variable suma más $\{-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}} ]

La expresión depende de ambas matrices $s$ y $t$ de alguna manera complicada.

Básicamente, en lugar de escribir las sumas sobre cada uno de los índices de matriz $s[1], s[2], s[3], t[1], t[2], t[3]$, ¿cómo puedo escribir esto de forma general en función de un parámetro N?

Respuestas

4 Alan Nov 02 2020 at 19:47

Creo que esto llega al núcleo de tu pregunta:

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

Aquí hay una forma libre de fugas de evaluación: (es decir, funcionará incluso si, s[1]etc.tienen valores fuera de 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}}]] *)

Como se señaló en el comentario anterior, deberá eliminar el Holdpara permitir que la tabla se evalúe. Para ver cómo funciona esto, muestro algunos de los pasos individuales de la expresión anterior:

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

Si no le importan las fugas de evaluación, esto es suficiente:

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

Nuevamente, deberá eliminar la retención en su código real.

También podría considerar usar Arraysi puede cambiar la forma en que se usan las variables:

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

Aquí, la función fsimplemente obtiene los valores de s[…]y t[…]en secuencia.

2 cvgmt Nov 03 2020 at 07:11

@Alan ha dado una forma elegante de resolver el problema.

Aquí solo mencionamos que la expresión original:

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

es equivalente a

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