Issues Implementing Pure Function

Thanks in advance for any assistance you may be able to provide. I'm new to Mathematica and running into issues creating a usable function from the code seen below. For context, all of this code works as intended, outside of the implementation of the pure function itself (see last 2-3 lines):

ClearAll["Global*"]

n = 2;

Do[θpsi[i] = RandomReal[π/2], {i, 1, (2^n) - 1}];
Do[ϕpsi[i]  =   RandomReal[2 π], {i, 1, (2^n) - 1}];

For[i = 0, i <= 2^n, i++,
Which[
i == 1, ψ[i] =  {Cos[θpsi[i]]};,
i != 1 &&
i != 2^n, ψ[
i] = {Product[Sin[θpsi[j]], {j, 1, i - 1}]*
Cos[θpsi[i]]*E^(I*ϕpsi[i - 1])};,
i == 2^n , ψ[
i] = {Product[Sin[θpsi[j]], {j, 1, i - 1}]*E^(
I*ϕpsi[i - 1])};
](*Which*)
](*For*)

ψ = Array[ψ, 2^n]

ϕState[
i_] := {{Cos[Subscript[θ,
i]]}, {Sin[Subscript[θ, i]]*E^(I*Subscript[ϕ, i])}};

kronk = Fold[KroneckerProduct];
seperableStates = Table[ϕState[i], {i, 1, n}];
Φ = kronk[seperableStates];

x = (ConjugateTranspose[ψ].Φ)[[1, 1]]

(* Generate objective function *)
f = Function[{θ1, θ2, ϕ1, ϕ2}, x];

f[1, 2, 3, 4]



My goal is to take the result of x = (ConjugateTranspose[ψ].Φ)[[1, 1]] and turn it into a user-friendly function that can be fed inputs, as seen on the last two lines.

Am I on the right track here? If not, how can I improve upon this code? I'm still trying to figure out Mathematica in general (recent convert from MATLAB), so any general feedback would be appreciated as well.

Cheers!

The problem with your definition of f is x is an expression that uses 2 subscripted symbols θ and ϕ, but f is a function of 4 symbols θ1, ... . Here is a definition of f that works (for n=2)

f = x /. {Subscript[θ, 1] -> #1, Subscript[θ, 2] -> #2,
Subscript[ϕ, 1] -> #3, Subscript[ϕ, 2] -> #4} &;

f[1, 2, 3, 4]


This definition of f can be generalized for other values of n as follows:

Clear[g]
g = Function@Evaluate[x /. Flatten@
Table[{Subscript[θ, k] -> Slot[k],
Subscript[ϕ, k] -> Slot[n + k]}, {k, n}]];

g[1, 2, 3, 4]


By the way, anyone who uses subscripts should be aware of what is said about them at these links: well-behaved indexed variables, sidenote on using Subscript, and avoid using subscripts

• Thank you for all of this information. After reading through the links you provided, it seems like subscripts are pesky in Mathematica, to say the least. Regarding the code you've created for pure function g, it appears as if it does the following: Generates a table of theta and phi values, replacing subscripts with a workable index for the pure function input. Then, it flattens out the table, and evaluates x with respect to the newly defined theta and phi variables to generate the pure function itself. (On the right track?). Thanks again for your time.
– Jim
Jun 17, 2020 at 12:56

In addition to the issue of subscripts, which I recommend avoiding, there is an issue of substitution within a Function as this requires the parameter Symbols to be literally present in the body:

x = a + b * c;

f = Function[{a,b,c}, x];

f[1, 2, 3]

a + b c      (* substitution did not occur *)


This construct using a Block analog addresses both points:

SetAttributes[ssFuntion, HoldAll]

ssFuntion[p : {__Subscript}, body_] :=
InternalLocalizedBlock[p, p = {##}; body] &


Usage:

f = ssFuntion[{Subscript[θ, 1], Subscript[θ, 2], Subscript[ϕ, 1], Subscript[ϕ, 2]}, x];

f[1, 2, 3, 4]

0.306819 + 0.138836 I


Reference:

• Thank you for this explanation and the associated references, Mr.Wizard. I wasn't aware of the Block analog option, which looks to be another useful solution to this problem. Mathematica seems to be a totally different beast when compared to MATLAB - lots to learn! :)
– Jim
Jun 17, 2020 at 13:03