Example #1
0
def tensor_eigenvalues(g):
    """

    :param g: tensor
    :return: eigenvalues of the tensor

    """
    import numpy as np
    import clinica.pipelines.machine_learning_spatial_svm.spatial_svm_utils as utils
    g = np.array(g)

    if g.shape[0] < 4:
        # condition if we have a tensor

        C1 = np.ones(len(np.ravel(g[0][0])))
        buff = -utils.tensor_trace(g)
        C2 = buff.flatten('F')
        buff = utils.tensor_trace(utils.tensor_product(g, g))
        buff = (- 0.5 * (buff.flatten('F') - np.multiply(C2, C2)))
        C3 = buff.flatten('F')
        buff = -utils.tensor_determinant(g)
        C4 = buff.flatten('F')

        C = np.array([C1, C2, C3, C4])
        rts = utils.roots_poly(C)

    else:
        print('Degree too big : not still implemented')

    rts2 = rts.real.copy()
    rts2.sort()

    lamb = np.zeros(shape=(g.shape[0], g.shape[2], g.shape[3], g.shape[4]), dtype='complex128')

    for i in range(g.shape[0]):
        lamb[i, :, :, :] = rts2[:, i].reshape(g.shape[2], g.shape[3], g.shape[4], order='F')

    # lamb[0] is the smallest eigenvalues, lamb[2] is the biggest
    return lamb
Example #2
0
def roots_poly(C):
    """

    :param C: coefficients. If C has N+1 components, the polynomial is C(1)*X^N + ... + C(N) * X + C(N+1)
    :return: roots of the polynomial

    the functions find the polynomial roots. It computes the roots of the polynomail whose coefficients are the elements of the vector C?
    """
    import cmath
    import math

    import numpy as np

    import clinica.pipelines.machine_learning_spatial_svm.spatial_svm_utils as utils

    C = np.array(C)
    if C.shape[0] < 2:
        rts = []

    elif C.shape[0] < 3:
        rts = -C[:, 1] * (1 / C[:, 0])

    elif C.shape[0] < 4:
        # implementation of delta
        delta = np.array(
            [
                cmath.sqrt((C[1, i] * C[1, i]) - (4 * C[0, i] * C[2, i]))
                for i in range(C.shape[1])
            ]
        )
        # two roots
        rts1 = (-C[1, :] + delta) * (1 / ((2 * C[0, :])))
        rts2 = (-C[1, :] - delta) * (1 / ((2 * C[0, :])))
        rts = np.array([rts1, rts2])

    elif C.shape[0] < 5:
        # implementation of the method of Cardan

        a = C[0, :]
        b = C[1, :]
        c = C[2, :]
        d = C[3, :]

        p = -b * b * (1 / (3 * a * a)) + c * (1 / a)
        q = b * (1 / (27.0 * a)) * (2 * b * b * (1 / (a * a)) - 9 * c * (1 / a)) + d * (
            1 / a
        )

        new_roots = np.array([np.ones((q.shape[0])), q, -(p * p * p) / 27])

        rts = utils.roots_poly(new_roots)

        u = rts[0, :]
        u_mod = abs(u) ** (1 / 3)
        u_angle = np.angle(u) * (1 / 3)

        v = rts[1, :]
        v_mod = abs(v) ** (1 / 3)
        v_angle = np.angle(v) * (1 / 3)

        rts = np.zeros([C.shape[1], 3], dtype="complex128")

        ind = np.zeros([u.shape[0]], dtype="int32")

        for k in [0, 1, 2]:
            u = u_mod * np.power(math.e, 1j * (u_angle + k * 2 * math.pi * (1 / 3)))
            u = np.array(u)

            for r in [0, 1, 2]:
                v = v_mod * np.power(math.e, 1j * (v_angle + r * 2 * math.pi * (1 / 3)))

                ind2 = abs(u * v + p * 1 / 3) < 1e-10

                rts[ind2, ind[ind2]] = u[ind2] + v[ind2] - b[ind2] * (1 / (3 * a[ind2]))

                ind[ind2] = np.minimum(2, ind[ind2] + 1)

    else:
        print("For degree > 3 use roots ")

    return rts