To initialize the visualization, you may need to click "Run all initialization cells" above (see button location in figure).
#This code was authored by Alex Shvonski, Copyright 2020 MIT All Rights Reserved.
%matplotlib notebook
import ipywidgets as widgets
from IPython.display import display, clear_output
from ipywidgets import interact, interactive, interactive_output, fixed, IntSlider, HBox, Layout, Output, VBox
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import (MultipleLocator, FormatStrFormatter,
AutoMinorLocator)
from math import pi
#Define functions
###############################################
###############################################
###############################################
#Func1: func and km
def func1(x,L):
f = np.zeros(len(x))
for i in range(len(x)):
x_i = x[i]
if x_i < L/3.:
f[i] = 0.
elif L/3. <= x_i <= 2.*L/3.:
f[i] = 1.
elif x_i > 2.*L/3.:
f[i] = 0.
return f
def func2(x,L):
f = np.zeros(len(x))
for i in range(len(x)):
x_i = x[i]
if x_i < L/2.:
f[i] = 2*x_i/L
elif x_i >= L/2.:
f[i] = 0.
return f
def func3(x,L):
f = np.zeros(len(x))
for i in range(len(x)):
x_i = x[i]
if x_i < L/2.:
f[i] = 2*x_i/L
elif x_i >= L/2.:
f[i] = 2*L-2*x_i/L
return f
def func4(x,L):
f = np.zeros(len(x))
for i in range(len(x)):
x_i = x[i]
if x_i < L/4.:
f[i] = 4*x_i/L
elif L/4. <= x_i <= L/2.:
f[i] = 2.*L-4*x_i/L
elif x_i > L/2.:
f[i] = 0
return f
def func5(x,L):
f = np.zeros(len(x))
for i in range(len(x)):
x_i = x[i]
if x_i < L/4.:
f[i] = 4*x_i/L
elif L/4. <= x_i:
f[i] = (4./3.)*L-4*x_i/(3.*L)
return f
def km_f1(m,L):
result = m*pi/L
return result
#Define Fourier coefficients
###############################################
###############################################
def Am(func,x,L,m):
#this approximates integration
#km =
result = func(x,L)*np.sin(km_f1(m,L)*x)
return 2.*result.sum()/result.size
def mth_term(func,x,L,m):
#km =
result = Am(func,x,L,m)*np.sin(km_f1(m,L)*x)
return result
def fourier_series(func,x,L,N):
f = np.zeros((N+1,len(x)))
#if N==0:
# result =
for i in np.arange(1,N+1,1):
f[i] = mth_term(func,x,L,i)
result = np.sum(f,axis=0)
return result
#Define plot
###############################################
###############################################
fig, ax = plt.subplots(1, 2, figsize=(9.5, 5))
plt.subplots_adjust(left=0.05, bottom=None, right=1, top=None, wspace=None, hspace=1.)
L=1.
x = np.linspace(0., L, 10000)
func=func1
N=5
#############################
#plot1
y_max = max(func(x,L))*1.5
line_1, = ax[0].plot(x, func(x,L),
'k--', lw=2, label="Function")
line_2, = ax[0].plot(x, fourier_series(func,x,L,N),
'c-', lw=3, label="Fourier Sum")
#plot params
ax[0].set_title('Amplitude: $\psi(x,0)$', fontsize=16)
ax[0].set_xlabel('$x/L$', fontsize=16)
ax[0].set_ylim(-0.5,y_max)
ax[0].set_xlim(min(x),max(x))
ax[0].grid(True)
ax[0].legend(loc=1, fontsize=16)
ax[0].xaxis.set_major_locator(MultipleLocator(0.5))
ax[0].yaxis.set_major_locator(MultipleLocator(0.5))
plt.setp(ax[0].get_xticklabels(), fontsize=14)
plt.setp(ax[0].get_yticklabels(), fontsize=14)
#############################
#plot2
line_3, = ax[1].plot(x, mth_term(func,x,L,N),
'r-', lw=2)
#plot params
ax[1].set_title('nth Fourier Component', fontsize=16)
ax[1].set_xlabel('$t$', fontsize=16)
ax[1].set_ylim(-1,1)
ax[1].set_xlim(min(x),max(x))
ax[1].grid(True)
ax[1].xaxis.set_major_locator(MultipleLocator(0.5))
plt.setp(ax[1].get_xticklabels(), fontsize=14)
plt.setp(ax[1].get_yticklabels(), fontsize=14)
#Define plot updater
###############################################
###############################################
def update(func,N):
#plot1
#############################
line_1.set_ydata(func(x,L))
line_2.set_ydata(fourier_series(func,x,L,N))
#plot2
#############################
line_3.set_ydata(mth_term(func,x,L,N))
fig.canvas.draw_idle()
return
#Define control elements
###############################################
###############################################
s1=widgets.Dropdown(
options=[('function-1', func1),('function-2', func2),('function-3', func3),('function-4', func4),('function-5', func5)],
value=func1,
description='Function:')
s2=widgets.IntSlider(
min=1,
max=20,
step=1,
value=15,
layout=Layout(width='600px'),
description='Number of Fourier terms: $N=$',
style = {'description_width': 'initial'})
#Connect controls to plot
###############################################
###############################################
out = interactive_output(update, {'func': s1, 'N': s2})
#Set layout
###############################################
###############################################
box_layout = Layout(display='flex', flex_flow='row', justify_content='space-between', align_items='center')
#Display output
###############################################
###############################################
d = display(HBox([s1, s2], layout=box_layout))
HBox(children=(Dropdown(description='Function:', options=(('function-1', <function func1 at 0x119a6b730>), ('f…
These plots show the Fourier series approximation of different functions. One can select a function, which is shown as a dashed line in Plot 1 (left), and generate a Fourier series of the function (shown as cyan line in Plot 1) by setting the number of terms, $N$, to include in the series. In Plot 2 (right) the amplitude the highest order term, $N$, is shown.
Consider the following questions and possible actions:
#The code in this block includes content from StackOverFlow User: harshil (CC BY-SA 4.0)
#and can be found here: https://stackoverflow.com/questions/27934885/how-to-hide-code-from-cells-in-ipython-notebook-visualized-with-nbviewer
###############################################
###############################################
#Enable hidden code
from IPython.display import HTML
HTML('''<script>
code_show=true;
function code_toggle() {
if (code_show){
$('div.input').hide();
} else {
$('div.input').show();
}
code_show = !code_show
}
$( document ).ready(code_toggle);
</script>
<form action="javascript:code_toggle()"><input type="submit" value="Click here to toggle on/off the raw code."></form>''')