def update_integral_data(u_str, v_str, cx_str, cy_str): #string parsing u_fun, _ = my_bokeh_utils.string_to_function_parser(u_str, ['x', 'y']) v_fun, _ = my_bokeh_utils.string_to_function_parser(v_str, ['x', 'y']) cx_fun, cx_sym = my_bokeh_utils.string_to_function_parser(cx_str, ['t']) cy_fun, cy_sym = my_bokeh_utils.string_to_function_parser(cy_str, ['t']) from sympy import diff dcx_sym = diff(cx_sym,'t') dcy_sym = diff(cy_sym,'t') dcx_fun = my_bokeh_utils.sym_to_function_parser(dcx_sym, 't') dcy_fun = my_bokeh_utils.sym_to_function_parser(dcy_sym, 't') t = np.linspace(curveintegral_settings.parameter_min,curveintegral_settings.parameter_max) f_I = lambda xx, tt: (u_fun(cx_fun(tt),cy_fun(tt)) * dcx_fun(tt) + v_fun(cx_fun(tt),cy_fun(tt)) * dcy_fun(tt)) integrand = f_I(None,t) from scipy.integrate import odeint integral = odeint(f_I,0,t) source_integral.data = dict(t=t.tolist(), integral=integral.tolist(), integrand=integrand.tolist())
def update_point(): # Get the current slider value t0 = t_value_input.value f_x, f_x_sym = my_bokeh_utils.string_to_function_parser(x_component_input.value, ['t']) f_y, f_y_sym = my_bokeh_utils.string_to_function_parser(y_component_input.value, ['t']) t_min = leibnitz_settings.t_value_min t = np.linspace(t_min, t0, leibnitz_settings.resolution) # evaluation interval x = f_x(t) y = f_y(t) x = np.array([0] + x.tolist() + [0]) y = np.array([0] + y.tolist() + [0]) x0 = f_x(t0) y0 = f_y(t0) area = lf.calc_area(f_x_sym, f_y_sym, t0) # saving data to plot source_point.data = dict(x=[x0], y=[y0]) source_sector.data = dict(x=x, y=y) source_lines.data = dict(x_start=[0, f_x(t_min)], y_start=[0, f_y(t_min)], x_end=[0, f_x(t0)], y_end=[0, f_y(t0)]) source_text.data = dict(x=[f_x(t0)], y=[f_y(t0)], text=[str(round(area, 2))], text_color=['blue'])
def update_parameter_data(cx_str, cy_str, t): # string parsing cx_fun, cx_sym = my_bokeh_utils.string_to_function_parser(cx_str, ['t']) cy_fun, cy_sym = my_bokeh_utils.string_to_function_parser(cy_str, ['t']) from sympy import diff dcx_sym = diff(cx_sym, 't') dcy_sym = diff(cy_sym, 't') dcx_fun = my_bokeh_utils.sym_to_function_parser(dcx_sym, 't') dcy_fun = my_bokeh_utils.sym_to_function_parser(dcy_sym, 't') # crating sample x_val = cx_fun(t) y_val = cy_fun(t) dx_val = dcx_fun(t) dy_val = dcy_fun(t) xx, hx = np.linspace(source_view.data['x_start'][0], source_view.data['x_end'][0], curveintegral_settings.n_sample, retstep=True) ssdict, spdict, _ = my_bokeh_utils.quiver_to_data(x=np.array(x_val), y=np.array(y_val), u=np.array(dx_val), v=np.array(dy_val), h=2*hx, do_normalization=True, fix_at_middle=False) # save data source_param.data = dict(x=[x_val], y=[y_val], t=[t], x0=ssdict['x0'], y0=ssdict['y0'], x1=ssdict['x1'], y1=ssdict['y1'], xs=spdict['xs'], ys=spdict['ys']) print "curve point was updated with t=%f" % (t)
def init_data(): """ initializes the plots and interactor """ f, _ = my_bokeh_utils.string_to_function_parser(f_input.value, ['x', 'y']) contour_f.compute_contour_data(f) g, _ = my_bokeh_utils.string_to_function_parser(g_input.value, ['x', 'y']) contour_g.compute_contour_data(g, isovalue=[0]) interactor.update_to_user_view()
def update_curve_data(cx_str, cy_str): # string parsing cx_fun, _ = my_bokeh_utils.string_to_function_parser(cx_str, ['t']) cy_fun, _ = my_bokeh_utils.string_to_function_parser(cy_str, ['t']) # crating samples t_range = np.linspace(0, 1) x_val = cx_fun(t_range) y_val = cy_fun(t_range) # save data source_curve.data = dict(x=x_val, y=y_val) print "curve data was updated with c(t)=[%s,%s]" % (cx_str, cy_str)
def update_curve(): # parse x and y component f_x, _ = my_bokeh_utils.string_to_function_parser(x_component_input.value, ['t']) f_y, _ = my_bokeh_utils.string_to_function_parser(y_component_input.value, ['t']) t = np.linspace(leibnitz_settings.t_value_min, leibnitz_settings.t_value_max, leibnitz_settings.resolution) # evaluation interval x = f_x(t) y = f_y(t) # saving data to plot source_curve.data = dict(x=x, y=y)
def refresh_contour(): """ periodically called function that updates data with respect to the current user view, if the user view has changed. """ user_view_has_changed = my_bokeh_utils.check_user_view(source_view.data, plot) if user_view_has_changed: f, _ = my_bokeh_utils.string_to_function_parser(f_input.value, ['x', 'y']) g, _ = my_bokeh_utils.string_to_function_parser(g_input.value, ['x', 'y']) if len(source_mark.data['x']) > 0: # has any point been marked? compute_click_data() contour_f.compute_contour_data(f) contour_g.compute_contour_data(g, [0]) interactor.update_to_user_view() source_view.data = my_bokeh_utils.get_user_view(plot)
def update_streamline_data(u_str, v_str, x0, y0): """ updates the bokeh.models.ColumnDataSource holding the streamline data. :param u_str: string, first component of the ode :param v_str: string, second component of the ode :param x0: initial value x for the streamline :param y0: initial value y for the streamline :return: """ # string parsing u_fun, u_sym = my_bokeh_utils.string_to_function_parser(u_str,['x','y']) v_fun, v_sym = my_bokeh_utils.string_to_function_parser(v_str,['x','y']) # numerical integration chaotic = (sample_fun_input.value == "dixon") # for the dixon system a special treatment is necessary x_val, y_val = odesystem_helpers.do_integration(x0, y0, u_fun, v_fun, get_plot_bounds(plot), chaotic) # update sources streamline_to_data(x_val, y_val, x0, y0) # save data to ColumnDataSource print "streamline was calculated for initial value (x0,y0)=(%f,%f)" % (x0, y0)
def update_parameter_data(cx_str, cy_str, t): # string parsing cx_fun, cx_sym = my_bokeh_utils.string_to_function_parser(cx_str, ['t']) cy_fun, cy_sym = my_bokeh_utils.string_to_function_parser(cy_str, ['t']) from sympy import diff dcx_sym = diff(cx_sym, 't') dcy_sym = diff(cy_sym, 't') dcx_fun = my_bokeh_utils.sym_to_function_parser(dcx_sym, 't') dcy_fun = my_bokeh_utils.sym_to_function_parser(dcy_sym, 't') # crating sample x_val = cx_fun(t) y_val = cy_fun(t) dx_val = dcx_fun(t) dy_val = dcy_fun(t) xx, hx = np.linspace(source_view.data['x_start'][0], source_view.data['x_end'][0], curveintegral_settings.n_sample, retstep=True) ssdict, spdict, _ = my_bokeh_utils.quiver_to_data(x=np.array(x_val), y=np.array(y_val), u=np.array(dx_val), v=np.array(dy_val), h=2 * hx, do_normalization=True, fix_at_middle=False) # save data source_param.data = dict(x=[x_val], y=[y_val], t=[t], x0=ssdict['x0'], y0=ssdict['y0'], x1=ssdict['x1'], y1=ssdict['y1'], xs=spdict['xs'], ys=spdict['ys']) print "curve point was updated with t=%f" % (t)
def f_changed(attr, old, new): """ called if f input function changes """ # get new functions f, _ = my_bokeh_utils.string_to_function_parser(f_input.value, ['x', 'y']) # has any point been marked? if len(source_mark.data['x']) > 0: # projected point does not change, just recompute isocontour on f compute_click_data() # update contour data contour_f.compute_contour_data(f)
def update_quiver_data(u_str, v_str): """ updates the bokeh.models.ColumnDataSource_s holding the quiver data and the ciritical points and lines of the ode. :param u_str: string, first component of the ode :param v_str: string, second component of the ode :return: """ # string parsing u_fun, u_sym = my_bokeh_utils.string_to_function_parser(u_str,['x','y']) v_fun, v_sym = my_bokeh_utils.string_to_function_parser(v_str,['x','y']) # compute critical points x_c, y_c, x_lines, y_lines = odesystem_helpers.critical_points(u_sym, v_sym, get_plot_bounds(plot)) # crating samples x_val, y_val, u_val, v_val, h = get_samples(u_fun, v_fun) # update quiver w.r.t. samples quiver.compute_quiver_data(x_val, y_val, u_val, v_val, normalize=True) # save critical point data critical_to_data(x_c, y_c, x_lines, y_lines) print "quiver data was updated for u(x,y) = %s, v(x,y) = %s" % (u_str, v_str)
def g_changed(attr, old, new): """ called if g input function changes """ # get new functions g, _ = my_bokeh_utils.string_to_function_parser(g_input.value, ['x', 'y']) # has any point been marked? if len(source_mark.data['x']) > 0: # use clicked on point to recompute projection and recompute isocontour on f on_selection_change(None,None,None) # update contour data contour_g.compute_contour_data(g, isovalue=[0])
def update_quiver_data(u_str, v_str): """ updates the bokeh.models.ColumnDataSource_s holding the quiver data :param u_str: string, first component of the vector values function :param v_str: string, second component of the vector values function :return: """ # string parsing u_fun, _ = my_bokeh_utils.string_to_function_parser(u_str, ['x', 'y']) v_fun, _ = my_bokeh_utils.string_to_function_parser(v_str, ['x', 'y']) # crating samples x_val, y_val, u_val, v_val, h = get_samples(u_fun, v_fun) # generating quiver data and updating sources ssdict, spdict, sbdict = my_bokeh_utils.quiver_to_data(x=x_val, y=y_val, u=u_val, v=v_val, h=h, do_normalization=False) # save quiver data to respective ColumnDataSource_s source_segments.data = ssdict source_patches.data = spdict source_basept.data = sbdict print "quiver data was updated for u(x,y) = %s, v(x,y) = %s" % (u_str, v_str)
def update_quiver_data(u_str, v_str): """ updates the bokeh.models.ColumnDataSource_s holding the quiver data and the ciritical points and lines of the ode. :param u_str: string, first component of the ode :param v_str: string, second component of the ode :return: """ # string parsing u_fun, u_sym = my_bokeh_utils.string_to_function_parser(u_str, ['x', 'y']) v_fun, v_sym = my_bokeh_utils.string_to_function_parser(v_str, ['x', 'y']) # compute critical points x_c, y_c, x_lines, y_lines = odesystem_helpers.critical_points( u_sym, v_sym, get_plot_bounds(plot)) # crating samples x_val, y_val, u_val, v_val, h = get_samples(u_fun, v_fun) # update quiver w.r.t. samples quiver.compute_quiver_data(x_val, y_val, u_val, v_val, normalize=True) # save critical point data critical_to_data(x_c, y_c, x_lines, y_lines) print "quiver data was updated for u(x,y) = %s, v(x,y) = %s" % (u_str, v_str)
def update_streamline_data(u_str, v_str, x0, y0): """ updates the bokeh.models.ColumnDataSource holding the streamline data. :param u_str: string, first component of the ode :param v_str: string, second component of the ode :param x0: initial value x for the streamline :param y0: initial value y for the streamline :return: """ # string parsing u_fun, u_sym = my_bokeh_utils.string_to_function_parser(u_str, ['x', 'y']) v_fun, v_sym = my_bokeh_utils.string_to_function_parser(v_str, ['x', 'y']) # numerical integration chaotic = (sample_fun_input.value == "dixon" ) # for the dixon system a special treatment is necessary x_val, y_val = odesystem_helpers.do_integration(x0, y0, u_fun, v_fun, get_plot_bounds(plot), chaotic) # update sources streamline_to_data(x_val, y_val, x0, y0) # save data to ColumnDataSource print "streamline was calculated for initial value (x0,y0)=(%f,%f)" % (x0, y0)
def update_quiver_data(u_str, v_str): """ updates the bokeh.models.ColumnDataSource_s holding the quiver data :param u_str: string, first component of the vector values function :param v_str: string, second component of the vector values function :return: """ # string parsing u_fun, _ = my_bokeh_utils.string_to_function_parser(u_str, ['x', 'y']) v_fun, _ = my_bokeh_utils.string_to_function_parser(v_str, ['x', 'y']) # crating samples x_val, y_val, u_val, v_val, h = get_samples(u_fun, v_fun) # generating quiver data and updating sources ssdict, spdict, sbdict = my_bokeh_utils.quiver_to_data( x=x_val, y=y_val, u=u_val, v=v_val, h=h, do_normalization=False) # save quiver data to respective ColumnDataSource_s source_segments.data = ssdict source_patches.data = spdict source_basept.data = sbdict print "quiver data was updated for u(x,y) = %s, v(x,y) = %s" % (u_str, v_str)
def compute_click_data(): """ computes relevant data for the position clicked on: 1. gradients of objective function f(x,y) and constraint function g(x,y) 2. contour lines running through click location """ # get objective function and constraint function f, f_sym = my_bokeh_utils.string_to_function_parser(f_input.value, ['x', 'y']) g, g_sym = my_bokeh_utils.string_to_function_parser(g_input.value, ['x', 'y']) # compute gradients df, _ = my_bokeh_utils.compute_gradient(f_sym, ['x', 'y']) dg, _ = my_bokeh_utils.compute_gradient(g_sym, ['x', 'y']) # compute isovalue on click location x_mark = source_mark.data['x'][0] y_mark = source_mark.data['y'][0] isovalue = f(x_mark, y_mark) # update contour running through isovalue contour_f0.compute_contour_data(f, [isovalue]) # save gradient data h = (source_view.data['x_end'][0] - source_view.data['x_start'][0]) / 5.0 x, y, u, v = get_samples(df, x_mark, y_mark) quiver_isolevel.compute_quiver_data(x, y, u, v, h=h, scaling=1) x, y, u, v = get_samples(dg, x_mark, y_mark) quiver_constraint.compute_quiver_data(x, y, u, v, h=h, scaling=1)
def on_selection_change(attr, old, new): """ called if the by click selected point changes """ # detect clicked point x_coor, y_coor = interactor.clicked_point() if x_coor is not None: # get constraint function g, _ = my_bokeh_utils.string_to_function_parser(g_input.value, ['x', 'y']) # project point onto constraint x_close, y_close = my_bokeh_utils.find_closest_on_iso(x_coor, y_coor, g) # save to mark source_mark.data = dict(x=[x_close], y=[y_close]) # update influenced data compute_click_data()