def test_theory_inverse_log_exp(): any_angle_1 = uniform(-np.pi + np.abs(np.spacing(-np.pi)), np.pi) any_tx_1 = uniform(-10, 10) any_ty_1 = uniform(-10, 10) a = se2.Se2A(any_angle_1, any_tx_1, any_ty_1) ans = se2.se2g_log(se2.se2a_exp(a)) assert_array_almost_equal(a.get, ans.get)
def test_se2_g_log_pade_approx_comparison(): theta = uniform(-np.pi, np.pi) tx = uniform(-5, 5) ty = uniform(-5, 5) element = se2.Se2G(theta, tx, ty) ans_log = se2.se2g_log(element).get_matrix ans_pade = lin.logm(element.get_matrix) assert_array_almost_equal(ans_log, ans_pade)
def test_se2_g_log_0_angle(): theta = 0 tx = uniform(-5, 5) ty = uniform(-5, 5) element = se2.Se2G(theta, tx, ty) ans_log = se2.se2g_log(element) if ans_log.rotation_angle == 0 and ans_log.tx == tx and ans_log.ty == ty: assert True else: assert False
def randomgen_linear_by_taste(sigma, taste, center=(0, 0)): """ To create a linear (2D) stationary tangent vector field according to the proposed taste classification: + Taste 1 : real eigenvalues with positive signs. UNSTABLE NODE + Taste 2 : real eigenvalues with negative signs. STABLE NODE + Taste 3 : real eigenvalues with opposite signs. SADDLE + Taste 4 : complex conjugate with positive real part. OUTWARD SPIRAL + Taste 5 : complex conjugate with negative real part. INWARD SPIRAL + Taste 6 : complex conjugate with 0 real parts. CIRCLES, Based on se2.Se2G :param sigma: how further away going from identity. :param taste: int between 1 and 6 as in the classification. :param center: (float, float) center of the transformation. :return: 3x3 tangent space linear transformation matrix of the shape | R | t | | - - - | | 0 | 0 | """ if taste not in range(1, 7): raise IOError('taste must be an integer number between 1 and 6.') if taste == 6: x_c, y_c = center theta = sigma * np.random.randn() + 2 * sigma tx = (1 - np.cos(theta)) * x_c + np.sin(theta) * y_c ty = -np.sin(theta) * x_c + (1 - np.cos(theta)) * y_c m0 = se2.Se2G(theta, tx, ty) dm0 = se2.se2g_log(m0) return dm0.get_matrix else: found = False rot = np.zeros([2, 2]) while not found: rot = np.random.randn(2, 2) if get_taste(rot - np.eye(2)) == taste: found = True dm = np.zeros([3, 3]) dm[:2, :2] = (1 / sigma) * rot tx = (1 - dm[0, 0]) * center[0] - dm[0, 1] * center[1] ty = -dm[1, 0] * center[0] + (1 - dm[1, 1]) * center[1] dm[:2, 2] = np.array([tx, ty]) dm = dm - np.eye(3) dm[2, 2] = 0 return dm
if params['deformation_model'] == 'translation': svf_0 = np.zeros(list(omega)[::-1] + [1, 1, 2]) svf_0[..., 0] = 10 svf_0[..., 1] = 20 elif params['deformation_model'] == 'rotation': x_c, y_c = [c / 2 for c in omega] theta = np.pi / 8 tx = (1 - np.cos(theta)) * x_c + np.sin(theta) * y_c ty = -np.sin(theta) * x_c + (1 - np.cos(theta)) * y_c m_0 = se2.Se2G(theta, tx, ty) dm_0 = se2.se2g_log(m_0) print(m_0.get_matrix) print('') print(dm_0.get_matrix) # Generate subsequent vector fields flow = gen.generate_from_matrix(list(omega)[::-1], m_0.get_matrix, structure='group') svf_0 = gen.generate_from_matrix(list(omega)[::-1], dm_0.get_matrix, structure='algebra') elif params['deformation_model'] == 'linear': taste = 1 beta = 0.5 x_c, y_c = [c / 2 for c in omega]
def test_theory_inverse_log_exp_input_not_in_quotient(): any_angle_1 = 2 * np.pi + uniform(-np.pi + np.abs(np.spacing(-np.pi)), np.pi) any_tx_1 = uniform(-10, 10) any_ty_1 = uniform(-10, 10) a = se2.Se2A(any_angle_1, any_tx_1, any_ty_1) ans = se2.se2g_log(se2.se2a_exp(a)) assert_array_almost_equal(a.get, ans.get) ### Deformation and displacement Methods # # # def test_deformation_and_displacement_passages_from_matrices(): # # passing from deformation to displacement and vice versa using a matrix as # # ground truth. # domain = (16, 16) # theta, tx, ty = np.pi / 6, 2.5, -2 # m_0 = se2_g.se2_g(theta, tx, ty) # dm_0 = se2_g.log(m_0) # # print dm_0.get_matrix # print m_0.get_matrix # # ### generate subsequent vector fields # svf_0 = SVF.generate_from_matrix(domain, dm_0.get_matrix, affine=np.eye(4)) # # # This provides the displacement since I am subtracting the id. # disp_0 = SDISP.generate_from_matrix(domain, m_0.get_matrix - np.eye(3), affine=np.eye(4)) # # # This provides the deformation since I am not subtracting the id # def_0 = SDISP.generate_from_matrix(domain, m_0.get_matrix, affine=np.eye(4)) # # # I generate the deformation from the displacement using deformation_from_displacement # def_generated_0 = SDISP.deformation_from_displacement(disp_0) # # # I generate the displacement from the deformation using displacement_from_deformation # disp_generated_0 = SDISP.displacement_from_deformation(def_0) # # assert_array_almost_equal(def_0.field, def_generated_0.field) # assert_array_almost_equal(disp_0.field, disp_generated_0.field) # # # # def test_invariance_under_linear_translations_for_projective_svf(): # # random_seed = 5 # # if random_seed > 0: # np.random.seed(random_seed) # # domain = (10, 10) # # # Algebra # # generate a 2 projective vector field up to a linear translation and verify that they are the same: # h_a = ProjectiveAlgebra.randomgen(d=2) # # svf_h1 = SVF.generate_from_projective_matrix_algebra(input_vol_ext=domain, input_h=h_a.matrix) # svf_h2 = SVF.generate_from_projective_matrix_algebra(input_vol_ext=domain, input_h=h_a.matrix - 17*np.eye(3)) # # assert_array_almost_equal(svf_h1.field, svf_h2.field) # # # Group # # generate a 2 projective vector field up to a scalar factor and verify that they are the same: # h_g = h_a.exponentiate() # # # generate the corresponding disp # disp_h1 = SDISP.generate_from_projective_matrix_group(input_vol_ext=domain, input_exp_h=h_g.matrix) # disp_h2 = SDISP.generate_from_projective_matrix_group(input_vol_ext=domain, input_exp_h=5*h_g.matrix) # # assert_array_almost_equal(disp_h1.field, disp_h2.field) # # test_invariance_under_linear_translations_for_projective_svf() # # # test_deformation_and_displacement_passages_from_matrices() # test_theory_inverse_exp_log()
def test_visual_assessment_method_one_se2(show=False): """ :param show: to add the visualisation of a figure. This test is for visual assessment. Please put show to True. Aimed to test the prototyping of the computation of the exponential map with some methods. (Nothing is saved in external folder.) """ ############## # controller # ############## domain = (20, 20) x_c = 10 y_c = 10 theta = np.pi / 8 tx = (1 - np.cos(theta)) * x_c + np.sin(theta) * y_c ty = -np.sin(theta) * x_c + (1 - np.cos(theta)) * y_c passepartout = 5 spline_interpolation_order = 3 l_exp = lie_exp.LieExp() l_exp.s_i_o = spline_interpolation_order methods_list = [ l_exp.scaling_and_squaring, l_exp.gss_ei, l_exp.gss_ei_mod, l_exp.gss_aei, l_exp.midpoint, l_exp.series, l_exp.euler, l_exp.euler_aei, l_exp.euler_mod, l_exp.heun, l_exp.heun_mod, l_exp.rk4, l_exp.gss_rk4, l_exp.trapeziod_euler, l_exp.trapezoid_midpoint, l_exp.gss_trapezoid_euler, l_exp.gss_trapezoid_midpoint ] # ----- # model # ----- m_0 = se2.Se2G(theta, tx, ty) dm_0 = se2.se2g_log(m_0) # -- generate subsequent vector fields svf_0 = gen.generate_from_matrix(domain, dm_0.get_matrix, structure='algebra') sdisp_0 = gen.generate_from_matrix(domain, m_0.get_matrix, structure='group') # -- compute exponential with different available methods: sdisp_list = [] res_time = np.zeros(len(methods_list)) for num_met, met in enumerate(methods_list): start = time.time() sdisp_list.append(met(svf_0, input_num_steps=10)) res_time[num_met] = (time.time() - start) # ---- # view # ---- print('--------------------') print('Norm of the svf: ') print(qr.norm(svf_0, passe_partout_size=4)) print('--------------------') print("Norm of the displacement field:") print(qr.norm(sdisp_0, passe_partout_size=4)) print('--------------------') print('Norm of the errors: ') print('--------------------') for num_met in range(len(methods_list)): err = qr.norm(sdisp_list[num_met] - sdisp_0, passe_partout_size=passepartout) print('|{0:>22} - disp| = {1}'.format(methods_list[num_met].__name__, err)) if methods_list[num_met].__name__ == 'euler': assert err < 3 else: assert err < 0.5 print('---------------------') print('Computational Times: ') print('---------------------') if show: title_input_l = ['Sfv Input', 'Ground Output'] + methods_list fields_list = [svf_0, sdisp_0] + sdisp_list list_fields_of_field = [[svf_0], [sdisp_0]] list_colors = ['r', 'b'] for third_field in fields_list[2:]: list_fields_of_field += [[svf_0, sdisp_0, third_field]] list_colors += ['r', 'b', 'm'] fields_comparisons.see_n_fields_special( list_fields_of_field, fig_tag=50, row_fig=5, col_fig=5, input_figsize=(14, 7), colors_input=list_colors, titles_input=title_input_l, sample=(1, 1), zoom_input=[0, 20, 0, 20], window_title_input='matrix generated svf') plt.show()