Exemplo n.º 1
0
def cov_integral(alpha, alphadot, basis, T=100, k=5):
    """
    Calculates covariance along path alpha

    :param alpha: numpy ndarray of shape (2,M) of M samples (first curve)
    :param alphadot: numpy ndarray of shape (2,M) of M samples
    :param basis: list numpy ndarray of shape (2,M) of M samples
    :param T: Number of samples of curve (Default = 100)
    :param k: number of samples along path (Default = 5)

    :rtype: numpy ndarray
    :return u: covariance

    """
    u = zeros((2, T, k))

    for tau in range(1, k):
        w = u[:, :, tau-1]
        q1 = alpha[:, :, tau-1]
        q2 = alpha[:, :, tau]
        b = basis[tau]
        wbar = cf.parallel_translate(w, q1, q2, b)
        u[:, :, tau] = (1./(k-1))*alphadot[:, :, tau]+wbar

    return(u)
Exemplo n.º 2
0
def back_parallel_transport(u1, alpha, basis, T=100, k=5):
    """
    backwards parallel translates q1 and q2 along manifold

    :param u1: numpy ndarray of shape (2,M) of M samples
    :param alpha: numpy ndarray of shape (2,M) of M samples
    :param basis: list numpy ndarray of shape (2,M) of M samples
    :param T: Number of samples of curve (Default = 100)
    :param k: number of samples along path (Default = 5)

    :rtype: numpy ndarray
    :return utilde: translated vector

    """
    utilde = zeros((2, T, k))

    utilde[:, :, k-1] = u1
    for tau in arange(k-2, -1, -1):
        w = utilde[:, :, tau+1]
        q1 = alpha[:, :, tau+1]
        q2 = alpha[:, :, tau]
        b = basis[tau]
        utilde[:, :, tau] = cf.parallel_translate(w, q1, q2, b)

    return(utilde)
Exemplo n.º 3
0
def back_parallel_transport(u1, alpha, basis, T=100, k=5):
    """
    backwards parallel translates q1 and q2 along manifold

    :param u1: numpy ndarray of shape (2,M) of M samples
    :param alpha: numpy ndarray of shape (2,M) of M samples
    :param basis: list numpy ndarray of shape (2,M) of M samples
    :param T: Number of samples of curve (Default = 100)
    :param k: number of samples along path (Default = 5)

    :rtype: numpy ndarray
    :return utilde: translated vector

    """
    utilde = zeros((2, T, k))

    utilde[:, :, k - 1] = u1
    for tau in arange(k - 2, -1, -1):
        w = utilde[:, :, tau + 1]
        q1 = alpha[:, :, tau + 1]
        q2 = alpha[:, :, tau]
        b = basis[tau]
        utilde[:, :, tau] = cf.parallel_translate(w, q1, q2, b)

    return utilde
Exemplo n.º 4
0
def cov_integral(alpha, alphadot, basis, T=100, k=5):
    """
    Calculates covariance along path alpha

    :param alpha: numpy ndarray of shape (2,M) of M samples (first curve)
    :param alphadot: numpy ndarray of shape (2,M) of M samples
    :param basis: list numpy ndarray of shape (2,M) of M samples
    :param T: Number of samples of curve (Default = 100)
    :param k: number of samples along path (Default = 5)

    :rtype: numpy ndarray
    :return u: covariance

    """
    u = zeros((2, T, k))

    for tau in range(1, k):
        w = u[:, :, tau - 1]
        q1 = alpha[:, :, tau - 1]
        q2 = alpha[:, :, tau]
        b = basis[tau]
        wbar = cf.parallel_translate(w, q1, q2, b)
        u[:, :, tau] = (1.0 / (k - 1)) * alphadot[:, :, tau] + wbar

    return u
