import%20marimo%0A%0A__generated_with%20%3D%20%220.24.0%22%0Aapp%20%3D%20marimo.App()%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%0A%20%20%20%20return%20(mo%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%3Ca%20href%3D%22https%3A%2F%2Fcolab.research.google.com%2Fgithub%2Fapplejxd%2Fcolaboratory%2Fblob%2Fmaster%2Falgorithm%2Fsort_tracking.ipynb%22%20target%3D%22_parent%22%3E%3Cimg%20src%3D%22https%3A%2F%2Fcolab.research.google.com%2Fassets%2Fcolab-badge.svg%22%20alt%3D%22Open%20In%20Colab%22%2F%3E%3C%2Fa%3E%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20%E3%83%8F%E3%83%B3%E3%82%AC%E3%83%AA%E3%82%A2%E3%83%B3%E6%B3%95%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt_hungarian%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20seaborn%20as%20sns%0A%0A%20%20%20%20%23%20%E8%A1%A8%E7%A4%BA%E3%81%AE%E7%B2%BE%E5%BA%A6%E3%82%92%E8%A8%AD%E5%AE%9A%0A%20%20%20%20np.set_printoptions(precision%3D3%2C%20suppress%3DFalse)%0A%20%20%20%20plt_hungarian.rcParams%5B'figure.figsize'%5D%20%3D%20(5%2C%202)%0A%20%20%20%20np.random.seed(42)%0A%0A%20%20%20%20N%20%3D%204%0A%20%20%20%20A%20%3D%20np.random.rand(N%2C%20N)%0A%20%20%20%20print(%22A%3D%22)%0A%20%20%20%20sns.heatmap(A%2C%20annot%3DTrue%2C%20cmap%3D'coolwarm')%0A%20%20%20%20plt_hungarian.show()%0A%20%20%20%20return%20A%2C%20np%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20https%3A%2F%2Fqiita.com%2Fm__k%2Fitems%2F8e2cb9067ec5d720c30d%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(A%2C%20np)%3A%0A%20%20%20%20def%20step1(mat_)%3A%0A%20%20%20%20%20%20%20%20mat%20%3D%20mat_.copy()%0A%20%20%20%20%20%20%20%20row_min%20%3D%20np.min(mat%2C%20axis%3D1)%5B%3A%2C%20np.newaxis%5D%0A%20%20%20%20%20%20%20%20mat%20%3D%20mat%20-%20row_min%0A%20%20%20%20%20%20%20%20col_min%20%3D%20np.min(mat%2C%20axis%3D0)%20%20%23%20%E5%90%84%E8%A1%8C%E3%81%AE%E6%9C%80%E5%B0%8F%E5%80%A4%E3%82%92%E5%BC%95%E3%81%8F%0A%20%20%20%20%20%20%20%20mat%20%3D%20mat%20-%20col_min%0A%20%20%20%20%20%20%20%20return%20mat%0A%20%20%20%20%20%20%23%20%E5%90%84%E5%88%97%E3%81%AE%E6%9C%80%E5%B0%8F%E5%80%A4%E3%82%92%E5%BC%95%E3%81%8F%0A%20%20%20%20def%20step2(mat)%3A%0A%20%20%20%20%20%20%20%20row_idxs%2C%20col_idxs%20%3D%20np.where(mat%20%3D%3D%200)%0A%20%20%20%20%20%20%20%20zero_idxs%20%3D%20np.array(%5Brow_idxs%2C%20col_idxs%5D).T%0A%20%20%20%20%20%20%20%20check_row%2C%20checl_col%20%3D%20(%5B%5D%2C%20%5B%5D)%0A%20%20%20%20%20%20%20%20for%20elem%20in%20zero_idxs%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20elem%5B0%5D%20not%20in%20check_row%20and%20elem%5B1%5D%20not%20in%20checl_col%3A%20%20%23%20%E5%80%A4%E3%81%8C%200%20%E3%81%AE%E6%88%90%E5%88%86%E3%81%AE%E3%82%A4%E3%83%B3%E3%83%87%E3%83%83%E3%82%AF%E3%82%B9%E3%82%92%E5%8F%96%E5%BE%97%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20check_row.append(elem%5B0%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20checl_col.append(elem%5B1%5D)%0A%20%20%20%20%20%20%20%20success%20%3D%20len(check_row)%20%3D%3D%20mat.shape%5B0%5D%20%20%23%200%20%E6%88%90%E5%88%86%E3%82%92%E5%90%AB%E3%82%80%E8%A1%8C%E3%83%BB%E5%88%97%E3%82%92%E9%87%8D%E8%A4%87%E3%81%AA%E3%81%8F%E3%83%BB%E4%B8%8D%E8%B6%B3%E3%81%AA%E3%81%8F%E9%81%B8%E6%8A%9E%E3%81%A7%E3%81%8D%E3%82%8B%E3%81%8B%0A%20%20%20%20%20%20%20%20return%20(success%2C%20zero_idxs)%0A%0A%20%20%20%20def%20step3(mat%2C%20zero_idxs)%3A%0A%20%20%20%20%20%20%20%20zero_list%20%3D%20zero_idxs%0A%20%20%20%20%20%20%20%20zero_count%20%3D%20%7B%7D%0A%20%20%20%20%20%20%20%20line%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20while%20len(zero_list)%20%3E%200%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20elem%20in%20zero_list%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20r%20%3D%20f'r_%7Belem%5B0%5D%7D'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20c%20%3D%20f'c_%7Belem%5B1%5D%7D'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20zero_count%5Br%5D%20%3D%20zero_count%5Br%5D%20%2B%201%20if%20r%20in%20zero_count%20else%201%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20zero_count%5Bc%5D%20%3D%20zero_count%5Bc%5D%20%2B%201%20if%20c%20in%20zero_count%20else%201%0A%20%20%20%20%20%20%20%20%20%20%20%20max_zero%20%3D%20max(zero_count.items()%2C%20key%3Dlambda%20x%3A%20x%5B1%5D)%5B0%5D%20%20%23%20%E8%A1%8C%E3%83%BB%E5%88%97%E3%81%94%E3%81%A8%E3%81%AB%200%20%E3%81%AE%E6%95%B0%E3%82%92%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%0A%20%20%20%20%20%20%20%20%20%20%20%20line.append(max_zero)%0A%20%20%20%20%20%20%20%20%20%20%20%20rc%2C%20num%20%3D%20max_zero.split('_')%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20rc%20%3D%3D%20'r'%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20zero_list%20%3D%20%5Bv%20for%20v%20in%20zero_list%20if%20str(v%5B0%5D)%20!%3D%20num%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20zero_list%20%3D%20%5Bv%20for%20v%20in%20zero_list%20if%20str(v%5B1%5D)%20!%3D%20num%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20zero_count%20%3D%20%7B%7D%0A%20%20%20%20%20%20%20%20return%20line%20%20%23%20%E6%9C%80%E3%82%82%E5%A4%9A%E3%81%84%E8%A1%8C%E3%83%BB%E5%88%97%E3%82%92%E9%81%B8%E6%8A%9E%0A%0A%20%20%20%20def%20step4(mat%2C%20line)%3A%0A%20%20%20%20%20%20%20%20line_r%2C%20line_c%20%3D%20(%5B%5D%2C%20%5B%5D)%20%20%23%20%E3%82%A4%E3%83%B3%E3%83%87%E3%83%83%E3%82%AF%E3%82%B9%E3%81%AE%E7%95%AA%E5%8F%B7%E3%82%92%E5%8F%96%E5%BE%97%0A%20%20%20%20%20%20%20%20for%20line_name%20in%20line%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20rc%20%3D%20line_name.split('_')%5B0%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20num%20%3D%20int(line_name.split('_')%5B1%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20rc%20%3D%3D%20'r'%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20line_r.append(num)%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20line_c.append(num)%20%20%23%20%E3%82%AF%E3%83%AA%E3%82%A2%0A%20%20%20%20%20%20%20%20line_cut_mat%20%3D%20np.delete(np.delete(mat%2C%20line_r%2C%200)%2C%20line_c%2C%201)%0A%20%20%20%20%20%20%20%20mini%20%3D%20np.min(line_cut_mat)%0A%20%20%20%20%20%20%20%20cross_point%20%3D%20%5B(i%2C%20j)%20for%20i%20in%20line_r%20for%20j%20in%20line_c%5D%0A%20%20%20%20%20%20%20%20non_line_point%20%3D%20%5B(i%2C%20j)%20for%20i%20in%20range(0%2C%20mat.shape%5B0%5D)%20for%20j%20in%20range(0%2C%20mat.shape%5B1%5D)%20if%20i%20not%20in%20line_r%20if%20j%20not%20in%20line_c%5D%0A%20%20%20%20%20%20%20%20for%20pt%20in%20cross_point%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20mat%5Bpt%5D%20%2B%3D%20mini%0A%20%20%20%20%20%20%20%20for%20pt%20in%20non_line_point%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20mat%5Bpt%5D%20-%3D%20mini%0A%20%20%20%20%20%20%20%20return%20mat%0A%0A%20%20%20%20def%20hungarian(mat)%3A%0A%20%20%20%20%20%20%20%20mat%20%3D%20step1(mat)%0A%20%20%20%20%20%20%20%20mat%20%3D%20step1(mat.T).T%0A%20%20%20%20%20%20%20%20while%20True%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20flag%2C%20zero_coordinate%20%3D%20step2(mat)%20%20%23%20step%203%20%E3%81%AE%E8%A1%8C%E3%83%BB%E5%88%97%E3%82%92%E5%89%8A%E9%99%A4%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20flag%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%20%20%23%20%E6%AE%8B%E3%82%8A%E3%81%AE%E8%A6%81%E7%B4%A0%E3%81%A7%E6%9C%80%E3%82%82%E5%B0%8F%E3%81%95%E3%81%84%E3%82%82%E3%81%AE%0A%20%20%20%20%20%20%20%20%20%20%20%20line%20%3D%20step3(mat%2C%20zero_coordinate)%0A%20%20%20%20%20%20%20%20%20%20%20%20mat%20%3D%20step4(mat%2C%20line)%0A%20%20%20%20%20%20%20%20r%2C%20c%2C%20optimal%20%3D%20(%5B%5D%2C%20%5B%5D%2C%20%5B%5D)%20%20%23%20%E7%B8%A6%E3%83%BB%E6%A8%AA%E3%81%AE%E7%B7%9A%E3%81%AE%E4%BA%A4%E5%B7%AE%E7%82%B9%0A%20%20%20%20%20%20%20%20for%20v%20in%20zero_coordinate%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20v%5B0%5D%20not%20in%20r%20and%20v%5B1%5D%20not%20in%20c%3A%20%20%23%20%E7%B8%A6%E3%83%BB%E6%A8%AA%E3%81%AE%E7%B7%9A%E3%81%AB%E3%81%8B%E3%81%8B%E3%82%89%E3%81%AA%E3%81%84%E8%A6%81%E7%B4%A0%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20optimal.append(v)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20r.append(v%5B0%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20c.append(v%5B1%5D)%0A%20%20%20%20%20%20%20%20return%20optimal%0A%20%20%20%20optimal%20%3D%20hungarian(A)%0A%20%20%20%20print(optimal)%20%20%23%20%E7%B8%A6%E6%A8%AA%E3%81%AE%E7%B7%9A%E3%81%8C%E4%BA%A4%E3%82%8F%E3%82%8B%E7%82%B9%20%20%23%20%E6%AE%8B%E3%82%8A%E3%81%AE%E8%A6%81%E7%B4%A0%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%A7%E7%B0%A1%E5%8D%98%E3%81%AB%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%82%82%E3%81%A7%E3%81%8D%E3%82%8B%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(A)%3A%0A%20%20%20%20from%20munkres%20import%20Munkres%0A%0A%20%20%20%20m%20%3D%20Munkres()%0A%20%20%20%20result%20%3D%20m.compute(A)%0A%20%20%20%20print(f%22%7Bresult%3D%7D%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20%E4%BA%8C%E9%87%8D%E6%8C%AF%E3%82%8A%E5%AD%90%E3%81%AE%E3%83%88%E3%83%A9%E3%83%83%E3%82%AD%E3%83%B3%E3%82%B0%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%E4%BA%8C%E9%87%8D%E6%8C%AF%E3%82%8A%E5%AD%90%E3%81%AE%E3%82%BD%E3%83%AB%E3%83%90%E3%83%BC%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(np)%3A%0A%20%20%20%20def%20dp_fmap(x%3A%20np.ndarray%2C%20dt%3A%20float)%3A%0A%20%20%20%20%20%20%20%20theta1%2C%20theta2%2C%20p1%2C%20p2%20%3D%20x%0A%20%20%20%20%20%20%20%20cos%20%3D%20np.cos(theta1%20-%20theta2)%0A%20%20%20%20%20%20%20%20sin%20%3D%20np.sin(theta1%20-%20theta2)%0A%20%20%20%20%20%20%20%20d_theta1%20%3D%20(p1%20-%20cos%20*%20p2)%20%2F%20(2%20-%20cos)%0A%20%20%20%20%20%20%20%20d_theta2%20%3D%20-cos%20%2B%202%20*%20p2%20%2F%20(2%20-%20cos)%0A%20%20%20%20%20%20%20%20g%20%3D%209.8%0A%20%20%20%20%20%20%20%20d_p1%20%3D%20-sin%20*%20d_theta1%20*%20d_theta2%20-%202%20*%20g%20*%20np.sin(theta1)%0A%20%20%20%20%20%20%20%20d_p2%20%3D%20sin%20*%20d_theta1%20*%20d_theta2%20-%20g%20*%20np.sin(theta2)%0A%20%20%20%20%20%20%20%20theta1_next%20%3D%20theta1%20%2B%20d_theta1%20*%20dt%0A%20%20%20%20%20%20%20%20theta2_next%20%3D%20theta2%20%2B%20d_theta2%20*%20dt%0A%20%20%20%20%20%20%20%20p1_next%20%3D%20p1%20%2B%20d_p1%20*%20dt%0A%20%20%20%20%20%20%20%20p2_next%20%3D%20p2%20%2B%20d_p2%20*%20dt%0A%20%20%20%20%20%20%20%20return%20np.array(%5Btheta1_next%2C%20theta2_next%2C%20p1_next%2C%20p2_next%5D)%0A%0A%20%20%20%20def%20dp_hmap(x%3A%20np.ndarray)%3A%0A%20%20%20%20%20%20%20%20theta1%2C%20theta2%2C%20_%2C%20_%20%3D%20x%0A%20%20%20%20%20%20%20%20x1%20%3D%20np.sin(theta1)%0A%20%20%20%20%20%20%20%20y1%20%3D%20-np.cos(theta1)%0A%20%20%20%20%20%20%20%20x2%20%3D%20x1%20%2B%20np.sin(theta2)%0A%20%20%20%20%20%20%20%20y2%20%3D%20y1%20-%20np.cos(theta2)%0A%20%20%20%20%20%20%20%20return%20np.array(%5Bx1%2C%20y1%2C%20x2%2C%20y2%5D)%20%20%23%20%E9%81%8B%E5%8B%95%E9%87%8F%E3%81%AF%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%AA%E3%81%84%0A%0A%20%20%20%20return%20dp_fmap%2C%20dp_hmap%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%E8%BB%8C%E8%B7%A1%E7%94%9F%E6%88%90%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(dp_fmap%2C%20dp_hmap%2C%20np)%3A%0A%20%20%20%20dt%20%3D%200.02%0A%20%20%20%20times%20%3D%20np.arange(0%2C%2010%2C%20dt)%0A%0A%20%20%20%20%23%20%E7%9C%9F%E3%81%AE%E8%BB%8C%E8%B7%A1%0A%20%20%20%20x_list%20%3D%20%5Bnp.array(%5Bnp.pi%2F2%2C%20np.pi%2F2%2C%200%2C%200%5D)%5D%0A%20%20%20%20for%20t%20in%20times%3A%0A%20%20%20%20%20%20%20%20x_list.append(dp_fmap(x_list%5B-1%5D%2C%20dt))%0A%20%20%20%20x_list%20%3D%20np.vstack(x_list)%0A%0A%20%20%20%20%23%20(x1%2C%20x2%2C%20p1%2C%20p2)%20%E3%81%AE%E3%83%8E%E3%82%A4%E3%82%BA%0A%20%20%20%20noise_sigma%20%3D%200.4%0A%20%20%20%20noise%20%3D%20np.random.normal(0%2C%20noise_sigma**2%2C%20(len(x_list)%2C%204))%0A%0A%20%20%20%20x_list%20%3D%20np.array(%5Bdp_hmap(x)%20for%20i%2C%20x%20in%20enumerate(x_list)%5D)%0A%20%20%20%20obs_list%20%3D%20np.array(%5Bx%20%2B%20noise%5Bi%5D%20for%20i%2C%20x%20in%20enumerate(x_list)%5D)%0A%20%20%20%20return%20noise_sigma%2C%20obs_list%2C%20x_list%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%E3%83%91%E3%83%AC%E3%83%83%E3%83%88%E4%BD%9C%E6%88%90%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20from%20matplotlib.colors%20import%20TABLEAU_COLORS%0A%0A%20%20%20%20blue%20%3D%20TABLEAU_COLORS%5B%22tab%3Ablue%22%5D%0A%20%20%20%20orange%20%3D%20TABLEAU_COLORS%5B%22tab%3Aorange%22%5D%0A%20%20%20%20red%20%3D%20TABLEAU_COLORS%5B%22tab%3Ared%22%5D%0A%20%20%20%20return%20blue%2C%20orange%2C%20red%0A%0A%0A%40app.cell%0Adef%20_(blue%2C%20orange%2C%20red)%3A%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt_tracking%0A%0A%20%20%20%20fig%2C%20ax%20%3D%20plt_tracking.subplots()%0A%20%20%20%20ax.set_aspect('equal')%0A%20%20%20%20ax.set_xlim(-2.3%2C%202.3)%0A%20%20%20%20ax.set_ylim(-2.3%2C%201.5)%0A%20%20%20%20traj_plt%2C%20%3D%20ax.plot(%5B%5D%2C%20%5B%5D%2C%20c%3Dblue%2C%20label%3D%22Trajectory%22)%0A%20%20%20%20cur_pos_plt%2C%20%3D%20ax.plot(%0A%20%20%20%20%20%20%20%20%5B%5D%2C%20%5B%5D%2C%20c%3Dorange%2C%20marker%3D%22o%22%2C%20markersize%3D5%2C%0A%20%20%20%20%20%20%20%20label%3D%22Current%20Position%22)%0A%20%20%20%20obs_pos_scat%20%3D%20ax.scatter(%5B%5D%2C%20%5B%5D%2C%20s%3D5%2C%20c%3Dred%2C%20label%3D%22Observation%22)%0A%20%20%20%20ax.legend(loc%3D%22upper%20right%22%2C%20fontsize%3D%22x-small%22)%0A%20%20%20%20return%20ax%2C%20cur_pos_plt%2C%20fig%2C%20obs_pos_scat%2C%20plt_tracking%2C%20traj_plt%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%E3%83%97%E3%83%AD%E3%83%83%E3%83%88%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20ax%2C%0A%20%20%20%20cur_pos_plt%2C%0A%20%20%20%20fig%2C%0A%20%20%20%20mo%2C%0A%20%20%20%20noise_sigma%2C%0A%20%20%20%20obs_list%2C%0A%20%20%20%20obs_pos_scat%2C%0A%20%20%20%20plt_tracking%2C%0A%20%20%20%20red%2C%0A%20%20%20%20traj_plt%2C%0A%20%20%20%20x_list%2C%0A)%3A%0A%20%20%20%20import%20matplotlib.animation%20as%20animation%0A%20%20%20%20from%20matplotlib.patches%20import%20Ellipse%0A%0A%20%20%20%20%23%20%E8%A6%B3%E6%B8%AC%E8%AA%A4%E5%B7%AE%E7%AF%84%E5%9B%B2%0A%20%20%20%20obs_ellipse%20%3D%20Ellipse(%0A%20%20%20%20%20%20%20%20xy%3D(0%2C%201)%2C%20width%3Dnoise_sigma%2C%20height%3Dnoise_sigma%2C%20angle%3D0%2C%0A%20%20%20%20%20%20%20%20color%3Dred%2C%20alpha%3D0.1%2C%20animated%3DTrue)%0A%20%20%20%20ax.add_patch(obs_ellipse)%0A%0A%20%20%20%20def%20anim_callback(i)%3A%0A%0A%20%20%20%20%20%20%20%20ax.set_title(f%22Frame%20%7Bi%7D%22)%0A%0A%20%20%20%20%20%20%20%20traj_plt.set_data(x_list%5B%3Ai%2C%202%5D%2C%20x_list%5B%3Ai%2C%203%5D)%0A%20%20%20%20%20%20%20%20cur_pos_plt.set_data(%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B0%2C%20*x_list%5Bi%2C%20%5B0%2C%202%5D%5D%5D%2C%20%5B0%2C%20*x_list%5Bi%2C%20%5B1%2C%203%5D%5D%5D)%0A%0A%20%20%20%20%20%20%20%20%23%20%E8%A6%B3%E6%B8%AC%E7%82%B9%0A%20%20%20%20%20%20%20%20obs_pos_scat.set_offsets(obs_list%5B%3Ai%2B1%2C%20%5B2%2C%203%5D%5D)%0A%20%20%20%20%20%20%20%20obs_ellipse.set_center(obs_list%5Bi%2C%20%5B2%2C%203%5D%5D)%0A%0A%20%20%20%20skip%20%3D%204%0A%20%20%20%20ani%20%3D%20animation.FuncAnimation(%0A%20%20%20%20%20%20%20%20fig%2C%20anim_callback%2C%20frames%3Drange(0%2C%20len(obs_list)%2C%20skip))%0A%20%20%20%20animation_html%20%3D%20mo.Html(ani.to_jshtml())%0A%20%20%20%20plt_tracking.close(fig)%0A%20%20%20%20return%20(animation_html%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%E6%8F%8F%E7%94%BB%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(animation_html)%3A%0A%20%20%20%20animation_html%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
a0d697269949b535971823161ae80826