array[K > 1 ? J : 0] unit_vector[K > 1 ? K : 2] u;
Ignoring the logic in the code above there any way to create a unit vector for model parameters as is possible in Stan like above?
Chatgpt suggested:
u_raw =pm.Flat("u_raw", shape=K)
# Normalize the vector to have unit length
u_unit = u_raw / pm.math.sqrt(pm.math.sum(u_raw**2))
# Add a deterministic node to keep track of the unit vector
u = pm.Deterministic('unit_vector', u_unit)
It appears to work for multiple regression simulate example but samples terrible on a spline type model.
Thank you for any response in advance.
In PyMC you don’t usually think about parameters but distributions. If you want a unit vector you would probably start with a Dirichlet prior and go from there.
Flat by itself won’t really sample well since it’s an improper prior. That ChatGPT is from examples that show how Stan language relates to PyMC, but is not really a good suggestion how you should go about writing PyMC models.
Usually it’s better to think how you would generate synthetic data and write that as your model.
It’s not clear what you mean by “unit vector”. Do you mean the norm of the parameter vector is 1? In that case, which norm? Do you mean that the vector is on a simplex (i.e. all the values sum to 1?).
If you mean the latter, @ricardoV94 suggestion applies. You can also sample from whatever prior you wish, then push the values through pm.math.softmax
to enforce the sum-to-1 constraint.
If the meaning was the first, you can divide the draws from your prior (whatever it happens to be) by pt.linalg.norm(x)
, choosing whichever norm floats your boat.
In either case, the advice to think about your model as a generative process (rather than a collection of functional contrivances) is very good council.