Exemplo n.º 5
0
def sample_shapes(mu, K, mode='O', no=3, numSamp=10):
    """
    Computes sample shapes from mean and covariance

    :param betamean: numpy ndarray of shape (n, M) describing the mean curve
    :param mu: numpy ndarray of shape (n, M) describing the mean srvf
    :param K: numpy ndarray of shape (M, M) describing the covariance
    :param mode: Open ('O') or closed curve ('C') (default 'O')
    :param no: number of direction (default 3)
    :param numSamp: number of samples (default 10)

    :rtype: tuple of numpy array
    :return samples: sample shapes

    """
    n, T = mu.shape
    modes = ['O', 'C']
    mode = [i for i, x in enumerate(modes) if x == mode]
    if len(mode) == 0:
        mode = 0
    else:
        mode = mode[0]

    U, s, V = svd(K)

    if mode == 0:
        N = 2
    else:
        N = 10

    epsilon = 1./(N-1)

    samples = empty(numSamp, dtype=object)
    for i in range(0, numSamp):
        v = zeros((2, T))
        for m in range(0, no):
            v = v + randn()*sqrt(s[m])*vstack((U[0:T, m], U[T:2*T, m]))

        q1 = mu
        for j in range(0, N-1):
            normv = sqrt(cf.innerprod_q2(v, v))

            if normv < 1e-4:
                q2 = mu
            else:
                q2 = cos(epsilon*normv)*q1+sin(epsilon*normv)*v/normv
                if mode == 1:
                    q2 = cf.project_curve(q2)

            # Parallel translate tangent vector
            basis2 = cf.find_basis_normal(q2)
            v = cf.parallel_translate(v, q1, q2, basis2, mode)

            q1 = q2

        samples[i] = cf.q_to_curve(q2)

    return(samples)
Exemplo n.º 6
0
def sample_shapes(mu, K, mode='O', no=3, numSamp=10):
    """
    Computes sample shapes from mean and covariance

    :param betamean: numpy ndarray of shape (n, M) describing the mean curve
    :param mu: numpy ndarray of shape (n, M) describing the mean srvf
    :param K: numpy ndarray of shape (M, M) describing the covariance
    :param mode: Open ('O') or closed curve ('C') (default 'O')
    :param no: number of direction (default 3)
    :param numSamp: number of samples (default 10)

    :rtype: tuple of numpy array
    :return samples: sample shapes

    """
    n, T = mu.shape
    modes = ['O', 'C']
    mode = [i for i, x in enumerate(modes) if x == mode]
    if len(mode) == 0:
        mode = 0
    else:
        mode = mode[0]

    U, s, V = svd(K)

    if mode == 0:
        N = 2
    else:
        N = 10

    epsilon = 1./(N-1)

    samples = empty(numSamp, dtype=object)
    for i in range(0, numSamp):
        v = zeros((2, T))
        for m in range(0, no):
            v = v + randn()*sqrt(s[m])*vstack((U[0:T, m], U[T:2*T, m]))

        q1 = mu
        for j in range(0, N-1):
            normv = sqrt(cf.innerprod_q2(v, v))

            if normv < 1e-4:
                q2 = mu
            else:
                q2 = cos(epsilon*normv)*q1+sin(epsilon*normv)*v/normv
                if mode == 1:
                    q2 = cf.project_curve(q2)

            # Parallel translate tangent vector
            basis2 = cf.find_basis_normal(q2)
            v = cf.parallel_translate(v, q1, q2, basis2, mode)

            q1 = q2

        samples[i] = cf.q_to_curve(q2)

    return(samples)
Exemplo n.º 7
0
    def sample_shapes(self, no=3, numSamp=10):
        """
        Computes sample shapes from mean and covariance

        :param no: number of direction (default 3)
        :param numSamp: number of samples (default 10)
        """
        n, T = self.q_mean.shape
        modes = ['O', 'C']
        mode = [i for i, x in enumerate(modes) if x == self.mode]
        if len(mode) == 0:
            mode = 0
        else:
            mode = mode[0]

        U, s, V = svd(self.C)

        if mode == 0:
            N = 2
        else:
            N = 10

        epsilon = 1. / (N - 1)

        samples = empty(numSamp, dtype=object)
        for i in range(0, numSamp):
            v = zeros((2, T))
            for m in range(0, no):
                v = v + randn() * sqrt(s[m]) * vstack(
                    (U[0:T, m], U[T:2 * T, m]))

            q1 = self.q_mean
            for j in range(0, N - 1):
                normv = sqrt(cf.innerprod_q2(v, v))

                if normv < 1e-4:
                    q2 = self.q_mean
                else:
                    q2 = cos(epsilon * normv) * q1 + sin(
                        epsilon * normv) * v / normv
                    if mode == 1:
                        q2 = cf.project_curve(q2)

                # Parallel translate tangent vector
                basis2 = cf.find_basis_normal(q2)
                v = cf.parallel_translate(v, q1, q2, basis2, mode)

                q1 = q2

            samples[i] = cf.q_to_curve(q2)

        self.samples = samples
        return
