diff --git a/algorithm/interactive.ipynb b/algorithm/interactive.ipynb index 914cb85..b6ac3b7 100644 --- a/algorithm/interactive.ipynb +++ b/algorithm/interactive.ipynb @@ -12,34 +12,120 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "0a5c51d2-8b18-4143-b6f1-73a909ccb623", "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": [ "gd1 = gradient_descent_1d(environ=\"jupyterlab\")" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "15c6e757-cde3-422b-be7e-3f55b7752142", "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": [ "gd2 = gradient_descent_2d(environ=\"jupyterlab\")" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 4, "id": "694b7e27-cc21-44f4-9a89-7a6b97725a64", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "08df46f6a3b54543a15dd79d71c334bc", + "model_id": "f1d170fccfee4e5891a3c33ad564c197", "version_major": 2, "version_minor": 0 }, @@ -53,7 +139,21 @@ { "data": { "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_minor": 0 }, @@ -69,33 +169,10 @@ "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", "execution_count": null, - "id": "b89040ec-4318-419b-95eb-60320f146877", + "id": "d6001078-5cf2-402e-b37e-a6dad90674a6", "metadata": {}, "outputs": [], "source": [] @@ -117,7 +194,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.13" + "version": "3.9.13" } }, "nbformat": 4, diff --git a/algorithm/optimization/.ipynb_checkpoints/gd-checkpoint.py b/algorithm/optimization/.ipynb_checkpoints/gd-checkpoint.py index 04e5100..de0e56e 100644 --- a/algorithm/optimization/.ipynb_checkpoints/gd-checkpoint.py +++ b/algorithm/optimization/.ipynb_checkpoints/gd-checkpoint.py @@ -330,12 +330,16 @@ class gradient_descent_2d_race(object): def __init__(self, environ:str="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_person_one = widgets.Text(value="(0, 0)", description="coordinate 1:") - self.wg_person_two = widgets.Text(value="(0, 0)", description="coordinate 2:") + self.wg_person_one = widgets.Text(value="(5, 5)", description="candidate 1:") + self.wg_person_two = widgets.Text(value="(5, 5)", description="candidate 2:") self.button_compute = widgets.Button(description="Compute") self.button_plot = widgets.Button(description="Plot") + 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_p2, self.df_list_p2 = [], [] self.initialization() @@ -344,8 +348,8 @@ class gradient_descent_2d_race(object): display(self.config) self.button_compute.on_click(self.compute) display(self.compute_output) - #self.button_plot.on_click(self.plot) - #display(self.plot_output) + self.button_plot.on_click(self.plot) + display(self.plot_output) def compute(self, *args): with self.compute_output: @@ -375,5 +379,60 @@ class gradient_descent_2d_race(object): print("player two: gradient= {}".format(gradient)) clear_output(wait=True) 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() + \ No newline at end of file diff --git a/algorithm/optimization/__pycache__/gd.cpython-39.pyc b/algorithm/optimization/__pycache__/gd.cpython-39.pyc index 8c81221..4796c7f 100644 Binary files a/algorithm/optimization/__pycache__/gd.cpython-39.pyc and b/algorithm/optimization/__pycache__/gd.cpython-39.pyc differ diff --git a/algorithm/optimization/gd.py b/algorithm/optimization/gd.py index 04e5100..de0e56e 100644 --- a/algorithm/optimization/gd.py +++ b/algorithm/optimization/gd.py @@ -330,12 +330,16 @@ class gradient_descent_2d_race(object): def __init__(self, environ:str="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_person_one = widgets.Text(value="(0, 0)", description="coordinate 1:") - self.wg_person_two = widgets.Text(value="(0, 0)", description="coordinate 2:") + self.wg_person_one = widgets.Text(value="(5, 5)", description="candidate 1:") + self.wg_person_two = widgets.Text(value="(5, 5)", description="candidate 2:") self.button_compute = widgets.Button(description="Compute") self.button_plot = widgets.Button(description="Plot") + 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_p2, self.df_list_p2 = [], [] self.initialization() @@ -344,8 +348,8 @@ class gradient_descent_2d_race(object): display(self.config) self.button_compute.on_click(self.compute) display(self.compute_output) - #self.button_plot.on_click(self.plot) - #display(self.plot_output) + self.button_plot.on_click(self.plot) + display(self.plot_output) def compute(self, *args): with self.compute_output: @@ -375,5 +379,60 @@ class gradient_descent_2d_race(object): print("player two: gradient= {}".format(gradient)) clear_output(wait=True) 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() + \ No newline at end of file