Esempio n. 1
0
    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_matrix_vector_field_product_2d():
    def field_vector(t, x):
        t = float(t)
        x = [float(y) for y in x]
        return x[1], -1 * x[0]

    def field_matrix(t, x):
        t = float(t)
        x = [float(y) for y in x]
        return 0.5, 0.6, x[0], 0.8

    def field_ground_product(t, x):
        t = float(t)
        x = [float(y) for y in x]
        return 0.5 * x[1] - 0.6 * x[0], x[0] * x[1] - 0.8 * x[0]

    v = np.zeros([20, 20, 2])
    jac = np.zeros([20, 20, 4])

    ground_jac_v = np.zeros([20, 20, 2])

    for i in range(0, 20):
        for j in range(0, 20):

            v[i, j, :] = field_vector(1, [i, j])
            jac[i, j, :] = field_matrix(1, [i, j])

            ground_jac_v[i, j, :] = field_ground_product(1, [i, j])

    jac_v = mat.matrix_vector_field_product(jac, v)

    assert_array_equal(jac_v.shape, np.array([20, 20, 2]))
    assert_array_equal(jac_v, ground_jac_v)
Esempio n. 3
0
def iterative_jacobian_product(vf, n):
    """
    :param vf: input SVF
    :param n: number of iterations
    :return: a new SVF defined by the jacobian product J_v^(n-1) v
    """
    jv_field = compute_jacobian(vf)[...]
    v_field = vf[...]

    jv_n_prod_v = matrices.matrix_vector_field_product(matrices.matrix_fields_product_iterative(jv_field, n-1), v_field)

    return jv_n_prod_v
Esempio n. 4
0
def jacobian_product(vf_left, vf_right):
    """
    Compute the jacobian product between two 2d or 3d SVF self and right: J_{self}(right)
    the results is a second SVF.
    :param vf_left : svf
    :param vf_right: svf
    :return: J_{right}(left) : jacobian product between 2 svfs
    """
    left  = np.copy(vf_left)
    right = np.copy(vf_right)

    result_array = matrices.matrix_vector_field_product(compute_jacobian(right), left)

    return result_array
Esempio n. 5
0
def scalar_dot_eulerian(sf_left,
                        vf_right_eul,
                        affine_left_right=None,
                        s_i_o=3,
                        mode='constant',
                        cval=0.0,
                        prefilter=False):

    omega_right = qr.get_omega(vf_right_eul)
    d = len(omega_right)

    if affine_left_right is not None:
        A_l, A_r = affine_left_right
        # multiply each point of the vector field by the transformation matrix
        vf_right_eul = matrices.matrix_vector_field_product(
            np.linalg.inv(A_l).dot(A_r), vf_right_eul)

    if d == 2:
        assert vf_right_eul.shape[:
                                  2] == sf_left.shape[::
                                                      -1], 'Shape inconsistency.'
        coord = [
            vf_right_eul[..., i].reshape(omega_right, order='F').T
            for i in range(d)
        ][::-1]
        result = np.zeros_like(sf_left)
    else:
        coord = [
            vf_right_eul[..., i].reshape(omega_right, order='F')
            for i in range(d)
        ]
        result = np.zeros_like(sf_left)

    ndimage.map_coordinates(sf_left,
                            coord,
                            output=result,
                            order=s_i_o,
                            mode=mode,
                            cval=cval,
                            prefilter=prefilter)

    return result
def test_matrix_vector_field_product_toy_example_3d():
    def field_vector(t, x):
        t = float(t)
        x = [float(y) for y in x]
        return 2 * x[1], 3 * x[0], x[0] - x[2]

    def field_matrix(t, x):
        t = float(t)
        x = [float(y) for y in x]
        return 0.5*x[0], 0.5*x[1], 0.5*x[2], \
               0.5,      x[0],     0.3,      \
               0.2*x[2], 3.0,      2.1*x[2]

    def field_ground_product(t, x):
        t = float(t)
        x = [float(y) for y in x]
        return 0.5*2*x[0]*x[1] + 0.5*3*x[0]*x[1] + 0.5*x[2]*(x[0] - x[2]), \
               0.5*2*x[1] + 3*x[0]*x[0] + 0.3*(x[0] - x[2]), \
               0.2*2*x[2]*x[1] + 3*3*x[0] + 2.1*x[2]*(x[0] - x[2])

    v = np.zeros([20, 20, 20, 3])
    jac = np.zeros([20, 20, 20, 9])

    ground_jac_v = np.zeros([20, 20, 20, 3])

    for i in range(0, 20):
        for j in range(0, 20):
            for k in range(0, 20):
                v[i, j, k, :] = field_vector(1, [i, j, k])
                jac[i, j, k, :] = field_matrix(1, [i, j, k])

                ground_jac_v[i, j, k, :] = field_ground_product(1, [i, j, k])

    jac_v = mat.matrix_vector_field_product(jac, v)

    assert_array_equal(jac_v.shape, np.array([20, 20, 20, 3]))
    assert_array_almost_equal(jac_v, ground_jac_v)
Esempio n. 7
0
    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
Esempio n. 8
0
def lagrangian_dot_eulerian(vf_left_lag,
                            vf_right_eul,
                            affine_left_right=None,
                            s_i_o=2,
                            mode='constant',
                            cval=0.0,
                            prefilter=True,
                            add_right=True):

    omega_right = qr.get_omega(vf_right_eul)
    d = len(omega_right)

    if affine_left_right is not None:
        A_l, A_r = affine_left_right
        vf_right_eul = matrices.matrix_vector_field_product(
            np.linalg.inv(A_l).dot(A_r), vf_right_eul)

    coord = [
        vf_right_eul[..., i].reshape(omega_right, order='F') for i in range(d)
    ]
    result = np.squeeze(np.zeros_like(vf_left_lag))

    for i in range(d):  # see if the for can be avoided with tests.

        ndimage.map_coordinates(np.squeeze(vf_left_lag[..., i]),
                                coord,
                                output=result[..., i],
                                order=s_i_o,
                                mode=mode,
                                cval=cval,
                                prefilter=prefilter)
    if add_right:  # option for the scaling and squaring.
        return result.reshape(
            vf_left_lag.shape) + cs.eulerian_to_lagrangian(vf_right_eul)
    else:
        return result.reshape(vf_left_lag.shape)