Exemplo n.º 8
0
def curve_principal_directions(betamean, mu, K, mode='O', no=3, N=5):
    """
    Computes principal direction of variation specified by no. N is
    Number of shapes away from mean. Creates 2*N+1 shape sequence

    :param betamean: numpy ndarray of shape (n, M) describing the mean curve
    :param mu: numpy ndarray of shape (n, M) describing the mean srvf
    :param K: numpy ndarray of shape (M, M) describing the covariance
    :param mode: Open ('O') or closed curve ('C') (default 'O')
    :param no: number of direction (default 3)
    :param N: number of shapes (2*N+1) (default 5)

    :rtype: tuple of numpy array
    :return pd: principal directions

    """
    n, T = betamean.shape
    modes = ['O', 'C']
    mode = [i for i, x in enumerate(modes) if x == mode]
    if len(mode) == 0:
        mode = 0
    else:
        mode = mode[0]

    U, s, V = svd(K)

    qarray = empty((no, 2*N+1), dtype=object)
    qarray1 = empty(N, dtype=object)
    qarray2 = empty(N, dtype=object)
    pd = empty((no, 2*N+1), dtype=object)
    pd1 = empty(N, dtype=object)
    pd2 = empty(N, dtype=object)
    for m in range(0, no):
        princDir = vstack((U[0:T, m], U[T:2*T, m]))
        v = sqrt(s[m]) * princDir
        q1 = mu
        epsilon = 2./N

        # Forward direction from mean
        for i in range(0, N):
            normv = sqrt(cf.innerprod_q2(v, v))

            if normv < 1e-4:
                q2 = mu
            else:
                q2 = cos(epsilon*normv)*q1 + sin(epsilon*normv)*v/normv
                if mode == 1:
                    q2 = cf.project_curve(q2)

            qarray1[i] = q2
            p = cf.q_to_curve(q2)
            centroid1 = -1*cf.calculatecentroid(p)
            beta_scaled, scale = cf.scale_curve(p + tile(centroid1, [T, 1]).T)
            pd1[i] = beta_scaled

            # Parallel translate tangent vector
            basis2 = cf.find_basis_normal(q2)
            v = cf.parallel_translate(v, q1, q2, basis2, mode)

            q1 = q2

        # Backward direction from mean
        v = -sqrt(s[m])*princDir
        q1 = mu
        for i in range(0, N):
            normv = sqrt(cf.innerprod_q2(v, v))

            if normv < 1e-4:
                q2 = mu
            else:
                q2 = cos(epsilon*normv)*q1+sin(epsilon*normv)*v/normv
                if mode == 1:
                    q2 = cf.project_curve(q2)

            qarray2[i] = q2
            p = cf.q_to_curve(q2)
            centroid1 = -1*cf.calculatecentroid(p)
            beta_scaled, scale = cf.scale_curve(p + tile(centroid1, [T, 1]).T)
            pd2[i] = beta_scaled

            # Parallel translate tangent vector
            basis2 = cf.find_basis_normal(q2)
            v = cf.parallel_translate(v, q1, q2, basis2, mode)

            q1 = q2

        for i in range(0, N):
            qarray[m, i] = qarray2[(N-1)-i]
            pd[m, i] = pd2[(N-1)-i]

        qarray[m, N] = mu
        centroid1 = -1*cf.calculatecentroid(betamean)
        beta_scaled, scale = cf.scale_curve(betamean +
                                            tile(centroid1, [T, 1]).T)
        pd[m, N] = beta_scaled

        for i in range(N+1, 2*N+1):
            qarray[m, i] = qarray1[i-(N+1)]
            pd[m, i] = pd1[i-(N+1)]

    return(pd)
