This commit is contained in:
TerenceLiu98 2022-10-14 13:01:23 +08:00
parent 9b4039d95f
commit ff992380c9
4 changed files with 237 additions and 42 deletions

View File

@ -12,34 +12,120 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 2,
"id": "0a5c51d2-8b18-4143-b6f1-73a909ccb623", "id": "0a5c51d2-8b18-4143-b6f1-73a909ccb623",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "0bcac263607a46d19fead8b1cf79e498",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"VBox(children=(HBox(children=(VBox(children=(Text(value='x**3 - x**(1/2)', description='Expression:', style=Te…"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "3f64c031482d41799291390431aa3264",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "0504d25c3aab477ca0acf3d054dbaf92",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [ "source": [
"gd1 = gradient_descent_1d(environ=\"jupyterlab\")" "gd1 = gradient_descent_1d(environ=\"jupyterlab\")"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 5,
"id": "15c6e757-cde3-422b-be7e-3f55b7752142", "id": "15c6e757-cde3-422b-be7e-3f55b7752142",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "fca48b98af304f1d821c948d8dcc8629",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"VBox(children=(HBox(children=(Dropdown(index=2, options=(('(sin(x1) - 2) + (sin(x2) - 2) ** 2', '(sin(x1) - 2)…"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "f25a00c1bb294530973475c7a5c8bb10",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "4afc98f7c6954a58aba389526ba09164",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [ "source": [
"gd2 = gradient_descent_2d(environ=\"jupyterlab\")" "gd2 = gradient_descent_2d(environ=\"jupyterlab\")"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 2, "execution_count": 4,
"id": "694b7e27-cc21-44f4-9a89-7a6b97725a64", "id": "694b7e27-cc21-44f4-9a89-7a6b97725a64",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"data": { "data": {
"application/vnd.jupyter.widget-view+json": { "application/vnd.jupyter.widget-view+json": {
"model_id": "08df46f6a3b54543a15dd79d71c334bc", "model_id": "f1d170fccfee4e5891a3c33ad564c197",
"version_major": 2, "version_major": 2,
"version_minor": 0 "version_minor": 0
}, },
@ -53,7 +139,21 @@
{ {
"data": { "data": {
"application/vnd.jupyter.widget-view+json": { "application/vnd.jupyter.widget-view+json": {
"model_id": "ee2bc3a3c2b843aeae594ece6e02596e", "model_id": "e6a5a98d84b54da7b1ac6deaa408ed5d",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "5b35d3e6383947cfb24f1663388ef556",
"version_major": 2, "version_major": 2,
"version_minor": 0 "version_minor": 0
}, },
@ -69,33 +169,10 @@
"gd2_race = gradient_descent_2d_race(environ=\"jupyterlab\")" "gd2_race = gradient_descent_2d_race(environ=\"jupyterlab\")"
] ]
}, },
{
"cell_type": "code",
"execution_count": 6,
"id": "5a2aec3f-e47b-44ab-b3da-2275578e9636",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[array([-4., -4.]),\n",
" array([-1.2519118 , 0.90778485]),\n",
" array([-2.02500166, 2.8935338 ])]"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"gd2_race.df_list_p1"
]
},
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"id": "b89040ec-4318-419b-95eb-60320f146877", "id": "d6001078-5cf2-402e-b37e-a6dad90674a6",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [] "source": []
@ -117,7 +194,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.7.13" "version": "3.9.13"
} }
}, },
"nbformat": 4, "nbformat": 4,

View File

@ -330,12 +330,16 @@ class gradient_descent_2d_race(object):
def __init__(self, environ:str="jupyterlab"): def __init__(self, environ:str="jupyterlab"):
pio.renderers.default = environ # 'notebook' or 'colab' or 'jupyterlab' pio.renderers.default = environ # 'notebook' or 'colab' or 'jupyterlab'
self.wg_expr = widgets.Text(value="(sin(x1) - 2) ** 2 + (sin(x2) - 2) ** 2", description="Expression:") self.wg_expr = widgets.Text(value="(sin(x1) - 2) ** 2 + (sin(x2) - 2) ** 2", description="Expression:")
self.wg_person_one = widgets.Text(value="(0, 0)", description="coordinate 1:") self.wg_person_one = widgets.Text(value="(5, 5)", description="candidate 1:")
self.wg_person_two = widgets.Text(value="(0, 0)", description="coordinate 2:") self.wg_person_two = widgets.Text(value="(5, 5)", description="candidate 2:")
self.button_compute = widgets.Button(description="Compute") self.button_compute = widgets.Button(description="Compute")
self.button_plot = widgets.Button(description="Plot") self.button_plot = widgets.Button(description="Plot")
self.compute_output = widgets.Output() self.compute_output = widgets.Output()
self.config = widgets.VBox([self.wg_expr, self.wg_person_one, self.wg_person_two, self.button_compute]) self.plot_output = widgets.Output()
self.button_box = widgets.HBox([self.button_compute, self.button_plot], description="operations")
self.config = widgets.VBox([self.wg_expr, self.wg_person_one, self.wg_person_two, self.button_box])
self.xn_list_p1, self.df_list_p1 = [], [] self.xn_list_p1, self.df_list_p1 = [], []
self.xn_list_p2, self.df_list_p2 = [], [] self.xn_list_p2, self.df_list_p2 = [], []
self.initialization() self.initialization()
@ -344,8 +348,8 @@ class gradient_descent_2d_race(object):
display(self.config) display(self.config)
self.button_compute.on_click(self.compute) self.button_compute.on_click(self.compute)
display(self.compute_output) display(self.compute_output)
#self.button_plot.on_click(self.plot) self.button_plot.on_click(self.plot)
#display(self.plot_output) display(self.plot_output)
def compute(self, *args): def compute(self, *args):
with self.compute_output: with self.compute_output:
@ -375,5 +379,60 @@ class gradient_descent_2d_race(object):
print("player two: gradient= {}".format(gradient)) print("player two: gradient= {}".format(gradient))
clear_output(wait=True) clear_output(wait=True)
return None return None
def plot(self, *args):
with self.plot_output:
clear_output(wait=True)
#x0 = np.array(self.wg_x0.value.split(","), dtype=float)
x1 = symbols("x1")
x2 = symbols("x2")
expr = sympify(self.wg_expr.value)
xx1 = np.arange(np.array(self.xn_list_p1)[:, 0].min()*0.5, np.array(self.xn_list_p1)[:, 0].max()*1.5, 0.1)
xx2 = np.arange(np.array(self.xn_list_p1)[:, 1].min()*0.5, np.array(self.xn_list_p1)[:, 1].max()*1.5, 0.1)
xx1, xx2 = np.meshgrid(xx1, xx2)
f = lambdify((x1, x2), expr, "numpy")
fx = f(xx1, xx2)
f_xn_p1 = f(np.array(self.xn_list_p1)[:, 0], np.array(self.xn_list_p1)[:, 1])
f_xn_p2 = f(np.array(self.xn_list_p2)[:, 0], np.array(self.xn_list_p2)[:, 1])
frames, steps = [], []
for k in range(len(f_xn_p1)):
tmp_trace1 = go.Scatter3d(x=np.array(self.xn_list_p1)[:k,0], y=np.array(self.xn_list_p1)[:k,1], z=f_xn_p1)
tmp_trace2 = go.Scatter3d(x=np.array(self.xn_list_p2)[:k,0], y=np.array(self.xn_list_p2)[:k,1], z=f_xn_p2)
frame = go.Frame(dict(data=[tmp_trace1, tmp_trace2], name=f'frame{k+1}'), traces=[1, 2])
frames.append(frame)
step = dict(
method="update",
args=[{"visible": [True]},
{"title": "Slider switched to step: " + str(k+1)}], # layout attribute
)
steps.append(step)
sliders = [dict(steps= [dict(method= 'animate',
args= [[f'frame{k+1}'],
dict(mode= 'immediate',
frame= dict( duration=0, redraw= True ),
transition=dict( duration=0)
)
],
#label='Date : {}'.format(date_range[k])
) for k in range(0,len(frames))],
transition= dict(duration=0),
x=0,
y=0,
currentvalue=dict(font=dict(size=12), visible=True, xanchor= 'center'),
len=1.0)
]
trace1 = go.Surface(x=xx1, y=xx2, z=fx, showscale=True, opacity=0.4)
trace2 = go.Scatter3d(x=None, y=None, z=None)
trace3 = go.Scatter3d(x=None, y=None, z=None)
fig = go.Figure(data=[trace1, trace2, trace3], frames=frames)
fig.update_layout(updatemenus=[dict(type="buttons", buttons=[dict(label="Play", method="animate", args=[None, dict(fromcurrent=True)]), \
dict(label="Pause", method="animate", args=[[None], dict(fromcurrent=True, mode='immediate', transition= {'duration': 0}, frame=dict(redraw=True, duration=0))])])],
margin=dict(l=20, r=20, b=20, t=20), sliders=sliders)
fig.show()

View File

@ -330,12 +330,16 @@ class gradient_descent_2d_race(object):
def __init__(self, environ:str="jupyterlab"): def __init__(self, environ:str="jupyterlab"):
pio.renderers.default = environ # 'notebook' or 'colab' or 'jupyterlab' pio.renderers.default = environ # 'notebook' or 'colab' or 'jupyterlab'
self.wg_expr = widgets.Text(value="(sin(x1) - 2) ** 2 + (sin(x2) - 2) ** 2", description="Expression:") self.wg_expr = widgets.Text(value="(sin(x1) - 2) ** 2 + (sin(x2) - 2) ** 2", description="Expression:")
self.wg_person_one = widgets.Text(value="(0, 0)", description="coordinate 1:") self.wg_person_one = widgets.Text(value="(5, 5)", description="candidate 1:")
self.wg_person_two = widgets.Text(value="(0, 0)", description="coordinate 2:") self.wg_person_two = widgets.Text(value="(5, 5)", description="candidate 2:")
self.button_compute = widgets.Button(description="Compute") self.button_compute = widgets.Button(description="Compute")
self.button_plot = widgets.Button(description="Plot") self.button_plot = widgets.Button(description="Plot")
self.compute_output = widgets.Output() self.compute_output = widgets.Output()
self.config = widgets.VBox([self.wg_expr, self.wg_person_one, self.wg_person_two, self.button_compute]) self.plot_output = widgets.Output()
self.button_box = widgets.HBox([self.button_compute, self.button_plot], description="operations")
self.config = widgets.VBox([self.wg_expr, self.wg_person_one, self.wg_person_two, self.button_box])
self.xn_list_p1, self.df_list_p1 = [], [] self.xn_list_p1, self.df_list_p1 = [], []
self.xn_list_p2, self.df_list_p2 = [], [] self.xn_list_p2, self.df_list_p2 = [], []
self.initialization() self.initialization()
@ -344,8 +348,8 @@ class gradient_descent_2d_race(object):
display(self.config) display(self.config)
self.button_compute.on_click(self.compute) self.button_compute.on_click(self.compute)
display(self.compute_output) display(self.compute_output)
#self.button_plot.on_click(self.plot) self.button_plot.on_click(self.plot)
#display(self.plot_output) display(self.plot_output)
def compute(self, *args): def compute(self, *args):
with self.compute_output: with self.compute_output:
@ -375,5 +379,60 @@ class gradient_descent_2d_race(object):
print("player two: gradient= {}".format(gradient)) print("player two: gradient= {}".format(gradient))
clear_output(wait=True) clear_output(wait=True)
return None return None
def plot(self, *args):
with self.plot_output:
clear_output(wait=True)
#x0 = np.array(self.wg_x0.value.split(","), dtype=float)
x1 = symbols("x1")
x2 = symbols("x2")
expr = sympify(self.wg_expr.value)
xx1 = np.arange(np.array(self.xn_list_p1)[:, 0].min()*0.5, np.array(self.xn_list_p1)[:, 0].max()*1.5, 0.1)
xx2 = np.arange(np.array(self.xn_list_p1)[:, 1].min()*0.5, np.array(self.xn_list_p1)[:, 1].max()*1.5, 0.1)
xx1, xx2 = np.meshgrid(xx1, xx2)
f = lambdify((x1, x2), expr, "numpy")
fx = f(xx1, xx2)
f_xn_p1 = f(np.array(self.xn_list_p1)[:, 0], np.array(self.xn_list_p1)[:, 1])
f_xn_p2 = f(np.array(self.xn_list_p2)[:, 0], np.array(self.xn_list_p2)[:, 1])
frames, steps = [], []
for k in range(len(f_xn_p1)):
tmp_trace1 = go.Scatter3d(x=np.array(self.xn_list_p1)[:k,0], y=np.array(self.xn_list_p1)[:k,1], z=f_xn_p1)
tmp_trace2 = go.Scatter3d(x=np.array(self.xn_list_p2)[:k,0], y=np.array(self.xn_list_p2)[:k,1], z=f_xn_p2)
frame = go.Frame(dict(data=[tmp_trace1, tmp_trace2], name=f'frame{k+1}'), traces=[1, 2])
frames.append(frame)
step = dict(
method="update",
args=[{"visible": [True]},
{"title": "Slider switched to step: " + str(k+1)}], # layout attribute
)
steps.append(step)
sliders = [dict(steps= [dict(method= 'animate',
args= [[f'frame{k+1}'],
dict(mode= 'immediate',
frame= dict( duration=0, redraw= True ),
transition=dict( duration=0)
)
],
#label='Date : {}'.format(date_range[k])
) for k in range(0,len(frames))],
transition= dict(duration=0),
x=0,
y=0,
currentvalue=dict(font=dict(size=12), visible=True, xanchor= 'center'),
len=1.0)
]
trace1 = go.Surface(x=xx1, y=xx2, z=fx, showscale=True, opacity=0.4)
trace2 = go.Scatter3d(x=None, y=None, z=None)
trace3 = go.Scatter3d(x=None, y=None, z=None)
fig = go.Figure(data=[trace1, trace2, trace3], frames=frames)
fig.update_layout(updatemenus=[dict(type="buttons", buttons=[dict(label="Play", method="animate", args=[None, dict(fromcurrent=True)]), \
dict(label="Pause", method="animate", args=[[None], dict(fromcurrent=True, mode='immediate', transition= {'duration': 0}, frame=dict(redraw=True, duration=0))])])],
margin=dict(l=20, r=20, b=20, t=20), sliders=sliders)
fig.show()