How do I set a time-varying observation intercept in a state-space model

Hello,
How do I set a time-varying observation intercept in a state-space model? According to the comments on this question, it’s supported. I want to do this instead of using the RegressionComponent because I have a fairly complex deterministic function that I want to subtract off from the endogenous variable. The example below is substantially simplified. Are there any examples of 2d time-varying parameters I can look at?

If I understand this correctly you should it should be possible to add it by specifying a two-dimensional observation intercept with the first-dimension being time. Originally, I was trying to modify with the structural class. I was able to get a time-varying observation covariance to work by adding a third dimension. To simplify the code, I modified the the example notebook AutoRegressiveThree(PyMCStateSpace) .

class AutoRegressiveThree(PyMCStateSpace):
    def __init__(self):
        k_states = 3  # size of the state vector x
        k_posdef = 1  # number of shocks (size of the state covariance matrix Q)
        k_endog = 1  # number of observed states
        self.time_dim = 100

        super().__init__(k_endog=k_endog, k_states=k_states, k_posdef=k_posdef)

    def make_symbolic_graph(self):
        x0 = self.make_and_register_variable("x0", shape=(3,))
        P0 = self.make_and_register_variable("P0", shape=(3, 3))
        ar_params = self.make_and_register_variable("ar_params", shape=(3,))
        sigma_x = self.make_and_register_variable("sigma_x", shape=())
        beta = self.make_and_register_variable("beta", shape=())
        time_trend = self.make_and_register_variable('time_trend', shape=(self.time_dim,))

        self.ssm["transition", :, :] = np.eye(3, k=-1)
        self.ssm["selection", 0, 0] = 1
        self.ssm["design", 0, 0] = 1

        self.ssm["initial_state", :] = x0
        self.ssm["initial_state_cov", :, :] = P0
        self.ssm["transition", 0, :] = ar_params
        self.ssm["state_cov", :, :] = sigma_x
        self.ssm['obs_cov', :, :] = beta * time_trend

    @property
    def param_names(self):
        return ["x0", "P0", "ar_params", "sigma_x", 'beta', 'time_trend']

The model is here

ar3 = AutoRegressiveThree()
with pm.Model() as mod:
    x0 = pm.Deterministic("x0", pt.arange(3, dtype="float"))
    P0 = pm.Deterministic("P0", pt.eye(3) * 10.0)
    ar_params = pm.Deterministic("ar_params", pt.as_tensor_variable([10.0, 11.0, 12.0]))
    sigma_x = pm.Deterministic("sigma_x", pt.as_tensor_variable(13.0, dtype="float64"))
    beta = pm.Deterministic("beta", pt.as_tensor_variable(14.0, dtype='float64'))
    time_trend = pm.Deterministic("time_trend", pt.arange(100).astype('float64'))

    ar3._insert_random_variables()
``

Looking at the shape  `ar3.unpack_statespace()[-2].shape.eval()` we get `array([1, 1])` instead of `array([100, 1])` as expected.   Any help would be great appreciated.

@

Hello! @jessegrabowski! You appear to be the resident expert on state space models. Do you know how to make the observation intercept time-varying? Any thoughts you’d have would be much appreciated!

Thanks!
Paul