def gss_aei(self, input_vf, input_num_steps=None, input_pix_dims=None): """ generalised scaling and squaring approximated exponential integrators """ # (0) self.initialise_input(input_vf) self.initialise_number_of_steps(input_num_steps=input_num_steps, input_pix_dims=input_pix_dims) # (1) if self.num_steps == 0: self.phi = self.vf else: init = 1 << self.num_steps self.phi = self.vf / init # (1.5) phi = 1 + v + 0.5jac*v jv = np.squeeze(jac.compute_jacobian(self.phi)) v_sq = np.squeeze(self.phi) new_shape = list( self.omega) + [1] * (4 - self.dimension) + [self.dimension] jv_prod_v = matrices.matrix_vector_field_product( jv, v_sq).reshape(new_shape) self.phi += 0.5 * jv_prod_v # (2) for _ in range(0, self.num_steps): self.phi = cp.lagrangian_dot_lagrangian(self.phi, self.phi, s_i_o=self.s_i_o) return self.phi
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 gss_ei(self, input_vf, input_num_steps=None, input_pix_dims=None): """ generalised scaling and squaring exponetial integrator """ # (0) self.initialise_input(input_vf) self.initialise_number_of_steps(input_num_steps=input_num_steps, input_pix_dims=input_pix_dims) # (1) init = 1 << self.num_steps self.phi = self.vf / init # (1.5) jv = jac.compute_jacobian(self.phi) if self.dimension == 2: v_matrix = np.array([0.0] * 3 * 3).reshape([3, 3]) for x in range(self.phi.shape[0]): for y in range(self.phi.shape[1]): # skew symmetric part v_matrix[0:2, 0:2] = jv[x, y, 0, 0, :].reshape([2, 2]) # translational part v_matrix[0, 2], v_matrix[1, 2] = self.phi[x, y, 0, 0, 0:2] # + \ # jv[x, y, 0, 0, :].reshape([2, 2]).dot([x, y]) # translational part of the exp is the answer: self.phi[x, y, 0, 0, :] = expm(v_matrix)[0:2, 2] elif self.dimension == 3: v_matrix = np.array([0.0] * 4 * 4).reshape([4, 4]) for x in range(self.phi.shape[0]): for y in range(self.phi.shape[1]): for z in range(self.phi.shape[2]): # skew symmetric part v_matrix[0:3, 0:3] = jv[x, y, z, 0, :].reshape([3, 3]) # translation part v_matrix[0, 3], v_matrix[1, 3], v_matrix[2, 3] = self.phi[x, y, z, 0, 0:3] self.phi[x, y, z, 0, :] = expm(v_matrix)[0:3, 3] # (2) for _ in range(0, self.num_steps): self.phi = cp.lagrangian_dot_lagrangian(self.phi, self.phi, s_i_o=self.s_i_o) return self.phi
def gss_ei_mod(self, input_vf, input_num_steps=None, input_pix_dims=None): """ generalised scaling and squaring exponential integrators modified """ # (0) self.initialise_input(input_vf) self.initialise_number_of_steps(input_num_steps=input_num_steps, input_pix_dims=input_pix_dims) # (1) copy the reduced v in phi, future solution of the ODE. init = 1 << self.num_steps self.phi = self.vf / init # (1.5) jv = jac.compute_jacobian(self.phi) if self.dimension == 2: for x in range(self.phi.shape[0]): for y in range(self.phi.shape[1]): j = jv[x, y, 0, 0, :].reshape([2, 2]) tr = self.phi[x, y, 0, 0, 0:2] j_tr = j.dot(tr) self.phi[x, y, 0, 0, :] = tr + 0.5 * j_tr # + 1/6. * J.dot(J_tr) elif self.dimension == 3: for x in range(self.phi.shape[0]): for y in range(self.phi.shape[1]): for z in range(self.phi.shape[2]): j = jv[x, y, z, 0, :].reshape([3, 3]) tr = self.phi[x, y, z, 0, 0:3] j_tr = j.dot(tr) self.phi[ x, y, z, 0, :] = tr + 0.5 * j_tr # + 1/6. * j.dot(j_tr) # (2) for _ in range(0, self.num_steps): self.phi = cp.lagrangian_dot_lagrangian(self.phi, self.phi, s_i_o=self.s_i_o) return self.phi
def euler_aei(self, input_vf, input_num_steps=None, input_pix_dims=None): """ euler with approximated exponential integrators """ # (0) self.initialise_input(input_vf) self.initialise_number_of_steps(input_num_steps=input_num_steps, input_pix_dims=input_pix_dims) self.vf = self.vf / self.num_steps jv = np.squeeze(jac.compute_jacobian(self.vf)) v_sq = np.squeeze(self.vf) new_shape = list( self.omega) + [1] * (4 - self.dimension) + [self.dimension] jv_prod_v = matrices.matrix_vector_field_product( jv, v_sq).reshape(new_shape) self.vf += 0.5 * jv_prod_v for _ in range(self.num_steps): self.phi = cp.lagrangian_dot_lagrangian(self.vf, self.phi, s_i_o=self.s_i_o) return self.phi