<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def filter_step(G, covY, pred, yt):
 """Filtering step of Kalman filter. Parameters G: (dy, dx) numpy array mean of Y_t | X_t is G * X_t covX: (dx, dx) numpy array covariance of Y_t | X_t pred: MeanAndCov object predictive distribution at time t Returns ------- pred: MeanAndCov object filtering distribution at time t logpyt: float log density of Y_t | Y_{0:t-1} """

    # data prediction
    data_pred_mean = np.matmul(pred.mean, G.T)
    data_pred_cov = dotdot(G, pred.cov, G.T) + covY
    if covY.shape[0] == 1:
        logpyt = dists.Normal(loc=data_pred_mean,
                              scale=np.sqrt(data_pred_cov)).logpdf(yt)
    else:
        logpyt = dists.MvNormal(loc=data_pred_mean,
                                cov=data_pred_cov).logpdf(yt)
    # filter
    residual = yt - data_pred_mean
    gain = dotdot(pred.cov, G.T, inv(data_pred_cov))
    filt_mean = pred.mean + np.matmul(residual, gain.T)
    filt_cov = pred.cov - dotdot(gain, G, pred.cov)
    return MeanAndCov(mean=filt_mean, cov=filt_cov), logpyt