393 lines
23 KiB
Python
393 lines
23 KiB
Python
import math
|
|
import copy
|
|
import time
|
|
import sympy
|
|
import numpy as np
|
|
from scipy.misc import derivative
|
|
from sympy import symbols, sympify, lambdify, diff
|
|
|
|
import ipywidgets as widgets
|
|
from IPython.display import Image, display, clear_output
|
|
|
|
from tqdm import tqdm
|
|
|
|
import matplotlib.pyplot as plt
|
|
|
|
import plotly.io as pio
|
|
import plotly.graph_objects as go
|
|
import plotly.figure_factory as ff
|
|
from plotly.subplots import make_subplots
|
|
|
|
import warnings
|
|
warnings.filterwarnings("ignore")
|
|
|
|
def array_mesh(data, n):
|
|
array_mesh = []
|
|
for i in range(len(data) - n):
|
|
for j in range(len(data[i:i+n])):
|
|
array_mesh.append(data[i:i+n])
|
|
return np.vstack(array_mesh)
|
|
|
|
class gd1d(object):
|
|
def __init__(self, environ:str="jupyterlab"):
|
|
pio.renderers.default = environ # 'notebook' or 'colab' or 'jupyterlab'
|
|
self.wg_expr = widgets.Text(value="sin(x) + sin((10.0 / 3.0) * x)",
|
|
description="Expression:",
|
|
style={'description_width': 'initial'})
|
|
self.wg_x0 = widgets.FloatText(value="2",
|
|
description="Startpoint(x):",
|
|
style={'description_width': 'initial'})
|
|
self.wg_lr = widgets.FloatText(value="1e-1",
|
|
description="step size:",
|
|
style={'description_width': 'initial'})
|
|
self.wg_epsilon = widgets.FloatText(value="1e-5",
|
|
description="criterion:",
|
|
style={'description_width': 'initial'})
|
|
self.wg_max_iter = widgets.IntText(value="1000",
|
|
description="max iteration:",
|
|
style={'description_width': 'initial'})
|
|
self.wg_x_range = widgets.Text(value="-2,5",
|
|
description="X-axis range:",
|
|
style={"description_width": "initial"})
|
|
|
|
self.button_compute = widgets.Button(description="Compute")
|
|
self.button_plot = widgets.Button(description="Plot")
|
|
|
|
self.compute_output = widgets.Output()
|
|
self.plot_output = widgets.Output()
|
|
self.params_lvbox = widgets.VBox([self.wg_expr, self.wg_x0, self.wg_lr])
|
|
self.params_rvbox = widgets.VBox([self.wg_epsilon, self.wg_max_iter, self.wg_x_range])
|
|
self.params_box = widgets.HBox([self.params_lvbox, self.params_rvbox], description="Parameters")
|
|
self.button_box = widgets.HBox([self.button_compute, self.button_plot], description="operations")
|
|
self.config = widgets.VBox([self.params_box, self.button_box])
|
|
self.initialization()
|
|
|
|
|
|
def initialization(self):
|
|
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)
|
|
|
|
def compute(self, *args):
|
|
with self.compute_output:
|
|
xn = self.wg_x0.value
|
|
x = symbols("x")
|
|
expr = sympify(self.wg_expr.value)
|
|
f = lambdify(x, expr)
|
|
df = lambdify(x, diff(expr, x))
|
|
self.xn_list, self.df_list = [], []
|
|
for n in tqdm(range(0, self.wg_max_iter.value)):
|
|
gradient = df(xn)
|
|
self.xn_list.append(xn)
|
|
self.df_list.append(gradient)
|
|
if (abs(gradient) < self.wg_epsilon.value):
|
|
clear_output(wait=True)
|
|
print("Found solution of {} after".format(expr), n, "iterations")
|
|
print("x* = {}".format(xn))
|
|
return None
|
|
xn = xn - self.wg_lr.value * gradient
|
|
clear_output(wait=True)
|
|
display("Exceeded maximum iterations. No solution found.")
|
|
return None
|
|
|
|
def plot(self, *args):
|
|
with self.plot_output:
|
|
clear_output(wait=True)
|
|
x0 = float(self.wg_x0.value)
|
|
x_range = np.array(self.wg_x_range.value.split(","), dtype=float)
|
|
x = symbols("x")
|
|
expr = sympify(self.wg_expr.value)
|
|
f = lambdify(x, sympify(expr), "numpy")
|
|
xx1 = np.arange(x_range[0], x_range[1], 0.05)
|
|
fx = f(xx1)
|
|
f_xn = f(np.array(self.xn_list))
|
|
|
|
tangent_x, tangent_y = [], []
|
|
normal_x, normal_y = [], []
|
|
for i in range(0, len(f_xn)):
|
|
xrange = np.linspace(np.array(self.xn_list)[i]-0.25, np.array(self.xn_list)[i]+0.25, 10)
|
|
tangent_line = self.df_list[i] * (x - np.array(self.xn_list)[i]) + f_xn[i]
|
|
normal_line = (-1/(self.df_list[i]))*(x - np.array(self.xn_list)[i]) + f_xn[i]
|
|
tangent_x.append(xrange)
|
|
tangent_y.append(lambdify(x, tangent_line)(xrange))
|
|
normal_x.append(xrange)
|
|
normal_y.append(lambdify(x, normal_line)(xrange))
|
|
|
|
fig = go.Figure()
|
|
#fig.add_scatter(x=xx1, y=fx)
|
|
|
|
fig.add_trace(go.Scatter(x=xx1, y=fx))
|
|
fig.add_traces(go.Scatter(x=None, y=None, mode="lines + markers", marker=dict(size=10), line={"color":"#de1032", "width":3, 'dash': 'dash'}))
|
|
fig.add_traces(go.Scatter(x=None, y=None, mode="lines", line={"color":"#debc10", "width":3, 'dash': 'dash'}))
|
|
#fig.add_traces(go.Scatter(x=None, y=None, mode="lines", line={"color":"#de3210", "width":3, 'dash': 'dash'}))
|
|
frames = [go.Frame(data=[go.Scatter(x=xx1, y=fx),
|
|
go.Scatter(x=np.array(self.xn_list)[:k+1], y=f_xn),
|
|
go.Scatter(x=tangent_x[k], y=tangent_y[k]),
|
|
go.Scatter(x=normal_x[k], y=normal_y[k])],
|
|
traces= [0, 1, 2, 3]) for k in range(len(f_xn))]
|
|
fig.frames = frames
|
|
button_play = dict(label="Play", method="animate", args=[None, dict(fromcurrent=True, transition=dict(duration=0), frame=dict(redraw=True, duration=2000))])
|
|
button_pause = dict(label="Pause", method="animate", args=[[None], dict(fromcurrent=True, mode='immediate', transition={'duration': 0}, frame=dict(redraw=True, duration=0))])
|
|
fig.update_layout(height=800, updatemenus=[dict(type="buttons",buttons=[button_play, button_pause])])
|
|
fig.update_yaxes(scaleanchor = "x", scaleratio = 1)
|
|
fig.show()
|
|
|
|
|
|
class gd2d(object):
|
|
def __init__(self, environ:str="jupyterlab", type="default"):
|
|
if type == "default":
|
|
self.initialization_default(environ=environ)
|
|
self.compute_default()
|
|
self.user_step = 1
|
|
elif type == "custom":
|
|
self.initlization_custom()
|
|
self.compute_custom()
|
|
else:
|
|
return None
|
|
|
|
|
|
def initialization_default(self, environ):
|
|
pio.renderers.default = environ # 'notebook' or 'colab' or 'jupyterlab'
|
|
self.wg_expr = widgets.Dropdown(options=[("(1 - 8 * x1 + 7 * x1**2 - (7/3) * x1**3 + (1/4) * x1**4) * x2**2 * E**(-x2)", "(1 - 8 * x1 + 7 * x1**2 - (7/3) * x1**3 + (1/4) * x1**4) * x2**2 * E**(-x2)"), ("x1 - x2 + 2*x1*x2 + 2*x1**2 + x2**2", "x1 - x2 + 2*x1*x2 + 2*x1**2 + x2**2"), ("(4-x1)**2 + x2**2", "(4-x1)**2 + x2**2"), ("x1**2 + 10*x2**2", "x1**2 + 10*x2**2")], value="(1 - 8 * x1 + 7 * x1**2 - (7/3) * x1**3 + (1/4) * x1**4) * x2**2 * E**(-x2)", descrption="Expression")
|
|
self.wg_x0 = widgets.Text(value="0,2", description="Startpoint:")
|
|
self.wg_lr = widgets.FloatText(value="1e-1", description="step size:")
|
|
self.wg_epsilon = widgets.FloatText(value="1e-5", description="criterion:")
|
|
self.wg_max_iter = widgets.IntText(value="1000", description="max iteration")
|
|
self.button_compute = widgets.Button(description="Compute")
|
|
self.button_plot_default = widgets.Button(description="3D Plot")
|
|
self.button_plot_contour = widgets.Button(description="Contour")
|
|
|
|
self.compute_output = widgets.Output()
|
|
self.plot_default_output = widgets.Output()
|
|
self.plot_contour_output = widgets.Output()
|
|
self.params_lvbox = widgets.VBox([self.wg_x0, self.wg_lr])
|
|
self.params_rvbox = widgets.VBox([self.wg_epsilon, self.wg_max_iter])
|
|
self.exp_box = widgets.HBox([self.wg_expr])
|
|
self.params_box = widgets.HBox([self.params_lvbox, self.params_rvbox], description="Parameters")
|
|
self.button_box = widgets.HBox([self.button_compute, self.button_plot_default, self.button_plot_contour], description="operations")
|
|
self.config = widgets.VBox([self.exp_box, self.params_box, self.button_box])
|
|
display(self.config)
|
|
|
|
self.button_compute.on_click(self.compute_default)
|
|
display(self.compute_output)
|
|
self.button_plot_default.on_click(self.plot_default)
|
|
self.button_plot_contour.on_click(self.plot_contour)
|
|
img1 = self.plot_default_output
|
|
img2 = self.plot_contour_output
|
|
#display(widgets.HBox([img1, img2]))
|
|
display(img1)
|
|
display(img2)
|
|
|
|
def compute_default(self, *args):
|
|
with self.compute_output:
|
|
x0 = np.array(self.wg_x0.value.split(","), dtype=float)
|
|
xn = x0
|
|
x1 = symbols("x1")
|
|
x2 = symbols("x2")
|
|
expr = sympify(self.wg_expr.value)
|
|
self.xn_list, self.df_list = [], []
|
|
|
|
for n in tqdm(range(0, self.wg_max_iter.value)):
|
|
gradient = np.array([diff(expr, x1).subs(x1, xn[0]).subs(x2, xn[1]),
|
|
diff(expr, x2).subs(x1, xn[0]).subs(x2, xn[1])], dtype=float)
|
|
self.xn_list.append(xn)
|
|
self.df_list.append(gradient)
|
|
if np.linalg.norm(gradient, ord=2) < self.wg_epsilon.value:
|
|
clear_output(wait=True)
|
|
print("Found solution of {} after".format(expr), n, "iterations")
|
|
print("x* = [{}, {}]".format(xn[0], xn[1]))
|
|
return None
|
|
xn = xn - self.wg_lr.value * gradient
|
|
clear_output(wait=True)
|
|
display("Exceeded maximum iterations. No solution found.")
|
|
return None
|
|
|
|
def plot_default(self, *args):
|
|
with self.plot_default_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)
|
|
expression_list = ["(1 - 8 * x1 + 7 * x1**2 - (7/3) * x1**3 + (1/4) * x1**4) * x2**2 * E**(-x2)", "(1 - 8 * x1 + 7 * x1**2 - (7/3) * x1**3 + (1/4) * x1**4) * x2**2 * E**(-x2)"]
|
|
if self.wg_expr.value in expression_list:
|
|
xx1, xx2 = np.arange(0, 5, 0.25), np.arange(0, 5, 0.25)
|
|
else:
|
|
xx1, xx2 = np.arange(-5, 5, 0.25), np.arange(-5, 5, 0.25)
|
|
xx1_tangent = np.arange(np.array(self.xn_list)[:, 0].min(), np.array(self.xn_list)[:, 0].max(), 0.1)
|
|
xx2_tangent = np.arange(np.array(self.xn_list)[:, 1].min(), np.array(self.xn_list)[:, 1].max(), 0.1)
|
|
xx1_o, xx2_o = xx1, xx2
|
|
xx1, xx2 = np.meshgrid(xx1, xx2)
|
|
xx1_tangent, xx2_tangent = np.meshgrid(xx1_o, xx2_o)
|
|
#xx1_tangent, xx2_tangent = array_mesh(np.arange(0, 5, 0.25), 10), array_mesh(np.arange(0, 5, 0.25), 10)
|
|
self.xx1_tangent, self.xx2_tangent = xx1_tangent, xx2_tangent
|
|
f = lambdify((x1, x2), expr, "numpy")
|
|
fx = f(xx1, xx2)
|
|
f_xn = f(np.array(self.xn_list)[:, 0], np.array(self.xn_list)[:, 1])
|
|
partial_x1 = lambdify((x1, x2), diff(expr, x1), "numpy")
|
|
partial_x2 = lambdify((x1, x2), diff(expr, x2), "numpy")
|
|
self.partial_x1, self.partial_x2 = partial_x1, partial_x2
|
|
plane = partial_x1(np.array(self.xn_list)[:, 0], np.array(self.xn_list)[:, 1]) * (x1 - np.array(self.xn_list)[:, 0]) + partial_x2(np.array(self.xn_list)[:, 0], np.array(self.xn_list)[:, 1]) * (x2 - np.array(self.xn_list)[:, 1]) + f_xn
|
|
|
|
z = [lambdify((x1, x2), plane[i], "numpy")(xx1_tangent, xx2_tangent) for i in range(0, len(plane))]
|
|
self.z = z
|
|
## projection
|
|
z_offset = (np.min(fx)) * np.ones(fx.shape)
|
|
proj_z = lambda x, y, z: z
|
|
colorsurfz = proj_z(xx1, xx2, fx)
|
|
|
|
fig = make_subplots(rows=1, cols=2, specs=[[{'type': 'surface'}, {'type': 'surface'}]])
|
|
fig.add_trace(go.Surface(contours = {"x": {"show": True}, "y":{"show": True}, "z":{"show": True}}, x=xx1, y=xx2, z=fx), row=1, col=1)
|
|
fig.add_trace(go.Scatter3d(x=None, y=None, z=None, marker=dict(size=5)), row=1, col=1)
|
|
fig.add_trace(go.Surface(x=None, y=None, z=None, showlegend=False, showscale=False, colorscale='Blues'), row=1, col=1)
|
|
fig.add_trace(go.Surface(z=list(z_offset), x=xx1, y=xx2, showlegend=False, showscale=False, surfacecolor=colorsurfz), row=1, col=2)
|
|
fig.add_trace(go.Scatter3d(x=None, y=None, z=None, marker=dict(size=5)), row=1, col=2)
|
|
fig.add_trace(go.Scatter3d(x=None, y=None, z=None, marker=dict(size=5)), row=1, col=2)
|
|
frames = [go.Frame(data=[go.Surface(visible=True, showscale=False, opacity=0.8),
|
|
go.Scatter3d(x=np.array(self.xn_list)[:k,0], y=np.array(self.xn_list)[:k,1], z=f_xn, marker=dict(size=5), line={"color":"blue", "width":3, 'dash': 'dash'}),
|
|
go.Surface(visible=False, x=xx1_tangent, y=xx2_tangent, z=z[k]),
|
|
go.Surface(visible=True, showscale=False, opacity=0.8),
|
|
go.Scatter3d(x=np.array(self.xn_list)[:k, 0], y=np.array(self.xn_list)[:k, 1], z=f_xn, line={"color":"blue", "width":3, 'dash': 'dash'}),
|
|
go.Scatter3d(x=np.array(self.xn_list)[:k, 0].flatten(), y=np.array(self.xn_list)[:k, 1].flatten(), z=z_offset.flatten(), marker=dict(size=5), line={"color":"green", "width":3, 'dash': 'dash'})],
|
|
traces=[0, 1, 2, 3, 4, 5]) for k in range(len(f_xn))]
|
|
fig.frames = frames
|
|
self.fig_frames = frames
|
|
|
|
button_play = dict(label="Play", method="animate", args=[None, dict(fromcurrent=True, transition=dict(duration=0), frame=dict(redraw=True, duration=1000))])
|
|
button_pause = dict(label="Pause", method="animate", args=[[None], dict(fromcurrent=True, mode='immediate', transition={'duration': 0}, frame=dict(redraw=True, duration=0))])
|
|
button_tangent = dict(label="Tangent Plane", method="update", args=[{"visible": [True, True, True, True, True, True]}])
|
|
fig.update_layout(scene_aspectmode='manual', scene_aspectratio=dict(x=0, y=0, z=0),
|
|
height=800, updatemenus=[dict(type="buttons", buttons=[button_play, button_pause, button_tangent])])
|
|
fig.update_scenes(xaxis_visible=True,
|
|
yaxis_visible=True,
|
|
zaxis_visible=True)
|
|
fig.update_scenes(camera_projection_type = "orthographic")
|
|
fig.update_yaxes(scaleanchor = "x", scaleratio = 1)
|
|
fig.show()
|
|
|
|
def plot_contour(self, *args):
|
|
with self.plot_contour_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(0, 5, 0.1)
|
|
xx2 = np.arange(0, 6, 0.1)
|
|
xx1_tangent = np.arange(np.array(self.xn_list)[:, 0].min(), np.array(self.xn_list)[:, 0].max(), 0.1)
|
|
xx2_tangent = np.arange(np.array(self.xn_list)[:, 1].min(), np.array(self.xn_list)[:, 1].max(), 0.1)
|
|
xx1_o, xx2_o = xx1, xx2
|
|
xx1, xx2 = np.meshgrid(xx1, xx2)
|
|
xx1_tangent, xx2_tangent = np.meshgrid(xx1_o, xx2_o)
|
|
f = lambdify((x1, x2), expr, "numpy")
|
|
fx = f(xx1, xx2)
|
|
f_xn = f(np.array(self.xn_list)[:, 0], np.array(self.xn_list)[:, 1])
|
|
partial_x1 = lambdify((x1, x2), diff(expr, x1), "numpy")
|
|
partial_x2 = lambdify((x1, x2), diff(expr, x2), "numpy")
|
|
plane = partial_x1(np.array(self.xn_list)[:, 0], np.array(self.xn_list)[:, 1]) * (x1 - np.array(self.xn_list)[:, 0]) + partial_x2(np.array(self.xn_list)[:, 0], np.array(self.xn_list)[:, 1]) * (x2 - np.array(self.xn_list)[:, 1]) + f_xn
|
|
z = [lambdify((x1, x2), plane[i], "numpy")(xx1_tangent, xx2_tangent) for i in range(0, len(plane))]
|
|
|
|
gradfun=[sympy.diff(expr,var) for var in (x1,x2)]
|
|
numgradfun=sympy.lambdify([x1,x2], gradfun)
|
|
x1_mesh, x2_mesh = np.meshgrid(xx1_o, xx2_o)#np.meshgrid(np.array(self.xn_list)[:, 0], np.array(self.xn_list)[:, 1])
|
|
graddat=numgradfun(x1_mesh, x2_mesh)
|
|
|
|
vec_field = ff.create_quiver(x1_mesh, x2_mesh, graddat[0], graddat[1], scale=.05, arrow_scale=.4, angle=math.pi/3)
|
|
vec_field.update_traces(line_color="black")
|
|
fig = go.Figure()
|
|
fig.add_trace(go.Contour(x=xx1_o, y=xx2_o, z=fx))
|
|
for d in vec_field.data:
|
|
fig.add_trace(go.Scatter(visible=False, x=d['x'], y=d['y'], line_color="black"))
|
|
fig.update_layout(
|
|
updatemenus=[dict(type = "buttons",direction = "left",
|
|
buttons=list([
|
|
dict(args=[{"visible":["True", "True"]}], label="Gradient", method="update")]))], height=800)
|
|
fig.show()
|
|
|
|
|
|
class gd2d_compete(object):
|
|
def __init__(self, environ:str="jupyterlab"):
|
|
self.initialization(environ=environ)
|
|
|
|
|
|
def initialization(self, environ):
|
|
pio.renderers.default = environ # 'notebook' or 'colab' or 'jupyterlab'
|
|
self.timer = 0
|
|
self.wg_expr = widgets.Dropdown(options=[("(1 - 8 * x1 + 7 * x1**2 - (7/3) * x1**3 + (1/4) * x1**4) * x2**2 * E**(-x2)", "(1 - 8 * x1 + 7 * x1**2 - (7/3) * x1**3 + (1/4) * x1**4) * x2**2 * E**(-x2)"), ("x1 - x2 + 2*x1*x2 + 2*x1**2 + x2**2", "x1 - x2 + 2*x1*x2 + 2*x1**2 + x2**2")], value="(1 - 8 * x1 + 7 * x1**2 - (7/3) * x1**3 + (1/4) * x1**4) * x2**2 * E**(-x2)", descrption="Expression")
|
|
self.wg_x0 = widgets.Text(value="0,2", description="Init point:")
|
|
self.wg_lr = widgets.FloatText(value="0.1", description="step size:")
|
|
self.wg_direction_p0 = widgets.Text(value="0.5,1", description="Direction (a1)")
|
|
self.wg_direction_p1 = widgets.Text(value="2.5,1", description="Direction (a2)")
|
|
# need learning rate
|
|
self.button_compute = widgets.Button(description="Compute")
|
|
self.button_plot = widgets.Button(description="Plot")
|
|
self.compute_output = widgets.Output()
|
|
self.plot_output =widgets.Output()
|
|
|
|
self.params_lvbox = widgets.VBox([self.wg_x0, self.wg_lr])
|
|
self.params_rvbox = widgets.VBox([self.wg_direction_p0, self.wg_direction_p1])
|
|
self.exp_box = widgets.HBox([self.wg_expr])
|
|
self.params_box = widgets.HBox([self.params_lvbox, self.params_rvbox], description="Parameters")
|
|
self.button_box = widgets.HBox([self.button_compute, self.button_plot])
|
|
self.config = widgets.VBox([self.exp_box, self.params_box, self.button_box])
|
|
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)
|
|
|
|
def compute(self, *args):
|
|
with self.compute_output:
|
|
expr = sympify(self.wg_expr.value)
|
|
x1, x2 = symbols("x1 x2")
|
|
if self.timer == 0:
|
|
self.xn_p0_list, self.xn_p1_list = [], []
|
|
x0 = np.array(self.wg_x0.value.split(","), dtype=float)
|
|
self.xn_p0_list.append(x0)
|
|
self.xn_p1_list.append(x0)
|
|
direction_p0 = np.array(self.wg_direction_p0.value.split(","), dtype=float)
|
|
direction_p1 = np.array(self.wg_direction_p1.value.split(","), dtype=float)
|
|
self.timer = self.timer + 1
|
|
# calcualte next point position
|
|
x0_p0 = self.xn_p0_list[self.timer-1] + self.wg_lr.value * direction_p0
|
|
x0_p1 = self.xn_p1_list[self.timer-1] + self.wg_lr.value * direction_p1
|
|
self.xn_p0_list.append(x0_p0)
|
|
self.xn_p1_list.append(x0_p1)
|
|
f = lambdify((x1, x2), expr, "numpy")
|
|
f_xn = f(np.array([x0_p0, x0_p1])[:, 0], np.array([x0_p0, x0_p1])[:, 1])
|
|
clear_output(wait=True)
|
|
print("a1({}): {}, a2({}): {}".format(self.timer, np.append(x0_p0, f_xn[0]), self.timer,np.append(x0_p1, f_xn[1])))
|
|
|
|
def plot(self, *args):
|
|
with self.plot_output:
|
|
clear_output(wait=True)
|
|
x1, x2 =symbols("x1 x2")
|
|
if self.wg_expr.value == "(1 - 8 * x1 + 7 * x1**2 - (7/3) * x1**3 + (1/4) * x1**4) * x2**2 * E**(-x2)":
|
|
xx1, xx2 = np.arange(0, 5, 0.25), np.arange(0, 5, 0.25)
|
|
else:
|
|
xx1, xx2 = np.arange(-5, 5, 0.25), np.arange(-5, 5, 0.25)
|
|
xx1, xx2 = np.meshgrid(xx1, xx2)
|
|
func = lambdify((x1, x2), sympify(self.wg_expr.value), "numpy")
|
|
fx = func(xx1, xx2)
|
|
fx_p0 = func(np.array(self.xn_p0_list)[:, 0], np.array(self.xn_p0_list)[:, 1])
|
|
fx_p1 = func(np.array(self.xn_p1_list)[:, 0], np.array(self.xn_p1_list)[:, 1])
|
|
|
|
#TODO: compute gradient
|
|
|
|
fig = make_subplots(rows=1, cols=1, specs=[[{'type': 'surface'}]])
|
|
fig.add_trace(go.Surface(contours = {"x": {"show": True}, "y":{"show": True}, "z":{"show": True}}, x=xx1, y=xx2, z=fx, opacity=0.8), row=1, col=1)
|
|
fig.add_trace(go.Scatter3d(x=np.array(self.xn_p0_list)[:, 0], y=np.array(self.xn_p0_list)[:, 1], z=fx_p0,
|
|
name="candidate 1", mode="lines+markers", marker=dict(size=5, color="green")), row=1, col=1)
|
|
fig.add_trace(go.Scatter3d(x=np.array(self.xn_p1_list)[:, 0], y=np.array(self.xn_p1_list)[:, 1], z=fx_p1,
|
|
name="candidate 2", mode="lines+markers", marker=dict(size=5, color="blue")), row=1, col=1)
|
|
frames = [go.Frame(data = [go.Surface(visible=True, showscale=False, opacity=0.8),
|
|
go.Scatter3d(x=np.array(self.xn_p0_list)[:self.timer, 0], y=np.array(self.xn_p0_list)[:self.timer, 1], z=fx_p0),
|
|
go.Scatter3d(x=np.array(self.xn_p1_list)[:self.timer, 0], y=np.array(self.xn_p1_list)[:self.timer, 1], z=fx_p1)],
|
|
traces=[0,1,2])]
|
|
fig.frames = frames
|
|
fig.update_layout(scene_aspectmode='manual', scene_aspectratio=dict(x=0, y=0, z=0), height=800)
|
|
fig.update_layout(legend=dict(yanchor="auto", y=0.9, xanchor="left", x=0.4))
|
|
fig.show() |