Exemplo n.º 9
0
def curve_principal_directions(betamean, mu, K, mode='O', no=3, N=5):
    """
    Computes principal direction of variation specified by no. N is
    Number of shapes away from mean. Creates 2*N+1 shape sequence

    :param betamean: numpy ndarray of shape (n, M) describing the mean curve
    :param mu: numpy ndarray of shape (n, M) describing the mean srvf
    :param K: numpy ndarray of shape (M, M) describing the covariance
    :param mode: Open ('O') or closed curve ('C') (default 'O')
    :param no: number of direction (default 3)
    :param N: number of shapes (2*N+1) (default 5)

    :rtype: tuple of numpy array
    :return pd: principal directions

    """
    n, T = betamean.shape
    modes = ['O', 'C']
    mode = [i for i, x in enumerate(modes) if x == mode]
    if len(mode) == 0:
        mode = 0
    else:
        mode = mode[0]

    U, s, V = svd(K)

    qarray = empty((no, 2*N+1), dtype=object)
    qarray1 = empty(N, dtype=object)
    qarray2 = empty(N, dtype=object)
    pd = empty((no, 2*N+1), dtype=object)
    pd1 = empty(N, dtype=object)
    pd2 = empty(N, dtype=object)
    for m in range(0, no):
        princDir = vstack((U[0:T, m], U[T:2*T, m]))
        v = sqrt(s[m]) * princDir
        q1 = mu
        epsilon = 2./N

        # Forward direction from mean
        for i in range(0, N):
            normv = sqrt(cf.innerprod_q2(v, v))

            if normv < 1e-4:
                q2 = mu
            else:
                q2 = cos(epsilon*normv)*q1 + sin(epsilon*normv)*v/normv
                if mode == 1:
                    q2 = cf.project_curve(q2)

            qarray1[i] = q2
            p = cf.q_to_curve(q2)
            centroid1 = -1*cf.calculatecentroid(p)
            beta_scaled, scale = cf.scale_curve(p + tile(centroid1, [T, 1]).T)
            pd1[i] = beta_scaled

            # Parallel translate tangent vector
            basis2 = cf.find_basis_normal(q2)
            v = cf.parallel_translate(v, q1, q2, basis2, mode)

            q1 = q2

        # Backward direction from mean
        v = -sqrt(s[m])*princDir
        q1 = mu
        for i in range(0, N):
            normv = sqrt(cf.innerprod_q2(v, v))

            if normv < 1e-4:
                q2 = mu
            else:
                q2 = cos(epsilon*normv)*q1+sin(epsilon*normv)*v/normv
                if mode == 1:
                    q2 = cf.project_curve(q2)

            qarray2[i] = q2
            p = cf.q_to_curve(q2)
            centroid1 = -1*cf.calculatecentroid(p)
            beta_scaled, scale = cf.scale_curve(p + tile(centroid1, [T, 1]).T)
            pd2[i] = beta_scaled

            # Parallel translate tangent vector
            basis2 = cf.find_basis_normal(q2)
            v = cf.parallel_translate(v, q1, q2, basis2, mode)

            q1 = q2

        for i in range(0, N):
            qarray[m, i] = qarray2[(N-1)-i]
            pd[m, i] = pd2[(N-1)-i]

        qarray[m, N] = mu
        centroid1 = -1*cf.calculatecentroid(betamean)
        beta_scaled, scale = cf.scale_curve(betamean +
                                            tile(centroid1, [T, 1]).T)
        pd[m, N] = beta_scaled

        for i in range(N+1, 2*N+1):
            qarray[m, i] = qarray1[i-(N+1)]
            pd[m, i] = pd1[i-(N+1)]

    return(pd)