Skip to main content
5 of 7
Typo in docstrings
Xbel
  • 197
  • 1
  • 8

Finding permutations efficiently

I have the following:

  1. A set of K time-series in a numpy array with dimensions T x K.
  2. A set of P permuted approximation of them in a numpy array with dimensions P times T.

I need a dictionary that tells me which is the most probable permutation. For that I've created the following function, but I would like to know if can be done in a more efficient way and with less code to do this.

def find_permutation(true, permuted):
    N = true.shape[1]
    max_comps = permuted.shape[0]

    permutation_dict = {}
    used_comps = []

    corr_matrix = np.zeros((N, max_comps))

    # Find correlations
    for i in range(N):
        for j in range(max_comps):
            corr_matrix[i, j] = np.corrcoef(true[:, i], permuted[j, :])[0, 1]

    # Find best order
    per_matrix = np.argsort(-np.abs(corr_matrix), axis=1)
    for i in range(N):
        for j in per_matrix[i, :]:
            if j in used_comps:
                continue
            else:
                permutation_dict[i] = j
                used_comps.append(j)
                break

    return permutation_dict

Here a Cython version

@cython.boundscheck(False)  # Deactivate bounds checking
@cython.wraparound(False)   # Deactivate negative indexing.
def find_permutation(np.ndarray[DTYPE_t, ndim=2] true, np.ndarray[DTYPE_t, ndim=2] permuted):
    """
    Finds the most probable permutation of true time series in between permuted time series
    :param true: true ordered time series of shape T times X
    :param permuted: Permuted time series of shape P times T. P > K
    :return: A dict containing {true idx: permuted idx}
    """
    
    cdef unsigned int N = true.shape[1]
    cdef unsigned int max_comps = permuted.shape[0]

    cdef dict permutation_dict = {}
    cdef list used_comps = []

    cdef np.ndarray[DTYPE_t, ndim=2] corr_matrix
    corr_matrix = np.zeros((N, max_comps))

    cdef Py_ssize_t i
    cdef Py_ssize_t j
        
    # Find correlations
    for i in range(N):
        for j in range(max_comps):
            corr_matrix[i, j] = np.corrcoef(true[:, i], permuted[j, :])[0, 1]
    
    # Find best order
    cdef np.ndarray[long, ndim=2] per_matrix
    per_matrix = np.argsort(-np.abs(corr_matrix), axis=1)

    for i in range(N):
        for j in per_matrix[i, :]:
            if j in used_comps:
                continue
            else:
                permutation_dict[i] = j
                used_comps.append(j)
                break

    return permutation_dict

Any suggestion is more than welcome.

Xbel
  • 197
  • 1
  • 8