def figure_GSC_1(debug_print=False): A = np_array([4., 1, 1, 15]).reshape(2, 2) data1, data2, data3 = [], [], [] u = np_array([1., 1]) v = np_array([-0.5, 2]) w0, w1 = gram_schmidt_conjugation(A, [u, v]) assert_A_orthogonal(A, w0, w1) c = 2.3 u0 = w0 u1 = w1 + c * w0 du0, m1 = draw_vector_R2(u0, color='blue', name=py_text_sub('u', 0)) du1, m2 = draw_vector_R2(u1, color='blue', name=py_text_sub('u', 1)) data1.extend(du0) data1.extend(du1) dw0, m1 = draw_vector_R2(u1, t=w1, color='red') dw1, m2 = draw_vector_R2(w1, color='green') Au0 = A.dot(u0) Au0n = Au0 / norm(Au0) dAu0, m1 = draw_vector_R2(3.5 * Au0n, color='grey', name=py_text_sub('Au', 0)) data2.extend(dw0) data2.extend(dw1) data2.extend(du0) data2.extend(du1) data2.extend(dAu0) d0, d1 = gram_schmidt_conjugation(A, [u0, u1]) assert_A_orthogonal(A, d0, d1) dd0, m1 = draw_vector_R2(d0, color='blue', name=py_text_sub('d', '(0)')) dd1, m2 = draw_vector_R2(d1, color='blue', name=py_text_sub('d', '(1)')) data3.extend(dd0) data3.extend(dd1) m = np_max([m1, m2]) plot_it_R2_short_3in1(data1, data2, data3, axes_max1=m, axes_max2=m, axes_max3=m, title='GSC.Fig.1', filename='Fig_GSC_1.html') return
def figure_ISD_1(debug_print=False): steps = steepest_descent(A, b, x0) assert np_allclose(steps[:, -1], center.flatten() ), "steepest_descent didn't find the minimum point of f" for i in range(steps.shape[1] - 1): x_i = steps[:, i] r_i = b.flatten() - A.dot(x_i) x_ip1 = steps[:, i + 1] e_ip1 = x_ip1 - center.flatten() assert_A_orthogonal(A, r_i, e_ip1) text = [py_text_sub('x', '(0)'), py_text_sub('x', '(1)')] t2 = [''] * (steps.shape[1] - 3) text.extend(t2) text.append(py_text_sub('x', '(*)')) textposition = ['middle left', 'top right'] tp2 = ['top center'] * len(t2) textposition.extend(tp2) textposition.append('bottom center') plotly_data = [] r0 = b - A.dot(x0) alpha0 = innprd(r0, r0) / innprd(r0, A.dot(r0)) x1 = x0 + alpha0 * r0 r0_normalized = r0.flatten() / norm(r0) d, _ = qfc.prep_vector_data(r0_normalized, center=x0, M=None, color='rgb(0,140,0)', name=py_text_sub('r', '(0)')) plotly_data.extend(d) e1 = x1 - center d, _ = qfc.prep_vector_data(e1, center=center, M=None, color='rgb(0,140,0)', name=py_text_sub('e', '(1)'), textposition='bottom left') plotly_data.extend(d) draw_concentric_contours(steps, text, textposition, plotly_data=plotly_data, title='ISD.Fig.1', filename='Fig_ISD_1.html', debug_print=debug_print) return
def figure_CJDR_3(debug_print=False): M_inv_x0 = M_inv.dot(x0 - center) + center steps = np_hstack((M_inv_x0, center)) text = [py_text_sub('x', '(0)'), py_text_sub('x', '(*)')] textposition = ['middle left', 'bottom center'] draw_concentric_balls(steps, text, textposition, title='CJDR.Fig.3', filename='Fig_CJDR_3.html', steps_mode='text, markers', debug_print=debug_print) return
def figure_CJDR_4(debug_print=False): steps = compute_steps_in_ball_space() text = [ py_text_sub('x', '(0)'), py_text_sub('x', '(1)'), py_text_sub('x', '(*)') ] textposition = ['middle left', 'top center', 'bottom center'] draw_concentric_balls(steps, text, textposition, title='CJDR.Fig.4', filename='Fig_CJDR_4.html', debug_print=debug_print) return
def figure_CJDR_4(debug_print=False): steps = orthogonal_directions_with_standard_basis() text = [ py_text_sub('x', '(0)'), py_text_sub('x', '(1)'), py_text_sub('x', '(*)') ] textposition = ['middle left', 'top center', 'bottom center'] draw_concentric_balls(steps, text, textposition, title='CJDR.Fig.4', filename='Fig_CJDR_4.html', debug_print=debug_print) return
def figure_CJDR_5(debug_print=False): steps = compute_steps_in_ball_space() for i in [0, 1]: steps[:, i] = (M.dot(steps[:, i].reshape(2, 1) - center) + center).reshape(2, ) u = steps[:, 1] - steps[:, 0] v = steps[:, 2] - steps[:, 1] assert_A_orthogonal(A, u, v) text = [ py_text_sub('x', '(0)'), py_text_sub('x', '(1)'), py_text_sub('x', '(*)') ] textposition = ['middle left', 'top center', 'bottom center'] draw_concentric_contours(steps, text, textposition, title='CJDR.Fig.5', filename='Fig_CJDR_5.html', debug_print=debug_print) return
def figure_CJDR_1(debug_print=False): r0 = b - A.dot(x0) alpha0 = innprd(r0, r0) / innprd(r0, A.dot(r0)) x1 = x0 + alpha0 * r0 steps = np_hstack((x0, x1, center)) text = [ py_text_sub('x', '(0)'), py_text_sub('x', '(1)'), py_text_sub('x', '(*)') ] textposition = ['middle left', 'middle left', 'bottom center'] plotly_data = [] r0_normalized = r0.flatten() / norm(r0) d, _ = qfc.prep_vector_data(r0_normalized, center=x0, M=None, color='rgb(0,140,0)', name=py_text_sub('r', '(0)')) plotly_data.extend(d) Ar0 = A.dot(r0_normalized) d, _ = qfc.prep_vector_data(Ar0, center=x0, M=None, color='rgb(170,0,0)', name=py_text_sub('Ar', '(0)')) plotly_data.extend(d) e1 = x1 - center d, _ = qfc.prep_vector_data(e1, center=center, M=None, color='rgb(0,140,0)', name=py_text_sub('e', '(1)'), textposition='top right') plotly_data.extend(d) e1_normalized = e1.flatten() / norm(e1) d, _ = qfc.prep_vector_data(e1_normalized, center=x0, M=None, color='rgb(170,0,0)', name=py_text_sub('e', '(1)')) plotly_data.extend(d) assert_A_orthogonal(A, r0, -e1) d, _ = qfc.prep_vector_data(-e1_normalized, center=x0, M=None, color='rgb(170,0,0)', name=py_text_sub('-e', '(1)')) plotly_data.extend(d) draw_concentric_contours(steps, text, textposition, plotly_data=plotly_data, title='CJDR.Fig.1', filename='Fig_CJDR_1.html', steps_mode='text, markers', debug_print=debug_print) return
def draw_concentric_balls(steps, text, textposition, title, filename, steps_mode='lines, text, markers', debug_print=False): ply_data = [] ams = [] if debug_print: print("{}: steepest-descent: start at x0={}".format(title, x0)) print("number of steps for Steepest Descent={}".format(steps.shape[1])) for k, ec in zip(ks, ecs): expected_radius = compute_radius_after_dilating_ellipse_to_ball( alpha, beta, b, c, evals, evecs, k=k, phi_q=phi_1) _, am, E = qfc.level_k_ellipsoid(A, b, c, alpha, beta, k=k, ellipsoid_color=ec, show_eigenvectors=False, debug_print=debug_print) ams.append(am) d, am, E = qfc.ellipsoid_from_ellipsoid_and_map( E, name='radius={}'.format(rnd(expected_radius, 1)), color=ec, M=M_inv, center=center) for x in E.T: computed_radius = norm(x - center.flatten()) assert np_abs( computed_radius - expected_radius ) < 1e-9, \ "computed radius={} doesn't equal expected radius={}".format( computed_radius, expected_radius ) ply_data.append(d) ams.append(am) steps_ply_data = Scatter_R2(steps[0], steps[1], color='rgb(0,0,140)', width=1., mode=steps_mode, text=text, textposition=textposition, textfontsize=18, hoverinfo='x+y') ply_data.append(steps_ply_data) axes_max = np_max(np_abs(ams)) lds = qfc.prep_line_data_for_vectors(evecs, axes_max, center=center) ply_data.extend(lds) for i in range(2): d, _ = qfc.prep_vector_data(evecs[:, i], center=center, M=None, name=py_text_sub('v', i + 1)) ply_data.extend(d) plot_it_R2(ply_data, axes_max, title=title, filename=filename, buffer_scale=1., buffer_fixed=.1) return
def level_k_ellipsoid(self, A, b, c, alpha, beta, k, display_ellipsoid=True, ellipsoid_color=None, centered_at_origin=False, RTDR_variation='RTDR', show_eigenvectors=True, show_standard_basis=False, rotate_eigenvectors=False, rotate_standard_basis=False, eigenvector_color='rgb(0, 0, 255)', standard_basis_color='rgb(0, 140, 0)', debug_print=False, check_center=True, center_check_atol=1e-5): evals, evecs = get_eigens_for_positive_definite_matrix(A) if debug_print: print("original evecs=\n{}".format(evecs)) eigen_decomp = evecs.dot(np.diag(evals)).dot(evecs.T) assert np.allclose(A, eigen_decomp), "A not equal to eigen_decomp" evals, evecs = order_and_shift_eigens(A, evals, evecs, debug_print=debug_print) phi_k = compute_phi_k(k, alpha, beta, b, c, evals, evecs) d = compute_semi_axes_lengths(phi_k, alpha, evals) D = np.diag(d) if debug_print: print("The semi-axes lengths are {}".format(d)) computed_center = compute_center(alpha, beta, b, evals, evecs) if check_center: x0 = self._default_x0.reshape(computed_center.shape) self.check_center_equals_min(computed_center, x0, A, b, c, alpha, beta, atol=center_check_atol, debug_print=debug_print) center = self._origin if centered_at_origin else computed_center """ Next we compute a map from the eigenvectors to the standard basis """ R, es = self.compute_rotation_to_standard_basis( evecs, debug_print=debug_print) # R.T s/b first component in Eigendecomp eigen_decomp = R.T.dot(np.diag(evals)).dot(R) assert np.allclose( A, eigen_decomp), "A does not equal R^TSR\nA{}\ne={}".format( A, eigen_decomp) assert check_matrices_equal_except_column_sign( R.T, evecs), "R.T doesn't equal evecs\nR={}\ne={}".format(R, evecs) if debug_print: print("R^T=\n{}\nevecs=\n{}".format(R.T, evecs)) """ Now that we can easily map the eigenvectors to the standard basis vectors, we can just as easily go in reverse. We compute """ R_inv = np.linalg.inv(R) assert np.allclose( R_inv, R.T), "R_inv doesn't equal R.T" # s/b true since R is orthogonal assert np.allclose( R_inv.dot(es), evecs), "R_inv times standard basis not equal to evecs" if debug_print: print( "and R^T is a good map from the standard basis to the eigenvectors" ) ''' Let's check that the points on our level k ellipsoid satisfy the quadratic form f(x)=k ''' name = "f(x)={}".format(rnd( k, 1)) if RTDR_variation == 'RTDR' and np.allclose( center, computed_center) else None ell, mxell, E = self.ellipsoid_from_unit_ball_and_RTDR_variation( name=name, D=D, R=R, color=ellipsoid_color, center=computed_center) for col in range(E.shape[1]): x = E[:, col] f_x = quadratic_form(x, A, b, c, alpha, beta) assert np.abs(k - f_x) < 1e-8, "k={} and f_x={} are not equal".format( k, f_x) if debug_print: print("confirmed that f=k on level ellipsoid") ''' Lastly, let's assemble the plotly data for the ellipse, vectors, and lines ''' if display_ellipsoid and (RTDR_variation != 'RTDR' or centered_at_origin): ell, mxell, E = self.ellipsoid_from_unit_ball_and_RTDR_variation( name=name, D=D, R=R, color=ellipsoid_color, RTDR_variation=RTDR_variation, center=center) data = [] if not display_ellipsoid else [ell] axes_maxes = [center + 1., center - 1.] if not display_ellipsoid else [mxell] mr = np.max(axes_maxes) if debug_print: print("mr={} mxell={} all={}".format(mr, mxell, axes_maxes)) if show_eigenvectors: M = self.map_from_RTDR( D=D, R=R, RTDR_variation=RTDR_variation) if rotate_eigenvectors else None lds = self.prep_line_data_for_vectors(evecs, mr, center=center, M=M) data.extend(lds) elif show_standard_basis: M = self.map_from_RTDR(D=D, R=R, RTDR_variation=RTDR_variation ) if rotate_standard_basis else None lds = self.prep_line_data_for_vectors(es, mr, center=center, M=M) data.extend(lds) if show_eigenvectors: M = self.map_from_RTDR( D=D, R=R, RTDR_variation='RTR' if RTDR_variation == 'RTDR' else 'R') if rotate_eigenvectors else None for j in range(evecs.shape[1]): v, mx = self.prep_vector_data(evecs[:, j], center=center, M=M, color=eigenvector_color, name=py_text_sub('v', j + 1)) data.extend(v) axes_maxes.append(mx) if show_standard_basis: M = self.map_from_RTDR( D=D, R=R, RTDR_variation='RTR' if RTDR_variation == 'RTDR' else 'R') if rotate_standard_basis else None for j in range(es.shape[1]): v, mx = self.prep_vector_data(es[:, j], center=center, M=M, color=standard_basis_color, name=py_text_sub('e', j + 1)) data.extend(v) axes_maxes.append(mx) return data, mr, E