Sorry for the spam, but I think that I now at least partially understand what is going on. Running …
CONSTRAINT_STRENGTH = 10
CONSTRAINED_VARIABLE_INDEX = 0
CONSTRAINED_VARIABLE_VALUE = 0.
example_coords = {
'example_coord': ['constrained', 'not_constrained']
}
with pm.Model(coords=example_coords) as example_model:
example_variable = pm.Normal('example_variable', mu=0, sigma=1, dims=("example_coord"))
example_variable = pm.Deterministic('example_variable_constrained', tt.set_subtensor(example_variable[CONSTRAINED_VARIABLE_INDEX], CONSTRAINED_VARIABLE_VALUE))
# example_constraint = pm.Potential("example_constraint", -CONSTRAINT_STRENGTH*pm.math.dot(example_variable[CONSTRAINED_VARIABLE_INDEX]-CONSTRAINED_VARIABLE_VALUE, example_variable[CONSTRAINED_VARIABLE_INDEX]-CONSTRAINED_VARIABLE_VALUE))
example_derived_variable = pm.Deterministic('example_derived_variable', example_variable[0]+1)
trace = pm.sample(10, tune=0, cores=1, chains=1)
gives …
trace.get_values('example_variable')
array([[ 0.49995432, 0.62981397],
[ 0.13149576, -1.00936495],
[-0.107127 , 1.00584761],
[ 1.52122564, 0.79125473],
[ 1.469412 , 0.36296659],
[-0.51670114, -1.73684319],
[ 0.17392252, -1.88342137],
[ 0.21169503, -2.32805658],
[-0.73537455, 1.1358729 ],
[-0.12369345, -1.41137584]])
and …
trace.get_values('example_variable_constrained')
Last executed at 2020-12-10 15:23:33 in 145ms
array([[ 0. , 0.62981397],
[ 0. , -1.00936495],
[ 0. , 1.00584761],
[ 0. , 0.79125473],
[ 0. , 0.36296659],
[ 0. , -1.73684319],
[ 0. , -1.88342137],
[ 0. , -2.32805658],
[ 0. , 1.1358729 ],
[ 0. , -1.41137584]])
and …
trace.get_values('example_derived_variable')
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
So it looks like the variable is being fixed and that using example_variable
later in the model definition gives the expected results.