def nondiagonal_interactive(T, eigenvalues, **options):
initial_xy = options.get("initial_state", None)
state_vars = options.get("state_vars", ("X", "Y"))
rsmax = 10
tmax = 50
lambda1, lambda2 = eigenvalues
D = diagonal_matrix(RDF, eigenvalues)
M = matrix(RDF, T*D*~T).round(4)
if initial_xy is None:
initial_rs = vector([initchoice(lambda1, rsmax), initchoice(lambda2, rsmax)])
initial_xy = vector([round(x,3) for x in T * initial_rs])
else:
initial_rs = vector([round(x, 3) for x in ~T * vector(RDF, initial_xy)])
solution_rs = solution_r = solution_s = solution_xy = []
dont_update = False
def update(rt, st, rst, xyt, show_eigen, show_grid, axis1max, axis2max):
if dont_update or len(solution_rs) == 0:
return
rsmax = ceil(axis1max / abs(np.array(T).flatten()).min())
p1 = plot_graph_paper(T, show_vectors=show_eigen, show_axes=show_eigen,
show_grid=show_grid, gridlines=(rsmax,rsmax),
xyrange=(axis1max,axis1max))
p1 += list_plot(solution_xy[:xyt+1], size=30, color="black", zorder=10)
p1 += list_plot(solution_xy[:xyt+1], plotjoined=True, color="lightblue", zorder=5)
if show_eigen:
p1 += list_plot(solution_r[:rt+1], size=30, color="red")
p1 += list_plot(solution_s[:st+1], size=30, color="green")
p2 = list_plot(solution_rs[:rst+1], size=30, color="black", zorder=10)
p2 += list_plot(solution_rs[:rst+1], plotjoined=True, color="lightblue", zorder=5)
p2 += list_plot(solution_rs[:rt+1] * (1,0), size=30, color="red")
p2 += list_plot(solution_rs[:st+1] * (0,1), size=30, color="green")
if show_grid:
p1 += line((solution_r[xyt], solution_xy[xyt], solution_s[xyt]), color="gray")
p1 += point(solution_r[xyt], size=50, color="red")
p1 += point(solution_s[xyt], size=50, color="green")
p2 += line((solution_rs[rst] * (1,0), solution_rs[rst], solution_rs[rst] * (0,1)),
color="gray")
p2 += point(solution_rs[rst] * (1,0), size=50, color="red")
p2 += point(solution_rs[xyt] * (0,1), size=50, color="green")
p1.set_axes_range(xmin=-axis1max, xmax=axis1max, ymin=-axis1max, ymax=axis1max)
p2.set_axes_range(xmin=-axis2max, xmax=axis2max, ymin=-axis2max, ymax=axis2max)
p1.axes_labels(["$%s$" % label for label in state_vars])
p2.axes_labels(("$R$", "$S$"))
p1.set_aspect_ratio(1)
p2.set_aspect_ratio(1)
both = multi_graphics([(p1, (0, 0.25, 0.57, 0.57)), (p2, (0.43, 0.25, 0.57, 0.57))])
both.show(figsize=12)
def change_initial_rs(change):
nonlocal dont_update, solution_rs, solution_r, solution_s, solution_xy
initial_rs = change["new"].strip("()[]").split(",")
try:
initial_rs = vector([float(x) for x in initial_rs])
except:
return
solution_rs = np.array([D^t * initial_rs for t in range(tmax+1)], dtype=float)
solution_r = [initial_rs[0] * lambda1^t * T.column(0) for t in range(tmax+1)]
solution_s = [initial_rs[1] * lambda2^t * T.column(1) for t in range(tmax+1)]
solution_xy = [a + b for a, b in zip(solution_r, solution_s)]
dont_update = True
rt.value = 0
st.value = 0
rst.value = 0
xyt.value = 1
dont_update = False
xyt.value = 0
def change_initial_xy(change):
initial_xy = change["new"].strip("()[]").split(",")
try:
initial_xy = vector([float(x) for x in initial_xy])
except:
return
state_rs.value = str(vector([round(x, 3) for x in ~T * initial_xy]))
p2b = str.maketrans("()", "[]")
label = ((r"$ \begin{bmatrix} %s_{t+1} \\ %s_{t+1} \end{bmatrix} = " % state_vars) +
latex(M) + (r"\begin{bmatrix} %s_t \\ %s_t \end{bmatrix} \qquad " % state_vars) +
r"\vec{v}_1 = " + latex(T[:,0]).translate(p2b) + r" \qquad " +
(r"\text{with } \lambda_1 = %.2f \qquad" % lambda1) +
r"\vec{v}_2 = " + latex(T[:,1]).translate(p2b) + r" \qquad " +
(r"\text{with } \lambda_2 = %.2f $" % lambda2) )
equation = HTMLMath(label)
layout = Layout(width="250px", margin="0px 0px 0px 0px")
xyt = IntSlider(min=0, max=tmax, layout=layout, description="Sol'n (left):")
rst = IntSlider(min=0, max=tmax, layout=layout, description="Sol'n (right):")
rt = IntSlider(min=0, max=tmax, layout=layout, description="R steps:")
st = IntSlider(min=0, max=tmax, layout=layout, description="S steps:")
show_eigen = Checkbox(value=False, layout=layout, description="Show eigenlines")
show_grid = Checkbox(value=False, layout=layout, description="Show gridlines")
zoom1 = SelectionSlider(options=[1, 2, 5, 10, 20, 50, 100, 200, 500, 1000], value=10,
layout=layout, description="Zoom (left):")
zoom2 = SelectionSlider(options=[1, 2, 5, 10, 20, 50, 100, 200, 500, 1000], value=10,
layout=layout, description="Zoom (right):")
state_rs = Text(continuous_update=False, layout=layout, description="Initial (R,S):")
state_xy = Text(value=str(initial_xy), continuous_update=False,
layout=layout, description="Initial (%s,%s):" % state_vars)
state_rs.observe(change_initial_rs, "value")
state_xy.observe(change_initial_xy, "value")
state_rs.value = str(initial_rs)
output = interactive_output(update, dict(rt=rt, st=st, rst=rst, xyt=xyt,
show_eigen=show_eigen, show_grid=show_grid,
axis1max=zoom1, axis2max=zoom2))
controls1 = HBox((state_xy, state_rs, show_eigen, show_grid))
controls2 = HBox((rt, st))
controls3 = HBox((xyt, zoom1, rst, zoom2))
display(VBox((equation, controls1, controls2, controls3, output)))