def test_2_random_vector_fields_svf(get_figures=False): """ The composition is not the identity since we are working in the tangent space. """ dec = 3 passe_partout = 5 omega = (10, 10) svf_f = gen_id.id_lagrangian(omega=omega) svf_f_inv = np.copy(-1 * svf_f) f_o_f_inv = cp.lagrangian_dot_lagrangian(svf_f, svf_f_inv, add_right=True) f_inv_o_f = cp.lagrangian_dot_lagrangian(svf_f_inv, svf_f, add_right=True) svf_id = gen_id.id_lagrangian(omega=omega) # # results of a composition of 2 lagrangian must be a lagrangian zero field assert_array_almost_equal(f_o_f_inv[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], svf_id[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], decimal=dec) assert_array_almost_equal(f_inv_o_f[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], svf_id[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], decimal=dec) if get_figures: fields_at_the_window.see_field(svf_f, fig_tag=51) fields_at_the_window.see_field( svf_f_inv, fig_tag=51, input_color='r', title_input='2 vector fields: f blue, g red') fields_at_the_window.see_field(svf_f, fig_tag=52) fields_at_the_window.see_field(svf_f_inv, fig_tag=52, input_color='r') fields_at_the_window.see_field( f_o_f_inv, fig_tag=52, input_color='g', title_input='composition (f o f^(-1)) in green') fields_at_the_window.see_field(svf_f, fig_tag=53) fields_at_the_window.see_field(svf_f_inv, fig_tag=53, input_color='r') fields_at_the_window.see_field( f_inv_o_f, fig_tag=53, input_color='g', title_input='composition (f^(-1) o f) in green') plt.show()
def test_jacobian_toy_field_3(): clear_cache() def field_f(t, x): t = float(t) x = [float(y) for y in x] return x[0]**2 + 2 * x[0] + x[1], 3.0 * x[0] + 2.0 def jacobian_f(t, x): t = float(t) x = [float(y) for y in x] return 2.0 * x[0] + 2.0, 1.0, 3.0, 0.0 svf_f = gen_id.id_lagrangian(omega=(30, 30)) jac_f_ground = jac.initialise_jacobian(svf_f) for i in range(0, 30): for j in range(0, 30): svf_f[i, j, 0, 0, :] = field_f(1, [i, j]) jac_f_ground[i, j, 0, 0, :] = jacobian_f(1, [i, j]) jac_f_numeric = jac.compute_jacobian(svf_f) pp = 2 assert_array_almost_equal(jac_f_ground[pp:-pp, pp:-pp, 0, 0, :], jac_f_numeric[pp:-pp, pp:-pp, 0, 0, :])
def test_jacobian_toy_field_2(): clear_cache() def field_f(t, x): t = float(t) x = [float(y) for y in x] return 0.5 * x[0] + 0.6 * x[1], 0.8 * x[1] def jacobian_f(t, x): t = float(t) x = [float(y) for y in x] return 0.5, 0.6, 0.0, 0.8 svf_f = gen_id.id_lagrangian(omega=(20, 20)) jac_f_ground = jac.initialise_jacobian(svf_f) for i in range(0, 20): for j in range(0, 20): svf_f[i, j, 0, 0, :] = field_f(1, [i, j]) jac_f_ground[i, j, 0, 0, :] = jacobian_f(1, [i, j]) jac_f_numeric = jac.compute_jacobian(svf_f) square_size = range(0, 20) assert_array_almost_equal(jac_f_ground[square_size, square_size, 0, 0, :], jac_f_numeric[square_size, square_size, 0, 0, :])
def test_2_less_easy_vector_fields(get_figures=False): dec = 1 # decimal for the error passe_partout = 3 omega = (20, 20) svf_zeros = gen_id.id_lagrangian(omega) svf_f = gen_id.id_lagrangian(omega) svf_f_inv = gen_id.id_lagrangian(omega) def function_f(t, x): t = float(t) x = [float(y) for y in x] return np.array([np.sin(0.01 * x[1]), (3 * np.cos(x[0])) / (x[0] + 2)]) for x in range(20): for y in range(20): svf_f[x, y, 0, 0, :] = function_f(1, [x, y]) svf_f_inv[x, y, 0, 0, :] = -1 * function_f(1, [x, y]) f_o_f_inv = cp.lagrangian_dot_lagrangian(svf_f, svf_f_inv, add_right=True) f_inv_o_f = cp.lagrangian_dot_lagrangian(svf_f_inv, svf_f, add_right=True) assert_array_almost_equal(f_o_f_inv[10, 10, 0, 0, :], [.0, .0], decimal=dec) assert_array_almost_equal(f_inv_o_f[10, 10, 0, 0, :], [.0, .0], decimal=dec) # results of a composition assert_array_almost_equal(f_o_f_inv[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], svf_zeros[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], decimal=dec) assert_array_almost_equal(f_inv_o_f[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], svf_zeros[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], decimal=dec) if get_figures: fields_at_the_window.see_field(svf_f) fields_at_the_window.see_field( svf_f_inv, input_color='r', title_input='2 vector fields: f blue, g red') fields_at_the_window.see_field(svf_f, fig_tag=2) fields_at_the_window.see_field(svf_f_inv, fig_tag=2) fields_at_the_window.see_field( f_o_f_inv, fig_tag=2, input_color='g', title_input='composition (f o f^(-1)) in green') fields_at_the_window.see_field(svf_f, fig_tag=3) fields_at_the_window.see_field(svf_f_inv, fig_tag=3, input_color='r') fields_at_the_window.see_field( f_inv_o_f, fig_tag=3, input_color='g', title_input='composition (f^(-1) o f) in green') plt.show()
def test_controlled_composition_of_two_closed_form_vector_fields_2d_1( get_figures=False): omega = (30, 30) dec = 1 passe_partout = 10 def u(x, y): return 0, 0 def v(x, y): return 1, 1 def u_dot_v(x, y): return 0, 0 def v_dot_u(x, y): return 1, 1 svf_u = gen_id.id_lagrangian(omega=omega) svf_v = gen_id.id_lagrangian(omega=omega) svf_u_dot_v = gen_id.id_lagrangian(omega=omega) svf_v_dot_u = gen_id.id_lagrangian(omega=omega) for x in range(omega[0]): for y in range(omega[1]): svf_u[x, y, 0, 0, :] = u(x, y) svf_v[x, y, 0, 0, :] = v(x, y) svf_u_dot_v[x, y, 0, 0, :] = u_dot_v(x, y) svf_v_dot_u[x, y, 0, 0, :] = v_dot_u(x, y) svf_u_dot_v_numerical = cp.lagrangian_dot_lagrangian(svf_u, svf_v, add_right=False) svf_v_dot_u_numerical = cp.lagrangian_dot_lagrangian(svf_v, svf_u, add_right=False) if get_figures: fields_at_the_window.see_field(svf_u, fig_tag=62) fields_at_the_window.see_field(svf_v, fig_tag=62, input_color='r') fields_at_the_window.see_field(svf_u_dot_v, fig_tag=62, input_color='g', title_input='(u o v) closed form') fields_at_the_window.see_field(svf_u, fig_tag=63) fields_at_the_window.see_field(svf_v, fig_tag=63, input_color='r') fields_at_the_window.see_field(svf_u_dot_v_numerical, fig_tag=63, input_color='g', title_input='(u o v) numerical') fields_at_the_window.see_field(svf_u, fig_tag=64) fields_at_the_window.see_field(svf_v, fig_tag=64, input_color='r') fields_at_the_window.see_field( svf_v_dot_u, fig_tag=64, input_color='g', title_input='composition v o u closed form') fields_at_the_window.see_field(svf_u, fig_tag=65) fields_at_the_window.see_field(svf_v, fig_tag=65, input_color='r') fields_at_the_window.see_field( svf_v_dot_u_numerical, fig_tag=65, input_color='g', title_input='composition v o u numerical') plt.show() assert_array_almost_equal( svf_u_dot_v[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], svf_u_dot_v_numerical[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], decimal=dec) assert_array_almost_equal( svf_v_dot_u[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], svf_v_dot_u_numerical[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], decimal=dec)
def test_2_random_vector_fields_as_deformations(get_figures=False): dec = 1 passe_partout = 3 omega = (15, 15) sigma_init = 4 sigma_gaussian_filter = 2 svf_zeros = gen_id.id_lagrangian(omega) svf_0 = gen.generate_random(omega, parameters=(sigma_init, sigma_gaussian_filter)) l_exp = lie_exp.LieExp() sdisp_0 = l_exp.scaling_and_squaring(svf_0) sdisp_0_inv = l_exp.scaling_and_squaring(-1 * svf_0) f_o_f_inv = cp.lagrangian_dot_lagrangian(sdisp_0, sdisp_0_inv, add_right=True) f_inv_o_f = cp.lagrangian_dot_lagrangian(sdisp_0_inv, sdisp_0, add_right=True) # results of a composition of 2 lagrangian must be a lagrangian zero field assert_array_almost_equal(f_o_f_inv[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], svf_zeros[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], decimal=dec) assert_array_almost_equal(f_inv_o_f[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], svf_zeros[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], decimal=dec) if get_figures: fields_at_the_window.see_field(sdisp_0, fig_tag=61) fields_at_the_window.see_field( sdisp_0_inv, fig_tag=61, input_color='r', title_input='2 displacement fields: f blue, g red') fields_at_the_window.see_field(sdisp_0, fig_tag=62) fields_at_the_window.see_field(sdisp_0_inv, fig_tag=62, input_color='r') fields_at_the_window.see_field( f_o_f_inv, fig_tag=62, input_color='g', title_input='composition (f o f^(-1)) in green') fields_at_the_window.see_field(sdisp_0, fig_tag=63) fields_at_the_window.see_field(sdisp_0_inv, fig_tag=63, input_color='r') fields_at_the_window.see_field( f_inv_o_f, fig_tag=63, input_color='g', title_input='composition (f^(-1) o f) in green') plt.show()
def test_less_easy_composition_with_identity(get_figures=False): dec = 0 # decimal for the error passe_partout = 4 omega = (20, 25) svf_zeros = gen_id.id_lagrangian(omega=omega) svf_f = gen_id.id_lagrangian(omega=omega) svf_id = gen_id.id_lagrangian(omega=omega) def function_f(t, x): t = float(t) x = [float(y) for y in x] return np.array([np.sin(0.01 * x[1]), (3 * np.cos(x[0])) / (x[0] + 2)]) for x in range(20): for y in range(20): svf_f[x, y, 0, 0, :] = function_f(1, [x, y]) f_o_id = cp.lagrangian_dot_lagrangian(svf_f, svf_id, add_right=True) id_o_f = cp.lagrangian_dot_lagrangian(svf_id, svf_f, add_right=True) # test if the compositions are still in lagrangian coordinates, as attributes and as shape assert_array_almost_equal(f_o_id[5, 5, 0, 0, :], function_f(1, [5, 5]), decimal=dec) assert_array_almost_equal(id_o_f[5, 5, 0, 0, :], function_f(1, [5, 5]), decimal=dec) # results of a composition of 2 lagrangian must be a lagrangian zero field assert_array_almost_equal(f_o_id[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], svf_zeros[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], decimal=dec) assert_array_almost_equal(id_o_f[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], svf_zeros[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], decimal=dec) if get_figures: fields_at_the_window.see_field(svf_f, fig_tag=41) fields_at_the_window.see_field( svf_id, fig_tag=41, input_color='r', title_input='2 vector fields: f blue, g red') fields_at_the_window.see_field(svf_f, fig_tag=42) fields_at_the_window.see_field(svf_id, fig_tag=42, input_color='r') fields_at_the_window.see_field( f_o_id, fig_tag=42, input_color='g', title_input='composition (f o id) in green') fields_at_the_window.see_field(svf_f, fig_tag=43) fields_at_the_window.see_field(svf_id, fig_tag=43, input_color='r') fields_at_the_window.see_field( id_o_f, fig_tag=43, input_color='g', title_input='composition (id o f) in green') plt.show()
def test_easy_composition_with_identity(get_figures=False): dec = 6 passe_partout = 0 omega = (10, 10) svf_zeros = gen_id.id_lagrangian(omega) svf_f = gen_id.id_lagrangian(omega) svf_id = gen_id.id_lagrangian( omega) # id in lagrangian coordinates is the zero field def function_f(t, x): t = float(t) x = [float(y) for y in x] return np.array([0, 0.3]) for x in range(10): for y in range(10): svf_f[x, y, 0, 0, :] = function_f(1, [x, y]) f_o_id = cp.lagrangian_dot_lagrangian(svf_f, svf_id, add_right=True) id_o_f = cp.lagrangian_dot_lagrangian(svf_id, svf_f, add_right=True) # sfv_0 is provided in Lagrangian coordinates! if get_figures: fields_at_the_window.see_field(svf_f, fig_tag=21) fields_at_the_window.see_field( svf_id, fig_tag=21, input_color='r', title_input='2 vector fields: f blue, g red') fields_at_the_window.see_field(svf_f, fig_tag=22) fields_at_the_window.see_field(svf_id, fig_tag=22, input_color='r') fields_at_the_window.see_field( f_o_id, fig_tag=22, input_color='g', title_input='composition (f o id) in green') fields_at_the_window.see_field(svf_f, fig_tag=23) fields_at_the_window.see_field(svf_id, fig_tag=23, input_color='r') fields_at_the_window.see_field( id_o_f, fig_tag=23, input_color='g', title_input='composition (id o f) in green') plt.show() # test if the compositions are still in lagrangian coordinates, as attributes and as shape assert_array_almost_equal(f_o_id[5, 5, 0, 0, :], function_f(1, [5, 5]), decimal=dec) assert_array_almost_equal(id_o_f[5, 5, 0, 0, :], function_f(1, [5, 5]), decimal=dec) # results of a composition of 2 lagrangian must be a lagrangian zero field assert_array_almost_equal(f_o_id[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], svf_zeros[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], decimal=dec) assert_array_almost_equal(id_o_f[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], svf_zeros[passe_partout:-passe_partout, passe_partout:-passe_partout, 0, 0, :], decimal=dec)
def see_one_slice(input_vf, anatomical_plane='axial', h_slice=0, sample=(1, 1), window_title_input='quiver', title_input='2d vector field', long_title=False, fig_tag=1, scale=1, subtract_id=False, input_color='b', annotate=None, annotate_position=(1, 1)): qr.check_is_vf(input_vf) d = input_vf.shape[-1] if not d == 2: raise TypeError('See field 2d works only for 2d to 2d fields.') id_field = gen_id.id_lagrangian(list(input_vf.shape[:d])) fig = plt.figure(fig_tag) ax0 = fig.add_subplot(111) fig.canvas.set_window_title(window_title_input) input_field_copy = copy.deepcopy(input_vf) if subtract_id: input_field_copy -= id_field if anatomical_plane == 'axial': ax0.quiver(id_field[::sample[0], ::sample[1], h_slice, 0, 0], id_field[::sample[0], ::sample[1], h_slice, 0, 1], input_field_copy[::sample[0], ::sample[1], h_slice, 0, 0], input_field_copy[::sample[0], ::sample[1], h_slice, 0, 1], color=input_color, linewidths=0.01, width=0.03, scale=scale, scale_units='xy', units='xy', angles='xy') ax0.set_xlabel('x') ax0.set_ylabel('y') elif anatomical_plane == 'sagittal': ax0.quiver(id_field[::sample[0], h_slice, ::sample[1], 0, 0], id_field[::sample[0], h_slice, ::sample[1], 0, 1], input_field_copy[::sample[0], h_slice, ::sample[1], 0, 0], input_field_copy[::sample[0], h_slice, ::sample[1], 0, 1], color=input_color, linewidths=0.01, width=0.03, units='xy', angles='xy', scale=scale, scale_units='xy') elif anatomical_plane == 'coronal': ax0.quiver(id_field[h_slice, ::sample[0], ::sample[1], 0, 0], id_field[h_slice, ::sample[0], ::sample[1], 0, 1], input_field_copy[h_slice, ::sample[0], ::sample[1], 0, 0], input_field_copy[h_slice, ::sample[0], ::sample[1], 0, 1], color=input_color, linewidths=0.01, width=0.03, units='xy', angles='xy', scale=scale, scale_units='xy') else: raise TypeError('Anatomical_plane must be axial, sagittal or coronal') ax0.xaxis.grid(True, linestyle='-', which='major', color='lightgrey', alpha=0.5) ax0.yaxis.grid(True, linestyle='-', which='major', color='lightgrey', alpha=0.5) ax0.set_axisbelow(True) if long_title: ax0.set_title(title_input + ', ' + str(anatomical_plane) + ' plane, slice ' + str(h_slice)) else: ax0.set_title(title_input) if annotate is not None: ax0.text(annotate_position[0], annotate_position[1], annotate) plt.axes().set_aspect('equal', 'datalim') return fig
def test_vf_identity_lagrangian_ok_3d_timepoints(): assert_array_equal(gen_id.id_lagrangian((50, 49, 48), t=3), np.zeros((50, 49, 48, 3, 3)))
def test_vf_identity_lagrangian_ok_3d(): assert_array_equal(gen_id.id_lagrangian((50, 49, 48)), np.zeros((50, 49, 48, 1, 3)))
def test_vf_identity_lagrangian_ok_2d(): assert_array_equal(gen_id.id_lagrangian((50, 50)), np.zeros((50, 50, 1, 1, 2)))
def test_vf_identity_lagrangian_bad_input(): with assert_raises(IOError): gen_id.id_lagrangian((50, 50, 1, 1))
def generate_from_projective_matrix(omega, input_h, t=1, structure='algebra'): """ :param omega: domain of the vector field. :param input_h: matrix representing an element form the homography group. :param t: number of timepoints. :param structure: can be 'algebra' or 'group'. :return: vector field with the given input parameters. """ if t > 1: # TODO raise IndexError('Random generator not defined (yet) for multiple time points') d = qr.check_omega(omega) if structure == 'algebra': if d == 2: idd = gen_id.id_eulerian(omega) vf = gen_id.id_lagrangian(omega) idd = coord.affine_to_homogeneous(idd) x_intervals, y_intervals = omega for i in range(x_intervals): for j in range(y_intervals): vf[i, j, 0, 0, 0] = input_h[0, :].dot(idd[i, j, 0, 0, :]) - i * input_h[2, :].dot(idd[i, j, 0, 0, :]) vf[i, j, 0, 0, 1] = input_h[1, :].dot(idd[i, j, 0, 0, :]) - j * input_h[2, :].dot(idd[i, j, 0, 0, :]) return vf elif d == 3: idd = gen_id.id_eulerian(omega) vf = gen_id.id_lagrangian(omega) idd = coord.affine_to_homogeneous(idd) x_intervals, y_intervals, z_intervals = omega for i in range(x_intervals): for j in range(y_intervals): for k in range(z_intervals): vf[i, j, k, 0, 0] = input_h[0, :].dot(idd[i, j, k, 0, :]) - i * input_h[3, :].dot(idd[i, j, k, 0, :]) vf[i, j, k, 0, 1] = input_h[1, :].dot(idd[i, j, k, 0, :]) - j * input_h[3, :].dot(idd[i, j, k, 0, :]) vf[i, j, k, 0, 2] = input_h[2, :].dot(idd[i, j, k, 0, :]) - k * input_h[3, :].dot(idd[i, j, k, 0, :]) return vf elif structure == 'group': if d == 2: vf = gen_id.id_lagrangian(omega) x_intervals, y_intervals = omega for i in range(x_intervals): for j in range(y_intervals): s = input_h.dot(np.array([i, j, 1]))[:] if abs(s[2]) > 1e-5: # subtract the id to have the result in displacement coordinates vf[i, j, 0, 0, :] = (s[0:2] / float(s[2])) - np.array([i, j]) return vf elif d == 3: vf = gen_id.id_lagrangian(omega) x_intervals, y_intervals, z_intervals = omega for i in range(x_intervals): for j in range(y_intervals): for k in range(z_intervals): s = input_h.dot(np.array([i, j, k, 1]))[:] if abs(s[3]) > 1e-5: vf[i, j, k, 0, :] = (s[0:3] / float(s[3])) - np.array([i, j, k]) return vf else: raise IOError("structure can be only 'algebra' or 'group' corresponding to the algebraic structure.")