Fixing the value of one or more stochastic parameters at arbitrary indices after creating an array of parameters using dims/coords

Thanks to the community for making and supporting this package!

I would like to take advantage of the coords/dims keywords for creating arrays of stochastic parameters, but I’d also like to then be able to fix the value of one or more of the parameters in the array. I’ve managed to fix the value of a single parameter at the start of the array using something like

tt.concatenate(np.array([0.,]), pm.Normal(…, shape=len(example_dim)-1))

but is there a more flexible way to accomplish this?

Much appreciated,
Nick

Have you looked at using tt.set_subtensor yet?

1 Like

Yes, I was able to do what I needed with:

example_tensor = tt.set_subtensor(example_tensor[example_idx], 0.)

Thanks for the suggestion!

Upon closer inspection, what I was trying (using set_subtensor) doesn’t seem to be working. Have you tried something like this before @ckrapu? Running the following …

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 = 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))
    trace = pm.sample(10, tune=0, cores=1, chains=1)

gives …

trace.get_values('example_variable')

array([[-0.81615723, -0.83618503],
       [-0.022699  ,  0.67725928],
       [-0.11114975,  1.15123057],
       [ 0.14072193, -0.80481674],
       [ 0.2730177 , -1.43949344],
       [ 0.26197892, -0.81105021],
       [-0.94527977, -1.28695858],
       [-0.71159907, -1.33909117],
       [ 0.54736533,  1.5955785 ],
       [ 1.2836827 , -0.48124044]])

I can approximately constrain the variable using the commented code, but I’d rather be able to set it to a fixed value. Any tips?

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.