import%20marimo%0A%0A__generated_with%20%3D%20%220.25.2%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%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%20An%C3%A1lise%20dos%20dados%20da%20trajet%C3%B3ria%20da%20bola%3A%20filtragem%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%20Setup%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%20%20%23%20data%20visualization%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%20%20%23%20data%20visualization%0A%20%20%20%20import%20numpy%20as%20np%20%20%23%20algorithms%20and%20convenience%20functions%20for%20scientific%20computing%20with%20Python%0A%20%20%20%20import%20pandas%20as%20pd%20%20%23%20labelled%20tables%20with%20numeric%20and%20string%20data%0A%20%20%20%20import%20scipy%20as%20sp%20%20%23%20collection%20of%20mathematical%20algorithms%20and%20convenience%20functions%20built%20on%20NumPy%0A%20%20%20%20import%20seaborn%20as%20sns%20%20%23%20data%20visualization%0A%20%20%20%20import%20sympy%20%20%23%20symbolic%20programming%0A%20%20%20%20from%20watermark%20import%20watermark%20%20%23%20date%2C%20version%20numbers%20and%20hardware%20information%0A%0A%20%20%20%20print(%0A%20%20%20%20%20%20%20%20watermark(%0A%20%20%20%20%20%20%20%20%20%20%20%20updated%3DTrue%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20current_time%3DTrue%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20current_date%3DTrue%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20machine%3DTrue%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20python%3DTrue%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20iversions%3DTrue%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20globals_%3D%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22numpy%22%3A%20np%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22pandas%22%3A%20pd%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22matplotlib%22%3A%20matplotlib%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22seaborn%22%3A%20sns%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22sympy%22%3A%20sympy%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22scipy%22%3A%20sp%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20)%0A%20%20%20%20return%20np%2C%20pd%2C%20plt%2C%20sns%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%23%20Configura%C3%A7%C3%A3o%20do%20ambiente%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(sns)%3A%0A%20%20%20%20sns.set_context(%22notebook%22%2C%20font_scale%3D1%2C%20rc%3D%7B%22lines.linewidth%22%3A%201%7D)%0A%20%20%20%20sns.set_style(%22whitegrid%22)%0A%20%20%20%20colors%20%3D%20sns.color_palette()%0A%0A%20%20%20%20%23%20Par%C3%A2metros%0A%20%20%20%20g%20%3D%20-9.8%20%20%23%20acelera%C3%A7%C3%A3o%20de%20gravidade%2C%20m%2Fs2%0A%0A%20%20%20%20colors%0A%20%20%20%20return%20(g%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%23%23%23%20Importar%20dados%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(pd)%3A%0A%20%20%20%20%23%20importar%20dados%20da%20internet%0A%20%20%20%20url%20%3D%20(%0A%20%20%20%20%20%20%20%20%22https%3A%2F%2Fraw.githubusercontent.com%2FBMClab%2FBMC%2Frefs%2Fheads%2Fmaster%2Fdata%2Fdados.txt%22%0A%20%20%20%20)%0A%20%20%20%20dados%20%3D%20pd.read_csv(url%2C%20skiprows%3D1%2C%20usecols%3D%5B0%2C%201%2C%202%5D%2C%20sep%3D%22%2C%22)%0A%20%20%20%20print(f%22tamanho%20dos%20dados%3A%20%7Bdados.shape%7D%22)%0A%20%20%20%20dados%0A%20%20%20%20return%20(dados%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%23%23%23%20Plotar%20dados%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(dados%2C%20plt)%3A%0A%20%20%20%20dados.plot(%0A%20%20%20%20%20%20%20%20x%3D%22t%22%2C%0A%20%20%20%20%20%20%20%20y%3D%5B%22x%22%2C%20%22y%22%5D%2C%0A%20%20%20%20%20%20%20%20style%3D%5B%22.%22%2C%20%22.%22%5D%2C%0A%20%20%20%20%20%20%20%20figsize%3D(8%2C%203)%2C%0A%20%20%20%20%20%20%20%20xlabel%3D%22Time%20%5Bs%5D%22%2C%0A%20%20%20%20%20%20%20%20title%3D%22Position%20%5Bm%5D%22%2C%0A%20%20%20%20%20%20%20%20subplots%3DTrue%2C%0A%20%20%20%20)%0A%20%20%20%20plt.show()%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%23%20An%C3%A1lise%20dos%20dados%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%20freq%20%3D%20120%20%20%23%20Hz%0A%20%20%20%20%23%20freq%20%3D%201%20%2F%20np.mean(np.diff(dados.values%5B%3A%2C%200%5D))%0A%20%20%20%20return%20(freq%2C)%0A%0A%0A%40app.cell%0Adef%20_(mo%2C%20np)%3A%0A%20%20%20%20mo.doc(np.gradient)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(dados%2C%20freq%2C%20np)%3A%0A%20%20%20%20%23%20calculate%20velocity%0A%20%20%20%20vx%20%3D%20np.gradient(dados.x%2C%201%20%2F%20freq)%0A%20%20%20%20vy%20%3D%20np.gradient(dados.y%2C%201%20%2F%20freq)%0A%20%20%20%20%23%20calculate%20acceleration%0A%20%20%20%20ax%20%3D%20np.gradient(vx%2C%201%20%2F%20freq)%0A%20%20%20%20ay%20%3D%20np.gradient(vy%2C%201%20%2F%20freq)%0A%20%20%20%20return%20ax%2C%20ay%2C%20vx%2C%20vy%0A%0A%0A%40app.cell%0Adef%20_(ax%2C%20ay%2C%20dados%2C%20vx%2C%20vy)%3A%0A%20%20%20%20dados_deriv%20%3D%20dados.assign(vx%3Dvx%2C%20vy%3Dvy%2C%20ax%3Dax%2C%20ay%3Day)%0A%20%20%20%20dados_deriv%0A%20%20%20%20return%20(dados_deriv%2C)%0A%0A%0A%40app.cell%0Adef%20_(dados_deriv%2C%20plt)%3A%0A%20%20%20%20dados_deriv.plot(%0A%20%20%20%20%20%20%20%20x%3D%22t%22%2C%0A%20%20%20%20%20%20%20%20y%3D%5B%22vx%22%2C%20%22vy%22%5D%2C%0A%20%20%20%20%20%20%20%20style%3D%5B%22.%22%2C%20%22.%22%5D%2C%0A%20%20%20%20%20%20%20%20xlabel%3D%22Time%20%5Bs%5D%22%2C%0A%20%20%20%20%20%20%20%20title%3D%22Velocity%20%5Bm%2Fs%5D%22%2C%0A%20%20%20%20%20%20%20%20subplots%3DTrue%2C%0A%20%20%20%20)%0A%20%20%20%20plt.show()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(dados_deriv%2C%20plt)%3A%0A%20%20%20%20dados_deriv.plot(%0A%20%20%20%20%20%20%20%20x%3D%22t%22%2C%0A%20%20%20%20%20%20%20%20y%3D%5B%22ax%22%2C%20%22ay%22%5D%2C%0A%20%20%20%20%20%20%20%20style%3D%5B%22.%22%2C%20%22.%22%5D%2C%0A%20%20%20%20%20%20%20%20xlabel%3D%22Time%20%5Bs%5D%22%2C%0A%20%20%20%20%20%20%20%20title%3D%22Acceleration%20%5Bm%2Fs%24%5E2%24%5D%22%2C%0A%20%20%20%20%20%20%20%20subplots%3DTrue%2C%0A%20%20%20%20)%0A%20%20%20%20plt.show()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(dados_deriv)%3A%0A%20%20%20%20dados_deriv.mean()%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%20Dados%20s%C3%A3o%20muito%20ruidosos%20para%20estimar%20os%20valores%20da%20velocidade%20e%20acelera%C3%A7%C3%A3o...%0A%0A%20%20%20%20%23%23%20O%20que%20fazer%3F%0A%0A%20%20%20%20%23%23%20Uma%20poss%C3%ADvel%20solu%C3%A7%C3%A3o%3A%20filtrar%20dados%0A%0A%20%20%20%20*%20%5BData%20filtering%20in%20signal%20processing%5D(https%3A%2F%2Fmolab.marimo.io%2Fgithub%2FBMClab%2FBMC%2Fblob%2Fmaster%2Fnotebooks%2Fdata_filtering.py)%0A%20%20%20%20*%20%5BResidual%20analysis%20to%20determine%20the%20optimal%20cutoff%20frequency%5D(https%3A%2F%2Fmolab.marimo.io%2Fgithub%2FBMClab%2FBMC%2Fblob%2Fmaster%2Fnotebooks%2Fresidual_analysis.py)%0A%20%20%20%20*%20Revis%C3%A3o%3A%20%5BBasic%20properties%20of%20signals%5D(https%3A%2F%2Fmolab.marimo.io%2Fgithub%2FBMClab%2FBMC%2Fblob%2Fmaster%2Fnotebooks%2Fsignal_basic_properties.py)%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%23%20Duas%20estrat%C3%A9gias%20para%20filtrar%0A%0A%20%20%20%20Vamos%20usar%20um%20filtro%20Butterworth%20passa-baixas%20de%202%C2%AA%20ordem%2C%20aplicado%20duas%20vezes%20(para%20frente%20e%20para%20tr%C3%A1s%2C%20com%20%60filtfilt%60)%2C%20o%20que%20n%C3%A3o%20introduz%20atraso%20(*zero-lag*).%20Mas%20h%C3%A1%20duas%20maneiras%20de%20combin%C3%A1-lo%20com%20as%20derivadas%3A%0A%0A%20%20%20%20-%20**A.%20Filtrar%20a%20posi%C3%A7%C3%A3o%2C%20depois%20derivar%3A**%20filtrar%20%24y%24%20uma%20%C3%BAnica%20vez%20e%20ent%C3%A3o%20calcular%20%24v_y%24%20e%20%24a_y%24%20a%20partir%20da%20posi%C3%A7%C3%A3o%20filtrada.%0A%20%20%20%20-%20**B.%20Derivar%20e%20filtrar%20a%20cada%20passo%3A**%20calcular%20%24v_y%24%20a%20partir%20da%20posi%C3%A7%C3%A3o%20sem%20filtrar%2C%20filtrar%20%24v_y%24%2C%20calcular%20%24a_y%24%20e%20filtrar%20%24a_y%24%20de%20novo.%0A%0A%20%20%20%20Um%20detalhe%3A%20a%20cada%20passagem%2C%20o%20filtro%20atenua%20a%20pot%C3%AAncia%20na%20frequ%C3%AAncia%20de%20corte%20pela%20metade%2C%20e%20com%20duas%20passagens%20(para%20frente%20e%20para%20tr%C3%A1s)%20ela%20seria%20atenuada%20a%20um%20quarto.%20Por%20isso%20a%20frequ%C3%AAncia%20de%20corte%20informada%20ao%20filtro%20%C3%A9%20corrigida%20pelo%20fator%0A%0A%20%20%20%20%24%24%0A%20%20%20%20C%20%3D%20%5Cleft(2%5E%7B1%2Fn_%7Bpassagens%7D%7D%20-%201%5Cright)%5E%7B1%2F(2%5C%2Cordem)%7D%20%5Capprox%200.802%20%5Cquad%20%5Ctext%7B(2%C2%AA%20ordem%2C%202%20passagens)%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20para%20que%20o%20filtro%20final%20tenha%20de%20fato%20a%20frequ%C3%AAncia%20de%20corte%20desejada.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.function%0Adef%20filtra(x%2C%20freq%2C%20fc%2C%20ordem%3D2)%3A%0A%20%20%20%20%22%22%22Filtro%20Butterworth%20passa-baixas%20com%20atraso%20zero%20(filtfilt).%0A%0A%20%20%20%20A%20frequ%C3%AAncia%20de%20corte%20%C3%A9%20corrigida%20para%20as%20duas%20passagens%20do%20filtro%2C%20de%0A%20%20%20%20modo%20que%20a%20frequ%C3%AAncia%20de%20corte%20final%20seja%20%60fc%60.%0A%20%20%20%20%22%22%22%0A%20%20%20%20from%20scipy%20import%20signal%0A%0A%20%20%20%20C%20%3D%20(2%20**%20(1%20%2F%202)%20-%201)%20**%20(1%20%2F%20(2%20*%20ordem))%20%20%23%200.802%20para%202%C2%AA%20ordem%0A%20%20%20%20b%2C%20a%20%3D%20signal.butter(ordem%2C%20(fc%20%2F%20C)%20%2F%20(freq%20%2F%202)%2C%20btype%3D%22low%22)%0A%20%20%20%20return%20signal.filtfilt(b%2C%20a%2C%20x)%0A%0A%0A%40app.function%0Adef%20estrategia_a(y%2C%20freq%2C%20fc)%3A%0A%20%20%20%20%22%22%22A%3A%20filtra%20a%20posi%C3%A7%C3%A3o%20uma%20vez%2C%20depois%20deriva.%20Retorna%20(yf%2C%20vy%2C%20ay).%0A%0A%20%20%20%20As%20derivadas%20usam%20o%20intervalo%20de%20amostragem%201%2Ffreq.%0A%20%20%20%20%22%22%22%0A%20%20%20%20import%20numpy%20as%20np%0A%0A%20%20%20%20yf%20%3D%20filtra(y%2C%20freq%2C%20fc)%0A%20%20%20%20vy%20%3D%20np.gradient(yf%2C%201%20%2F%20freq)%0A%20%20%20%20ay%20%3D%20np.gradient(vy%2C%201%20%2F%20freq)%0A%20%20%20%20return%20yf%2C%20vy%2C%20ay%0A%0A%0A%40app.function%0Adef%20estrategia_b(y%2C%20freq%2C%20fc)%3A%0A%20%20%20%20%22%22%22B%3A%20deriva%20e%20filtra%20a%20velocidade%2C%20deriva%20e%20filtra%20a%20acelera%C3%A7%C3%A3o.%20Retorna%20(vy%2C%20ay).%0A%0A%20%20%20%20As%20derivadas%20usam%20o%20intervalo%20de%20amostragem%201%2Ffreq.%0A%20%20%20%20%22%22%22%0A%20%20%20%20import%20numpy%20as%20np%0A%0A%20%20%20%20vy%20%3D%20filtra(np.gradient(y%2C%201%20%2F%20freq)%2C%20freq%2C%20fc)%0A%20%20%20%20ay%20%3D%20filtra(np.gradient(vy%2C%201%20%2F%20freq)%2C%20freq%2C%20fc)%0A%20%20%20%20return%20vy%2C%20ay%0A%0A%0A%40app.function%0Adef%20compara_estrategias(dados%2C%20freq%2C%20fc%2C%20g%3D-9.8%2C%20trecho%3Dslice(50%2C%20-20))%3A%0A%20%20%20%20%22%22%22Plota%20a%20velocidade%20e%20a%20acelera%C3%A7%C3%A3o%20vertical%20pelas%20estrat%C3%A9gias%20A%20e%20B.%0A%0A%20%20%20%20Tamb%C3%A9m%20imprime%20a%20m%C3%A9dia%20da%20acelera%C3%A7%C3%A3o%20vertical%20no%20%60trecho%60%20dos%20dados.%0A%20%20%20%20%22%22%22%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20import%20numpy%20as%20np%0A%0A%20%20%20%20t%2C%20y%20%3D%20dados.t.to_numpy()%2C%20dados.y.to_numpy()%0A%20%20%20%20_%2C%20vy_a%2C%20ay_a%20%3D%20estrategia_a(y%2C%20freq%2C%20fc)%0A%20%20%20%20vy_b%2C%20ay_b%20%3D%20estrategia_b(y%2C%20freq%2C%20fc)%0A%20%20%20%20vy_bruto%20%3D%20np.gradient(y%2C%201%20%2F%20freq)%0A%20%20%20%20ay_bruto%20%3D%20np.gradient(vy_bruto%2C%201%20%2F%20freq)%0A%0A%20%20%20%20fig%2C%20axs%20%3D%20plt.subplots(2%2C%201%2C%20sharex%3DTrue%2C%20figsize%3D(9%2C%206))%0A%20%20%20%20axs%5B0%5D.plot(t%2C%20vy_bruto%2C%20%22.%22%2C%20color%3D%220.7%22%2C%20label%3D%22sem%20filtro%22)%0A%20%20%20%20axs%5B0%5D.plot(t%2C%20vy_a%2C%20%22-%22%2C%20linewidth%3D2%2C%20label%3D%22A%3A%20filtra%20a%20posi%C3%A7%C3%A3o%22)%0A%20%20%20%20axs%5B0%5D.plot(t%2C%20vy_b%2C%20%22--%22%2C%20linewidth%3D2%2C%20label%3D%22B%3A%20filtra%20a%20cada%20derivada%22)%0A%20%20%20%20axs%5B0%5D.set_ylabel(%22vy%20%5Bm%2Fs%5D%22)%0A%20%20%20%20axs%5B0%5D.legend(loc%3D%22best%22)%0A%20%20%20%20axs%5B1%5D.plot(t%2C%20ay_bruto%2C%20%22.%22%2C%20color%3D%220.7%22)%0A%20%20%20%20axs%5B1%5D.plot(t%2C%20ay_a%2C%20%22-%22%2C%20linewidth%3D2)%0A%20%20%20%20axs%5B1%5D.plot(t%2C%20ay_b%2C%20%22--%22%2C%20linewidth%3D2)%0A%20%20%20%20axs%5B1%5D.axhline(g%2C%20color%3D%22k%22%2C%20linestyle%3D%22%3A%22%2C%20label%3Df%22g%20%3D%20%7Bg%7D%20m%2Fs%24%5E2%24%22)%0A%20%20%20%20axs%5B1%5D.axvspan(%0A%20%20%20%20%20%20%20%20t%5Btrecho%5D%5B0%5D%2C%20t%5Btrecho%5D%5B-1%5D%2C%20color%3D%220.9%22%2C%20zorder%3D0%2C%20label%3D%22trecho%20da%20m%C3%A9dia%22%0A%20%20%20%20)%0A%20%20%20%20axs%5B1%5D.set_ylim(3%20*%20g%2C%20-g)%0A%20%20%20%20axs%5B1%5D.set_ylabel(%22ay%20%5Bm%2Fs%24%5E2%24%5D%22)%0A%20%20%20%20axs%5B1%5D.set_xlabel(%22Time%20%5Bs%5D%22)%0A%20%20%20%20axs%5B1%5D.legend(loc%3D%22best%22)%0A%20%20%20%20fig.suptitle(f%22Velocidade%20e%20acelera%C3%A7%C3%A3o%20verticais%2C%20filtro%20com%20fc%20%3D%20%7Bfc%3A.1f%7D%20Hz%22)%0A%20%20%20%20plt.tight_layout()%0A%20%20%20%20plt.show()%0A%0A%20%20%20%20print(f%22M%C3%A9dia%20de%20ay%20no%20trecho%2C%20A%3A%20%7Bnp.mean(ay_a%5Btrecho%5D)%3A6.2f%7D%20m%2Fs2%22)%0A%20%20%20%20print(f%22M%C3%A9dia%20de%20ay%20no%20trecho%2C%20B%3A%20%7Bnp.mean(ay_b%5Btrecho%5D)%3A6.2f%7D%20m%2Fs2%22)%0A%20%20%20%20print(f%22M%C3%A9dia%20de%20ay%20no%20trecho%2C%20sem%20filtro%3A%20%7Bnp.mean(ay_bruto%5Btrecho%5D)%3A6.2f%7D%20m%2Fs2%22)%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%23%20Explore%3A%20escolha%20a%20frequ%C3%AAncia%20de%20corte%0A%0A%20%20%20%20Mova%20o%20controle%20abaixo%20e%20observe%20as%20duas%20estrat%C3%A9gias.%20O%20trecho%20sombreado%20%C3%A9%20usado%20para%20calcular%20a%20m%C3%A9dia%20da%20acelera%C3%A7%C3%A3o%20(sem%20os%20extremos%20dos%20dados%2C%20onde%20os%20filtros%20e%20as%20derivadas%20s%C3%A3o%20menos%20confi%C3%A1veis).%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20fc_slider%20%3D%20mo.ui.slider(%0A%20%20%20%20%20%20%20%20start%3D1%2C%0A%20%20%20%20%20%20%20%20stop%3D40%2C%0A%20%20%20%20%20%20%20%20step%3D0.5%2C%0A%20%20%20%20%20%20%20%20value%3D10%2C%0A%20%20%20%20%20%20%20%20show_value%3DTrue%2C%0A%20%20%20%20%20%20%20%20label%3D%22Frequ%C3%AAncia%20de%20corte%20%5BHz%5D%22%2C%0A%20%20%20%20)%0A%20%20%20%20fc_slider%0A%20%20%20%20return%20(fc_slider%2C)%0A%0A%0A%40app.cell%0Adef%20_(dados%2C%20fc_slider%2C%20freq%2C%20g)%3A%0A%20%20%20%20compara_estrategias(dados%2C%20freq%2C%20fc_slider.value%2C%20g%3Dg)%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**Para%20explorar%3A**%0A%0A%20%20%20%201.%20Com%20que%20frequ%C3%AAncia%20de%20corte%20a%20acelera%C3%A7%C3%A3o%20fica%20razoavelmente%20constante%3F%20E%20a%20velocidade%3F%0A%20%20%20%202.%20Para%20uma%20mesma%20frequ%C3%AAncia%20de%20corte%2C%20qual%20das%20estrat%C3%A9gias%2C%20A%20ou%20B%2C%20suaviza%20mais%20a%20acelera%C3%A7%C3%A3o%3F%20Por%20qu%C3%AA%3F%20(Dica%3A%20quantas%20vezes%20cada%20uma%20passa%20o%20filtro%20pelos%20dados%3F)%0A%20%20%20%203.%20O%20que%20acontece%20nos%20extremos%20dos%20dados%2C%20no%20in%C3%ADcio%20e%20no%20fim%20do%20movimento%3F%0A%20%20%20%204.%20Com%20frequ%C3%AAncias%20de%20corte%20muito%20baixas%2C%20a%20m%C3%A9dia%20da%20acelera%C3%A7%C3%A3o%20ainda%20se%20aproxima%20de%20%24g%24%3F%20E%20a%20forma%20da%20curva%3F%0A%20%20%20%205.%20As%20derivadas%20acima%20usam%20o%20intervalo%20de%20amostragem%20%241%2F120%24%20s.%20A%20coluna%20%60t%60%20dos%20dados%20est%C3%A1%20arredondada%20para%20o%20milissegundo%2C%20e%20seus%20intervalos%20alternam%20entre%200.008%20e%200.009%20s.%20Troque%20%601%20%2F%20freq%60%20por%20%60dados.t%60%20em%20%60np.gradient%60%20(nas%20fun%C3%A7%C3%B5es%20%60estrategia_a%60%20e%20%60estrategia_b%60)%20e%20veja%20o%20que%20acontece%20com%20a%20acelera%C3%A7%C3%A3o.%20Por%20que%20a%20estrat%C3%A9gia%20A%20%C3%A9%20mais%20afetada%3F%0A%20%20%20%206.%20Como%20escolher%20a%20frequ%C3%AAncia%20de%20corte%20sem%20saber%20de%20antem%C3%A3o%20qual%20deveria%20ser%20a%20acelera%C3%A7%C3%A3o%3F%20Veja%20a%20seguir.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.function%0Adef%20optcutfreq(y%2C%20freq%3D1%2C%20fclim%3D%5B%5D%2C%20show%3DFalse%2C%20ax%3DNone)%3A%0A%20%20%20%20%22%22%22Automatic%20search%20of%20optimal%20filter%20cutoff%20frequency%20based%20on%20residual%20analysis.%0A%0A%20%20%20%20This%20method%20was%20proposed%20by%20Winter%20in%20his%20book%20%5B1%5D_.%0A%20%20%20%20The%20'optimal'%20cutoff%20frequency%20(in%20the%20sense%20that%20a%20filter%20with%20such%20cutoff%0A%20%20%20%20frequency%20removes%20as%20much%20noise%20as%20possible%20without%20considerably%20affecting%0A%20%20%20%20the%20signal)%20is%20found%20by%20performing%20a%20residual%20analysis%20of%20the%20difference%0A%20%20%20%20between%20filtered%20and%20unfiltered%20signals%20over%20a%20range%20of%20cutoff%20frequencies.%0A%20%20%20%20The%20optimal%20cutoff%20frequency%20is%20the%20one%20where%20the%20residual%20starts%20to%20change%0A%20%20%20%20very%20little%20because%20it%20is%20considered%20that%20from%20this%20point%2C%20it's%20being%0A%20%20%20%20filtered%20mostly%20noise%20and%20minimally%20signal%2C%20ideally.%0A%0A%20%20%20%20Parameters%0A%20%20%20%20----------%0A%20%20%20%20y%20%3A%201D%20array_like%0A%20%20%20%20%20%20%20%20Data%0A%20%20%20%20freq%20%3A%20float%2C%20optional%20(default%20%3D%201)%0A%20%20%20%20%20%20%20%20sampling%20frequency%20of%20the%20signal%20y%0A%20%20%20%20fclim%20%3A%20list%20with%202%20numbers%2C%20optional%20(default%20%3D%20%5B%5D)%0A%20%20%20%20%20%20%20%20limit%20frequencies%20of%20the%20noisy%20part%20or%20the%20residuals%20curve%0A%20%20%20%20show%20%3A%20bool%2C%20optional%20(default%20%3D%20False)%0A%20%20%20%20%20%20%20%20True%20(1)%20plots%20data%20in%20a%20matplotlib%20figure%0A%20%20%20%20%20%20%20%20False%20(0)%20to%20not%20plot%0A%20%20%20%20ax%20%3A%20a%20matplotlib.axes.Axes%20instance%2C%20optional%20(default%20%3D%20None).%0A%0A%20%20%20%20Returns%0A%20%20%20%20-------%0A%20%20%20%20fc_opt%20%3A%20float%0A%20%20%20%20%20%20%20%20%20%20%20%20%20optimal%20cutoff%20frequency%20(None%20if%20not%20found)%0A%0A%20%20%20%20Notes%0A%20%20%20%20-----%0A%20%20%20%20A%20second-order%20zero-phase%20digital%20Butterworth%20low-pass%20filter%20is%20used.%0A%20%20%20%20%23%20The%20cutoff%20frequency%20is%20corrected%20for%20the%20number%20of%20passes%3A%0A%20%20%20%20%23%20C%20%3D%20(2**(1%2Fnpasses)%20-%201)**0.25.%20C%20%3D%200.802%20for%20a%20dual%20pass%20filter.%0A%0A%20%20%20%20The%20matplotlib%20figure%20with%20the%20results%20will%20show%20a%20plot%20of%20the%20residual%0A%20%20%20%20analysis%20with%20the%20optimal%20cutoff%20frequency%2C%20a%20plot%20with%20the%20unfiltered%20and%0A%20%20%20%20filtered%20signals%20at%20this%20optimal%20cutoff%20frequency%20(with%20the%20RMSE%20of%20the%0A%20%20%20%20difference%20between%20these%20two%20signals)%2C%20and%20a%20plot%20with%20the%20respective%0A%20%20%20%20second%20derivatives%20of%20these%20signals%20which%20should%20be%20useful%20to%20evaluate%0A%20%20%20%20the%20quality%20of%20the%20optimal%20cutoff%20frequency%20found.%0A%0A%20%20%20%20Winter%20should%20not%20be%20blamed%20for%20the%20automatic%20search%20algorithm%20used%20here.%0A%20%20%20%20The%20algorithm%20implemented%20is%20just%20to%20follow%20as%20close%20as%20possible%20Winter's%0A%20%20%20%20suggestion%20of%20fitting%20a%20regression%20line%20to%20the%20noisy%20part%20of%20the%20residuals.%0A%0A%20%20%20%20This%20function%20performs%20well%20with%20data%20where%20the%20signal%20has%20frequencies%0A%20%20%20%20considerably%20below%20the%20Nyquist%20frequency%20and%20the%20noise%20is%20predominantly%0A%20%20%20%20white%20in%20the%20higher%20frequency%20region.%0A%0A%20%20%20%20If%20the%20automatic%20search%20fails%2C%20the%20lower%20and%20upper%20frequencies%20of%20the%20noisy%0A%20%20%20%20part%20of%20the%20residuals%20curve%20can%20be%20input%20as%20a%20parameter%20(fclim).%0A%20%20%20%20These%20frequencies%20can%20be%20chosen%20by%20viewing%20the%20plot%20of%20the%20residuals%20(enter%0A%20%20%20%20show%3DTrue%20as%20input%20parameter%20when%20calling%20this%20function).%0A%0A%20%20%20%20It%20is%20known%20that%20this%20residual%20analysis%20algorithm%20results%20in%20oversmoothing%0A%20%20%20%20kinematic%20data%20%5B2%5D_.%20Use%20it%20with%20moderation.%0A%20%20%20%20This%20code%20is%20described%20elsewhere%20%5B3%5D_.%0A%0A%20%20%20%20References%0A%20%20%20%20----------%0A%20%20%20%20..%20%5B1%5D%20Winter%20DA%20(2009)%20Biomechanics%20and%20motor%20control%20of%20human%20movement.%0A%20%20%20%20..%20%5B2%5D%20http%3A%2F%2Fwww.clinicalgaitanalysis.com%2Ffaq%2Fcutoff.html%0A%20%20%20%20..%20%5B3%5D%20https%3A%2F%2Fgithub.com%2Fdemotu%2Foptcutfreq%2Fblob%2Fmaster%2Fdocs%2Foptcutfreq_notebook.py%0A%0A%20%20%20%20Examples%0A%20%20%20%20--------%0A%20%20%20%20%3E%3E%3E%20y%20%3D%20np.cumsum(np.random.randn(1000))%0A%20%20%20%20%3E%3E%3E%20%23%20optimal%20cutoff%20frequency%20based%20on%20residual%20analysis%20and%20plot%3A%0A%20%20%20%20%3E%3E%3E%20fc_opt%20%3D%20optcutfreq(y%2C%20freq%3D1000%2C%20show%3DTrue)%0A%20%20%20%20%3E%3E%3E%20%23%20same%20analysis%20but%20specifying%20the%20frequency%20limits%20and%20plot%3A%0A%20%20%20%20%3E%3E%3E%20optcutfreq(y%2C%20freq%3D1000%2C%20fclim%3D%5B200%2C400%5D%2C%20show%3DTrue)%0A%20%20%20%20%3E%3E%3E%20%23%20It's%20not%20always%20possible%20to%20find%20an%20optimal%20cutoff%20frequency%0A%20%20%20%20%3E%3E%3E%20%23%20or%20the%20one%20found%20can%20be%20wrong%20(run%20this%20example%20many%20times)%3A%0A%20%20%20%20%3E%3E%3E%20y%20%3D%20np.random.randn(100)%0A%20%20%20%20%3E%3E%3E%20optcutfreq(y%2C%20freq%3D100%2C%20show%3DTrue)%0A%0A%20%20%20%20%22%22%22%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20from%20scipy.interpolate%20import%20UnivariateSpline%0A%20%20%20%20from%20scipy.signal%20import%20butter%2C%20filtfilt%0A%0A%20%20%20%20y%20%3D%20np.asarray(y)%0A%20%20%20%20%23%20Correct%20the%20cutoff%20frequency%20for%20the%20number%20of%20passes%20in%20the%20filter%0A%20%20%20%20C%20%3D%200.802%20%20%23%20for%20dual%20pass%3B%20C%20%3D%20(2**(1%2Fnpasses)-1)**0.25%0A%0A%20%20%20%20%23%20signal%20filtering%0A%20%20%20%20freqs%20%3D%20np.linspace((freq%20%2F%202)%20%2F%20100%2C%20(freq%20%2F%202)%20*%20C%2C%20101%2C%20endpoint%3DFalse)%0A%20%20%20%20res%20%3D%20%5B%5D%0A%20%20%20%20for%20fc%20in%20freqs%3A%0A%20%20%20%20%20%20%20%20b%2C%20a%20%3D%20butter(2%2C%20(fc%20%2F%20C)%20%2F%20(freq%20%2F%202))%0A%20%20%20%20%20%20%20%20yf%20%3D%20filtfilt(b%2C%20a%2C%20y)%0A%20%20%20%20%20%20%20%20%23%20residual%20between%20filtered%20and%20unfiltered%20signals%0A%20%20%20%20%20%20%20%20res%20%3D%20np.hstack((res%2C%20np.sqrt(np.mean((yf%20-%20y)%20**%202))))%0A%0A%20%20%20%20%23%20find%20the%20optimal%20cutoff%20frequency%20by%20fitting%20an%20exponential%20curve%0A%20%20%20%20%23%20y%20%3D%20A*exp(B*x)%2BC%20to%20the%20residual%20data%20and%20consider%20that%20the%20tail%20part%0A%20%20%20%20%23%20of%20the%20exponential%20(which%20should%20be%20the%20noisy%20part%20of%20the%20residuals)%0A%20%20%20%20%23%20decay%20starts%20after%203%20lifetimes%20(exp(-3)%2C%2095%25%20drop)%0A%20%20%20%20fclim%20%3D%20np.asarray(fclim)%0A%20%20%20%20if%20not%20len(fclim)%20or%20np.any(fclim%20%3C%200)%20or%20np.any(fclim%20%3E%20freq%20%2F%202)%3A%0A%20%20%20%20%20%20%20%20fc1%20%3D%200%0A%20%20%20%20%20%20%20%20fc2%20%3D%20int(0.95%20*%20(len(freqs)%20-%201))%0A%20%20%20%20%20%20%20%20%23%20log%20of%20exponential%20turns%20the%20problem%20to%20first%20order%20polynomial%20fit%0A%20%20%20%20%20%20%20%20%23%20make%20the%20data%20always%20greater%20than%20zero%20before%20taking%20the%20logarithm%0A%20%20%20%20%20%20%20%20reslog%20%3D%20np.log(%0A%20%20%20%20%20%20%20%20%20%20%20%20np.abs(res%5Bfc1%20%3A%20fc2%20%2B%201%5D%20-%20res%5Bfc2%5D)%20%2B%201000%20*%20np.finfo(float).eps%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20Blog%2C%20Alog%20%3D%20np.polyfit(freqs%5Bfc1%20%3A%20fc2%20%2B%201%5D%2C%20reslog%2C%201)%0A%20%20%20%20%20%20%20%20fcini%20%3D%20np.nonzero(freqs%20%3E%3D%20-3%20%2F%20Blog)%20%20%23%203%20lifetimes%0A%20%20%20%20%20%20%20%20fclim%20%3D%20%5Bfcini%5B0%5D%5B0%5D%2C%20fc2%5D%20if%20np.size(fcini)%20else%20%5B%5D%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20fclim%20%3D%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20np.nonzero(freqs%20%3E%3D%20fclim%5B0%5D)%5B0%5D%5B0%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20np.nonzero(freqs%20%3E%3D%20fclim%5B1%5D)%5B0%5D%5B0%5D%2C%0A%20%20%20%20%20%20%20%20%5D%0A%0A%20%20%20%20%23%20find%20fc_opt%20with%20linear%20fit%20y%3DA%2BBx%20of%20the%20noisy%20part%20of%20the%20residuals%0A%20%20%20%20B%20%3D%20A%20%3D%20None%0A%20%20%20%20if%20len(fclim)%20and%20fclim%5B0%5D%20%3C%20fclim%5B1%5D%3A%0A%20%20%20%20%20%20%20%20B%2C%20A%20%3D%20np.polyfit(freqs%5Bfclim%5B0%5D%20%3A%20fclim%5B1%5D%5D%2C%20res%5Bfclim%5B0%5D%20%3A%20fclim%5B1%5D%5D%2C%201)%0A%20%20%20%20%20%20%20%20%23%20optimal%20cutoff%20frequency%20is%20the%20frequency%20where%20y%5Bfc_opt%5D%20%3D%20A%0A%20%20%20%20%20%20%20%20roots%20%3D%20UnivariateSpline(freqs%2C%20res%20-%20A%2C%20s%3D0).roots()%0A%20%20%20%20%20%20%20%20fc_opt%20%3D%20roots%5B0%5D%20if%20len(roots)%20else%20None%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20fc_opt%20%3D%20None%0A%0A%20%20%20%20if%20show%3A%0A%20%20%20%20%20%20%20%20plot_optcutfreq(y%2C%20freq%2C%20freqs%2C%20res%2C%20fclim%2C%20fc_opt%2C%20B%2C%20A%2C%20ax)%0A%0A%20%20%20%20return%20fc_opt%0A%0A%0A%40app.function%0Adef%20plot_optcutfreq(y%2C%20freq%2C%20freqs%2C%20res%2C%20fclim%2C%20fc_opt%2C%20B%2C%20A%2C%20ax)%3A%0A%20%20%20%20%22%22%22Plot%20results%20of%20the%20optcutfreq%20function%2C%20see%20its%20help.%22%22%22%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20from%20scipy.signal%20import%20butter%2C%20filtfilt%0A%0A%20%20%20%20if%20ax%20is%20None%3A%0A%20%20%20%20%20%20%20%20plt.figure(num%3DNone%2C%20figsize%3D(10%2C%205))%0A%20%20%20%20%20%20%20%20ax%20%3D%20np.array(%5Bplt.subplot(121)%2C%20plt.subplot(222)%2C%20plt.subplot(224)%5D)%0A%0A%20%20%20%20plt.rc(%22axes%22%2C%20labelsize%3D12%2C%20titlesize%3D12)%0A%20%20%20%20plt.rc(%22xtick%22%2C%20labelsize%3D12)%0A%20%20%20%20plt.rc(%22ytick%22%2C%20labelsize%3D12)%0A%20%20%20%20ax%5B0%5D.plot(freqs%2C%20res%2C%20%22b.%22%2C%20markersize%3D9)%0A%20%20%20%20time%20%3D%20np.linspace(0%2C%20len(y)%20%2F%20freq%2C%20len(y))%0A%20%20%20%20ax%5B1%5D.plot(time%2C%20y%2C%20%22g%22%2C%20linewidth%3D1%2C%20label%3D%22Unfiltered%22)%0A%20%20%20%20ydd%20%3D%20np.diff(y%2C%20n%3D2)%20*%20freq**2%0A%20%20%20%20ax%5B2%5D.plot(time%5B%3A-2%5D%2C%20ydd%2C%20%22g%22%2C%20linewidth%3D1%2C%20label%3D%22Unfiltered%22)%0A%20%20%20%20if%20fc_opt%3A%0A%20%20%20%20%20%20%20%20ylin%20%3D%20np.poly1d(%5BB%2C%20A%5D)(freqs)%0A%20%20%20%20%20%20%20%20ax%5B0%5D.plot(freqs%2C%20ylin%2C%20%22r--%22%2C%20linewidth%3D2)%0A%20%20%20%20%20%20%20%20ax%5B0%5D.plot(%0A%20%20%20%20%20%20%20%20%20%20%20%20freqs%5Bfclim%5B0%5D%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20res%5Bfclim%5B0%5D%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22r%3E%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20freqs%5Bfclim%5B1%5D%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20res%5Bfclim%5B1%5D%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22r%3C%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20ms%3D9%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20ax%5B0%5D.set_ylim(bottom%3D0%2C%20top%3D4%20*%20A)%0A%20%20%20%20%20%20%20%20ax%5B0%5D.plot(%5B0%2C%20freqs%5B-1%5D%5D%2C%20%5BA%2C%20A%5D%2C%20%22r-%22%2C%20linewidth%3D2)%0A%20%20%20%20%20%20%20%20ax%5B0%5D.plot(%5Bfc_opt%2C%20fc_opt%5D%2C%20%5B0%2C%20A%5D%2C%20%22r-%22%2C%20linewidth%3D2)%0A%20%20%20%20%20%20%20%20ax%5B0%5D.plot(%0A%20%20%20%20%20%20%20%20%20%20%20%20fc_opt%2C%0A%20%20%20%20%20%20%20%20%20%20%20%200%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22ro%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20markersize%3D7%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20clip_on%3DFalse%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20zorder%3D9%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20label%3D%22%24Fc_%7Bopt%7D%24%20%3D%20%25.1f%20Hz%22%20%25%20fc_opt%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20ax%5B0%5D.legend(fontsize%3D12%2C%20loc%3D%22best%22%2C%20numpoints%3D1%2C%20framealpha%3D0.5)%0A%20%20%20%20%20%20%20%20%23%20Correct%20the%20cutoff%20frequency%20for%20the%20number%20of%20passes%0A%20%20%20%20%20%20%20%20C%20%3D%200.802%20%20%23%20for%20dual%20pass%3B%20C%20%3D%20(2**(1%2Fnpasses)%20-%201)**0.25%0A%20%20%20%20%20%20%20%20b%2C%20a%20%3D%20butter(2%2C%20(fc_opt%20%2F%20C)%20%2F%20(freq%20%2F%202))%0A%20%20%20%20%20%20%20%20yf%20%3D%20filtfilt(b%2C%20a%2C%20y)%0A%20%20%20%20%20%20%20%20ax%5B1%5D.plot(time%2C%20yf%2C%20color%3D%5B1%2C%200%2C%200%2C%200.5%5D%2C%20linewidth%3D2%2C%20label%3D%22Opt.%20filtered%22)%0A%20%20%20%20%20%20%20%20ax%5B1%5D.legend(fontsize%3D12%2C%20loc%3D%22best%22%2C%20framealpha%3D0.5)%0A%20%20%20%20%20%20%20%20ax%5B1%5D.set_title(%22Signals%20(RMSE%20%3D%20%25.3g)%22%20%25%20A)%0A%20%20%20%20%20%20%20%20yfdd%20%3D%20np.diff(yf%2C%20n%3D2)%20*%20freq**2%0A%20%20%20%20%20%20%20%20ax%5B2%5D.plot(%0A%20%20%20%20%20%20%20%20%20%20%20%20time%5B%3A-2%5D%2C%20yfdd%2C%20color%3D%5B1%2C%200%2C%200%2C%200.5%5D%2C%20linewidth%3D2%2C%20label%3D%22Opt.%20filtered%22%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20ax%5B2%5D.legend(fontsize%3D12%2C%20loc%3D%22best%22%2C%20framealpha%3D0.5)%0A%20%20%20%20%20%20%20%20resdd%20%3D%20np.sqrt(np.mean((yfdd%20-%20ydd)%20**%202))%0A%20%20%20%20%20%20%20%20ax%5B2%5D.set_title(%22Second%20derivatives%20(RMSE%20%3D%20%25.3g)%22%20%25%20resdd)%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20ax%5B0%5D.text(%0A%20%20%20%20%20%20%20%20%20%20%20%200.5%2C%0A%20%20%20%20%20%20%20%20%20%20%20%200.5%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Unable%20to%20find%20optimal%20cutoff%20frequency%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20horizontalalignment%3D%22center%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22r%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20zorder%3D9%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20transform%3Dax%5B0%5D.transAxes%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20fontsize%3D12%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20ax%5B1%5D.set_title(%22Signal%22)%0A%20%20%20%20%20%20%20%20ax%5B2%5D.set_title(%22Second%20derivative%22)%0A%0A%20%20%20%20ax%5B0%5D.set_xlabel(%22Cutoff%20frequency%20%5BHz%5D%22)%0A%20%20%20%20ax%5B0%5D.set_ylabel(%22Residual%20RMSE%22)%0A%20%20%20%20ax%5B0%5D.set_title(%22Residual%20analysis%22)%0A%20%20%20%20ax%5B0%5D.grid()%0A%20%20%20%20ax%5B1%5D.set_xlim(0%2C%20time%5B-1%5D)%0A%20%20%20%20ax%5B1%5D.grid()%0A%20%20%20%20ax%5B2%5D.set_xlabel(%22Time%20%5Bs%5D%22)%0A%20%20%20%20ax%5B2%5D.set_xlim(0%2C%20time%5B-1%5D)%0A%20%20%20%20ax%5B2%5D.grid()%0A%20%20%20%20plt.tight_layout()%0A%20%20%20%20plt.show()%0A%0A%0A%40app.cell%0Adef%20_(dados%2C%20freq)%3A%0A%20%20%20%20fc_opt%20%3D%20optcutfreq(dados.y%2C%20freq%3Dfreq%2C%20show%3DTrue)%0A%20%20%20%20fc_opt%0A%20%20%20%20return%20(fc_opt%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%20A%20frequ%C3%AAncia%20de%20corte%20%C3%B3tima%20foi%20calculada%20para%20a%20posi%C3%A7%C3%A3o%20%24y%24%2C%20com%20o%20mesmo%20filtro%20usado%20nas%20duas%20estrat%C3%A9gias%20(Butterworth%20de%202%C2%AA%20ordem%2C%20duas%20passagens%2C%20frequ%C3%AAncia%20corrigida).%20Vejamos%20as%20duas%20estrat%C3%A9gias%20com%20ela%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(dados%2C%20fc_opt%2C%20freq%2C%20g)%3A%0A%20%20%20%20compara_estrategias(dados%2C%20freq%2C%20fc_opt%2C%20g%3Dg)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(dados%2C%20fc_opt%2C%20freq)%3A%0A%20%20%20%20_yf%2C%20_vy_a%2C%20_ay_a%20%3D%20estrategia_a(dados.y%2C%20freq%2C%20fc_opt)%0A%20%20%20%20_vy_b%2C%20_ay_b%20%3D%20estrategia_b(dados.y%2C%20freq%2C%20fc_opt)%0A%20%20%20%20dados_fopt%20%3D%20dados.assign(yf%3D_yf%2C%20vy_A%3D_vy_a%2C%20ay_A%3D_ay_a%2C%20vy_B%3D_vy_b%2C%20ay_B%3D_ay_b)%0A%20%20%20%20dados_fopt%0A%20%20%20%20return%20(dados_fopt%2C)%0A%0A%0A%40app.cell%0Adef%20_(dados_fopt)%3A%0A%20%20%20%20dados_fopt.iloc%5B50%3A-20%2C%5D.mean()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(dados%2C%20np)%3A%0A%20%20%20%20%23%20Model%3A%20y%20%3D%20y0%20%2B%20v0*t%20%2B%201%2F2*g*t%5E2%0A%20%20%20%20%23%20fit%20a%20second%20order%20polynomial%20to%20the%20data%0A%20%20%20%20p%20%3D%20np.polyfit(dados.t%2C%20dados.y%2C%202)%0A%20%20%20%20print(%22g%20%3D%20%250.2f%20m%2Fs2%22%20%25%20(2%20*%20p%5B0%5D))%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%20Refer%C3%AAncias%0A%0A%20%20%20%20-%20Tracker%20Video%20Analysis%20and%20Modeling%20Tool%2C%20http%3A%2F%2Fphyslets.org%2Ftracker%2F%0A%20%20%20%20-%20marimo%2C%20https%3A%2F%2Fmarimo.io%2F%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%20marimo%20as%20mo%0A%0A%20%20%20%20return%20(mo%2C)%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
6a1d976017bba1fa418b434eb97ed7d6