(I'm repeating some things I said in a comment just for the sake of completeness :) )
Welcome! In general, you shouldn't use For
loops in mathematica, especially when building tables! See Avoiding For Loops. (Its parent post is always useful too!)
It's often better to use Table
or Array
to generate arrays. Table
can use multiple loops, e.g.
t = Table[f[i,j,k,l,m,n,o,p], {i,2}, {j,2}, {k,2}, {l,2}, {m,2}, {n,2}, {o,2}, {p,2}]
Then to get a 16x16 array, you can use ArrayReshape[t, {16, 16}]
, or Flatten
if you need more control over which layer winds up where. (If you're new to Mathematica, note that Mathematica has generally great documentation, which can be accessed by clicking Help at the top-right of the notebook window; lots of further info on e.g. how to use Flatten
in different ways can be found there.)
However, a more concise way is to use Tuples
, then reshape: Tuples[{1, 2}, 8]
will produce a list of all possible combinations, then (if your function takes in 8 arguments) you can apply a function to each of these using f @@@ Tuples[{1, 2}, 8]
(see the docs for Apply
). f @@@ {{a,b,c}, {d,e,g}}
replaces the inner List with your function, and will evaluate to {f[a,b,c], f[d,e,g],}
. (Contrast with Map
(/@
) which prefixes f
to the list itself: f /@ {{a,b,c}, {d,e,g}}
evaluates to {f[{a,b,c}], f[{d,e,g}]}
.)
The definition you included was for takeOpVal[O1_, O2_, O3_, O4_, O5_, O6_, O7_, O8_, U_]
. (Note: the code you included had errors, e.g. O_ 3
instead of O3_
. Make sure these errors aren't present in your actual code!) Seeing as you want to sort of "parametrize" this by U
, I recommed using the following pattern:
takeOpVal[U_][O1_, O2_, O3_, O4_, O5_, O6_, O7_, O8_] := (* ... *)
This behaves the same way in the end, but is more convenient: we can construct takeOpVal[U]
which then behaves like a function that we can apply to sequences of the 8 O
arguments. (If you're familiar, this is Mathematica's built-in version of currying.)
Note that Tuples
works with any list! Tuples[{Bigthing1, Bigthing2, ...}, 8]
will generate all 8-tuples with elements drawn from the list given as a first argument! So we can just use your Translator
list.
(Note: if you're coming from another language, you may be used to using list{i}
for part access as I noticed you did in the post! Remember that here, you use double square brackets: list[[i]]
. See the docs for Part
for more.)
So, to put it all together:
takeOpVal[U_][O1_, O2_, O3_, O4_, O5_, O6_, O7_, O8_] := Tr[KroneckerProduct[O1, O2, O3, O4] . U . KroneckerProduct[O5, O6, O7, O8] . ConjugateTranspose[U]]
Id = IdentityMatrix[2];
Sz = PauliMatrix[3];
Translator = {Id, Sz};
(* U = YourMatrixHere *)
vals = takeOpVal[U] @@@ Tuples[Translator, 8];
ArrayReshape[vals, {16,16}]
There may be technicalities for making this line up with KroneckerProduct
, though. I'm not sure exactly how you want it reshaped. If you'd like to provide more detail, I'd be happy to help further. :)
For
loops in mathematica, especially when building tables! See Avoiding For Loops. (Its parent post is always useful too!) It's often better to useTable
orArray
.Table
can use multiple loops, e.g.t = Table[f[i,j,k,l,m,n,o,p], {i,2}, {j,2}, {k,2}, {l,2}, {m,2}, {n,2}, {o,2}, {p,2}]
. Then to get a 16x16 array, you can useArrayReshape[t, {16, 16}]
, orFlatten
if you need more control over which layer winds up where. $\endgroup$Tuples
, then reshape:Tuples[{1, 2}, 8]
will produce a list of all possible combinations, then (if your function takes in 8 arguments) you can apply a function to each of these usingf @@@ Tuples[{1, 2}, 8]
(see the docs forApply
). If your function takes in a list of 8 values, useMap
instead, e.g.f /@ Tuples[{1,2}, 8]
. Then useArrayReshape
as before on the result. $\endgroup$