""" Other functions that  are Anthony's functions"""

from Analysis.AnthoRPhytoClus import *


def inv_dist(data, nb_bases):
    """ This function computes the invariant distance matrix to orientation

        Input : data is the matrix containing Fourier coefficients in column
                nb_bases is the number of basis functions for each profil (Fourier)

        Output : inv_dist_profil is the matrix of pairwise distances invariant to orientation

        Others : vec_inv is a vector of length of the number of bases
                 inv_coeff is the inverse of the data matrix
                 t_data_data is the matrix of : t(data matrix). data matrix
                 t_inv_coeff_dot_t_data is the matrix of : t(inv data matrix). data matrix

        # Caution : data has to be in column
    """

    # By default, data are not in column
    initial = data
    data = np.array(np.transpose(data))

    vec_inv = np.array(np.atleast_2d(np.append(np.tile([1, -1], int(nb_bases/2)), 1)))
    vec_inv = np.transpose(vec_inv)
    inv_coeff = np.array(data * vec_inv)
    t_data_data = np.asarray(np.transpose(data).dot(data))
    t_inv_coeff_t_data = np.asarray(np.transpose(inv_coeff).dot(data))

    # Anthony's method
    def eucl(x, y):
        return y-2*x

    d_t_data_data = np.transpose(np.tile(np.diag(t_data_data), (initial[:, 1].size, 1)))

    # Distance matrix with the initial matrix
    res_eucl = eucl(t_data_data, np.atleast_2d(np.diag(t_data_data)))
    eucli = np.sqrt(res_eucl + d_t_data_data)

    # Distance matrice with the invert distance matrix
    res_eucl2 = eucl(t_inv_coeff_t_data, np.atleast_2d(np.diag(t_data_data)))
    eucli_2 = np.sqrt(res_eucl2 + d_t_data_data)

    # Choose the min Distance matrix
    inv_dist_profil = base.pmin(eucli, eucli_2)
    inv_dist_profil = np.array(inv_dist_profil)

    return inv_dist_profil


def swap_cols(data, frm, to):
    data[:,[frm, to]] = data[:,[to, frm]]
