Exemplo n.º 1
0
def id_eulerian(omega, t=1):
    """
    :param omega: discretized domain of the vector field
    :param t: number of timepoints
    :return: identity vector field of given domain and timepoints, in Eulerian coordinates.
    """
    d = qr.check_omega(omega)
    omega = list(omega)
    v_shape = qr.shape_from_omega_and_timepoints(omega, t=t)
    id_vf = np.zeros(v_shape)

    if d == 2:
        x = range(v_shape[0])
        y = range(v_shape[1])
        gx, gy = np.meshgrid(x, y, indexing='ij')

        id_vf[..., 0, :, 0] = np.repeat(gx, t).reshape(omega + [t])
        id_vf[..., 0, :, 1] = np.repeat(gy, t).reshape(omega + [t])

    elif d == 3:
        x = range(v_shape[0])
        y = range(v_shape[1])
        z = range(v_shape[2])
        gx, gy, gz = np.meshgrid(x, y, z, indexing='ij')

        id_vf[..., :, 0] = np.repeat(gx, t).reshape(omega + [t])
        id_vf[..., :, 1] = np.repeat(gy, t).reshape(omega + [t])
        id_vf[..., :, 2] = np.repeat(gz, t).reshape(omega + [t])

    return id_vf
Exemplo n.º 2
0
def id_lagrangian(omega, t=1):
    """
    :param omega: discretized domain of the vector field
    :param t: number of timepoints
    :return: identity vector field of given domain and timepoints, in Lagrangian coordinates.
    """
    d = qr.check_omega(omega)
    vf_shape = list(omega) + [1] * (3 - d) + [t, d]
    return np.zeros(vf_shape)
Exemplo n.º 3
0
def id_matrices(omega, t=1):
    """
    From a omega of dimension dim =2,3, it returns the identity field
    that at each point of the omega has the (row mayor) vectorized identity matrix.
    :param omega: a squared or cubed omega
    :param t: timepoint
    :return: vector field with a vectorised identity matrix at each point.
    """
    d = qr.check_omega(omega)

    shape = list(omega) + [1] * (4 - d) + [d**2]
    shape[3] = t
    flat_id = np.eye(d).reshape(1, d**2)
    return np.repeat(flat_id, np.prod(list(omega) + [t])).reshape(shape, order='F')
Exemplo n.º 4
0
def test_check_omega_ok():
    assert qr.check_omega((10, 11, 12)) == 3
    assert qr.check_omega((10, 11)) == 2
Exemplo n.º 5
0
def test_check_omega_wrong_dimension1():
    with assert_raises(IOError):
        qr.check_omega((10, ))
Exemplo n.º 6
0
def test_check_omega_type():
    with assert_raises(IOError):
        qr.check_omega((10, 10, 10.2))
Exemplo n.º 7
0
def generate_from_matrix(omega, input_matrix, t=1, structure='algebra'):
    """
    :param omega: domain of the vector field.
    :param input_matrix: matrix generating the transformation of the vector field representing elements form groups
    SE(3), SE(2) or algebras so(3) and so(2).
    :param t: 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)
    v_shape = qr.shape_from_omega_and_timepoints(omega, t)
    vf = np.zeros(v_shape)

    if structure == 'algebra':
        pass
    elif structure == 'group':
        input_matrix = input_matrix - np.eye(input_matrix.shape[0])
    else:
        raise IOError

    if d == 2:

        if not np.alltrue(input_matrix.shape == (3, 3)):
            raise IOError('Omega dimension not compatible with the matrix dimension')

        vf = cs.affine_to_homogeneous(gen_id.id_eulerian(omega))

        x_intervals, y_intervals = omega
        for i in range(x_intervals):
            for j in range(y_intervals):
                vf[i, j, 0, 0, :] = input_matrix.dot(vf[i, j, 0, 0, :])

        vf = cs.homogeneous_to_affine(vf)

    elif d == 3:
        # If the matrix provides a 2d rototranslation, we consider the rotation axis perpendicular to the plane z=0.
        # this must be improved for 3d rotations in the space.
        x_intervals, y_intervals, z_intervals = omega

        if np.alltrue(input_matrix.shape == (3, 3)):

            # Create the slice at the ground of the domain (x,y,z) , z = 0, as a 2d rotation:
            base_slice = cs.affine_to_homogeneous(gen_id.id_eulerian(list(omega[:2])))

            for i in range(x_intervals):
                for j in range(y_intervals):
                    base_slice[i, j, 0, 0, :] = input_matrix.dot(base_slice[i, j, 0, 0, :])

            # Copy the slice at the ground on all the others:
            for k in range(z_intervals):
                vf[..., k, 0, :2] = base_slice[..., 0, 0, :2]

        # If the matrix is 3d the rotation axis is perpendicular to the plane z=0.
        elif np.alltrue(input_matrix.shape == (4, 4)):

            vf = cs.affine_to_homogeneous(gen_id.id_eulerian(omega))

            for i in range(x_intervals):
                for j in range(y_intervals):
                    for k in range(z_intervals):
                        vf[i, j, k, 0, :] = input_matrix.dot(vf[i, j, k, 0, :])

            vf = cs.homogeneous_to_affine(vf)
        else:
            raise IOError('Wrong input matrix shape. Must be 3x3 or 4x4.')

    return vf
Exemplo n.º 8
0
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.")