code: def test_linear_rts():
      """for a linear model the Kalman filter and UKF should produce nearly
      identical results.
  
      Test code mostly due to user gboehl as reported in GitHub issue #97, though
      I converted it from an AR(1) process to constant velocity kinematic
      model.
      """
      dt = 1.0
      F = np.array([[1.0, dt], [0.0, 1]])
      H = np.array([[1.0, 0.0]])
  
      def t_func(x, dt):
          F = np.array([[1.0, dt], [0.0, 1]])
          return np.dot(F, x)
  
      def o_func(x):
          return np.dot(H, x)
  
      sig_t = 0.1  # peocess
      sig_o = 0.0001  # measurement
  
      N = 50
      X_true, X_obs = [], []
  
      for i in range(N):
          X_true.append([i + 1, 1.0])
          X_obs.append(i + 1 + np.random.normal(scale=sig_o))
  
      X_true = np.array(X_true)
      X_obs = np.array(X_obs)
  
      oc = np.ones((1, 1)) * sig_o**2
      tc = np.zeros((2, 2))
      tc[1, 1] = sig_t**2
  
      tc = Q_discrete_white_noise(dim=2, dt=dt, var=sig_t**2)
      points = MerweScaledSigmaPoints(n=2, alpha=0.1, beta=2.0, kappa=1)
  
      ukf = UnscentedKalmanFilter(
          dim_x=2, dim_z=1, dt=dt, hx=o_func, fx=t_func, points=points
      )
      ukf.x = np.array([0.0, 1.0])
      ukf.R = np.copy(oc)
      ukf.Q = np.copy(tc)
      s = Saver(ukf)
      s.save()
      s.to_array()
  
      kf = KalmanFilter(dim_x=2, dim_z=1)
      kf.x = np.array([[0.0, 1]]).T
      kf.R = np.copy(oc)
      kf.Q = np.copy(tc)
      kf.H = np.copy(H)
      kf.F = np.copy(F)
  
      mu_ukf, cov_ukf = ukf.batch_filter(X_obs)
      x_ukf, _, _ = ukf.rts_smoother(mu_ukf, cov_ukf)
  
      mu_kf, cov_kf, _, _ = kf.batch_filter(X_obs)
      x_kf, _, _, _ = kf.rts_smoother(mu_kf, cov_kf)
  
      # check results of filtering are correct
      kfx = mu_kf[:, 0, 0]
      ukfx = mu_ukf[:, 0]
      kfxx = mu_kf[:, 1, 0]
      ukfxx = mu_ukf[:, 1]
  
      dx = kfx - ukfx
      dxx = kfxx - ukfxx
  
      # error in position should be smaller then error in velocity, hence
      # atol is different for the two tests.
      assert np.allclose(dx, 0, atol=1e-7)
      assert np.allclose(dxx, 0, atol=1e-6)
  
      # now ensure the RTS smoothers gave nearly identical results
      kfx = x_kf[:, 0, 0]
      ukfx = x_ukf[:, 0]
      kfxx = x_kf[:, 1, 0]
      ukfxx = x_ukf[:, 1]
  
      dx = kfx - ukfx
      dxx = kfxx - ukfxx
  
      assert np.allclose(dx, 0, atol=1e-7)
      assert np.allclose(dxx, 0, atol=1e-6)
      return ukf
  
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  from math import cos, sin
  import matplotlib.pyplot
  import numpy.random
  from numpy.random import randn
  from numpy import asarray
  import numpy
  from pytest import approx
  import scipy.linalg
  from scipy.spatial.distance import mahalanobis
  from filterpy.kalman import ExtendedKalmanFilter
  from filterpy.kalman import UnscentedKalmanFilter
  from filterpy.kalman import unscented_transform, MerweScaledSigmaPoints, JulierSigmaPoints, SimplexSigmaPoints, KalmanFilter
  from filterpy.common import Q_discrete_white_noise, Saver
  import filterpy.stats
label_desc: Use image node_id 17 for calling a global function with example usage: test_linear_rts() and returns: ukf, np, np