Generated by Cython 0.29.21

Yellow lines hint at Python interaction.
Click on a line that starts with a "+" to see the C code that Cython generated for it.

Raw output: mutual_info.c

+001: # cython: language_level=3, boundscheck=False, wraparound=False, initializedcheck=False, cdivision=True
  __pyx_t_2 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 002: # distutils: extra_compile_args=-fopenmp
 003: # distutils: extra_link_args=-fopenmp
 004: 
+005: import numpy as np
  __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 5, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 5, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 006: from libc.math cimport log
+007: from scipy.optimize import linear_sum_assignment
  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_INCREF(__pyx_n_s_linear_sum_assignment);
  __Pyx_GIVEREF(__pyx_n_s_linear_sum_assignment);
  PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_linear_sum_assignment);
  __pyx_t_2 = __Pyx_Import(__pyx_n_s_scipy_optimize, __pyx_t_1, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 7, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_linear_sum_assignment); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_linear_sum_assignment, __pyx_t_1) < 0) __PYX_ERR(0, 7, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 008: from cython.parallel import prange
+009: import time
  __pyx_t_2 = __Pyx_Import(__pyx_n_s_time, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 9, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_time, __pyx_t_2) < 0) __PYX_ERR(0, 9, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 010: 
 011: 
+012: def Inference_Partner_Mutual_Info(l_msa, s_train, reg, n_pair, fast=False, middle_index=None, n_mean=30, **kwargs):
/* Python wrapper */
static PyObject *__pyx_pw_11mutual_info_1Inference_Partner_Mutual_Info(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_11mutual_info_1Inference_Partner_Mutual_Info = {"Inference_Partner_Mutual_Info", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_11mutual_info_1Inference_Partner_Mutual_Info, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_11mutual_info_1Inference_Partner_Mutual_Info(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_l_msa = 0;
  PyObject *__pyx_v_s_train = 0;
  PyObject *__pyx_v_reg = 0;
  PyObject *__pyx_v_n_pair = 0;
  PyObject *__pyx_v_fast = 0;
  PyObject *__pyx_v_middle_index = 0;
  PyObject *__pyx_v_n_mean = 0;
  CYTHON_UNUSED PyObject *__pyx_v_kwargs = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("Inference_Partner_Mutual_Info (wrapper)", 0);
  __pyx_v_kwargs = PyDict_New(); if (unlikely(!__pyx_v_kwargs)) return NULL;
  __Pyx_GOTREF(__pyx_v_kwargs);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_l_msa,&__pyx_n_s_s_train,&__pyx_n_s_reg,&__pyx_n_s_n_pair,&__pyx_n_s_fast,&__pyx_n_s_middle_index,&__pyx_n_s_n_mean,0};
    PyObject* values[7] = {0,0,0,0,0,0,0};
    values[4] = ((PyObject *)Py_False);
    values[5] = ((PyObject *)Py_None);
    values[6] = ((PyObject *)__pyx_int_30);
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
        CYTHON_FALLTHROUGH;
        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
        CYTHON_FALLTHROUGH;
        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
        CYTHON_FALLTHROUGH;
        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_l_msa)) != 0)) kw_args--;
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_s_train)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("Inference_Partner_Mutual_Info", 0, 4, 7, 1); __PYX_ERR(0, 12, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_reg)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("Inference_Partner_Mutual_Info", 0, 4, 7, 2); __PYX_ERR(0, 12, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_n_pair)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("Inference_Partner_Mutual_Info", 0, 4, 7, 3); __PYX_ERR(0, 12, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  4:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_fast);
          if (value) { values[4] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  5:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_middle_index);
          if (value) { values[5] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  6:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_n_mean);
          if (value) { values[6] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, __pyx_v_kwargs, values, pos_args, "Inference_Partner_Mutual_Info") < 0)) __PYX_ERR(0, 12, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
        CYTHON_FALLTHROUGH;
        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
        CYTHON_FALLTHROUGH;
        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
        CYTHON_FALLTHROUGH;
        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_l_msa = values[0];
    __pyx_v_s_train = values[1];
    __pyx_v_reg = values[2];
    __pyx_v_n_pair = values[3];
    __pyx_v_fast = values[4];
    __pyx_v_middle_index = values[5];
    __pyx_v_n_mean = values[6];
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("Inference_Partner_Mutual_Info", 0, 4, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 12, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_DECREF(__pyx_v_kwargs); __pyx_v_kwargs = 0;
  __Pyx_AddTraceback("mutual_info.Inference_Partner_Mutual_Info", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_11mutual_info_Inference_Partner_Mutual_Info(__pyx_self, __pyx_v_l_msa, __pyx_v_s_train, __pyx_v_reg, __pyx_v_n_pair, __pyx_v_fast, __pyx_v_middle_index, __pyx_v_n_mean, __pyx_v_kwargs);

  /* function exit code */
  __Pyx_XDECREF(__pyx_v_kwargs);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_11mutual_info_Inference_Partner_Mutual_Info(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_l_msa, PyObject *__pyx_v_s_train, PyObject *__pyx_v_reg, PyObject *__pyx_v_n_pair, PyObject *__pyx_v_fast, PyObject *__pyx_v_middle_index, PyObject *__pyx_v_n_mean, CYTHON_UNUSED PyObject *__pyx_v_kwargs) {
  CYTHON_UNUSED int __pyx_v_i_avg;
  int __pyx_v_index_test;
  int __pyx_v_ind_species;
  int __pyx_v_counter_average;
  __Pyx_memviewslice __pyx_v_Percentage_True_partner = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_msa = NULL;
  PyObject *__pyx_v_l_perm = NULL;
  PyObject *__pyx_v_msa_train = NULL;
  PyObject *__pyx_v_index_max = NULL;
  PyObject *__pyx_v_msa_test = NULL;
  PyObject *__pyx_v_PMI_matrix = NULL;
  PyObject *__pyx_v_Cost = NULL;
  PyObject *__pyx_v_Permutation_worker_row = NULL;
  PyObject *__pyx_v_row_ind = NULL;
  PyObject *__pyx_v_col_ind = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("Inference_Partner_Mutual_Info", 0);
  __Pyx_INCREF(__pyx_v_middle_index);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __PYX_XDEC_MEMVIEW(&__pyx_t_4, 1);
  __Pyx_XDECREF(__pyx_t_14);
  __Pyx_XDECREF(__pyx_t_15);
  __PYX_XDEC_MEMVIEW(&__pyx_t_16, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_t_19, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_t_20, 1);
  __Pyx_AddTraceback("mutual_info.Inference_Partner_Mutual_Info", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __PYX_XDEC_MEMVIEW(&__pyx_v_Percentage_True_partner, 1);
  __Pyx_XDECREF(__pyx_v_msa);
  __Pyx_XDECREF(__pyx_v_l_perm);
  __Pyx_XDECREF(__pyx_v_msa_train);
  __Pyx_XDECREF(__pyx_v_index_max);
  __Pyx_XDECREF(__pyx_v_msa_test);
  __Pyx_XDECREF(__pyx_v_PMI_matrix);
  __Pyx_XDECREF(__pyx_v_Cost);
  __Pyx_XDECREF(__pyx_v_Permutation_worker_row);
  __Pyx_XDECREF(__pyx_v_row_ind);
  __Pyx_XDECREF(__pyx_v_col_ind);
  __Pyx_XDECREF(__pyx_v_middle_index);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__19 = PyTuple_Pack(23, __pyx_n_s_l_msa, __pyx_n_s_s_train, __pyx_n_s_reg, __pyx_n_s_n_pair, __pyx_n_s_fast, __pyx_n_s_middle_index, __pyx_n_s_n_mean, __pyx_n_s_kwargs, __pyx_n_s_i_avg, __pyx_n_s_index_test, __pyx_n_s_ind_species, __pyx_n_s_counter_average, __pyx_n_s_Percentage_True_partner, __pyx_n_s_msa, __pyx_n_s_l_perm, __pyx_n_s_msa_train, __pyx_n_s_index_max, __pyx_n_s_msa_test, __pyx_n_s_PMI_matrix, __pyx_n_s_Cost, __pyx_n_s_Permutation_worker_row, __pyx_n_s_row_ind, __pyx_n_s_col_ind); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(0, 12, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__19);
  __Pyx_GIVEREF(__pyx_tuple__19);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_11mutual_info_1Inference_Partner_Mutual_Info, NULL, __pyx_n_s_mutual_info); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 12, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Inference_Partner_Mutual_Info, __pyx_t_2) < 0) __PYX_ERR(0, 12, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__20 = (PyObject*)__Pyx_PyCode_New(7, 0, 23, 0, CO_OPTIMIZED|CO_NEWLOCALS|CO_VARKEYWORDS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__19, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mutual_info_pyx, __pyx_n_s_Inference_Partner_Mutual_Info, 12, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__20)) __PYX_ERR(0, 12, __pyx_L1_error)
 013:     cdef :
+014:         int i_avg, index_test, ind_species, counter_average = 0
  __pyx_v_counter_average = 0;
+015:         double[::1] Percentage_True_partner = np.zeros(n_pair)
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 15, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_zeros); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 15, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
    __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
    if (likely(__pyx_t_2)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
      __Pyx_INCREF(__pyx_t_2);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_3, function);
    }
  }
  __pyx_t_1 = (__pyx_t_2) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_2, __pyx_v_n_pair) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_n_pair);
  __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 15, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_4 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_1, PyBUF_WRITABLE); if (unlikely(!__pyx_t_4.memview)) __PYX_ERR(0, 15, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_Percentage_True_partner = __pyx_t_4;
  __pyx_t_4.memview = NULL;
  __pyx_t_4.data = NULL;
 016: 
+017:     if middle_index is None:
  __pyx_t_5 = (__pyx_v_middle_index == Py_None);
  __pyx_t_6 = (__pyx_t_5 != 0);
  if (__pyx_t_6) {
/* … */
  }
+018:         middle_index = int(float(l_msa[0].shape[1])/2.0)
    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_l_msa, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 18, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_shape); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 18, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_3, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 18, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __pyx_t_7 = __Pyx_PyObject_AsDouble(__pyx_t_1); if (unlikely(__pyx_t_7 == ((double)((double)-1)) && PyErr_Occurred())) __PYX_ERR(0, 18, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_1 = __Pyx_PyInt_FromDouble((__pyx_t_7 / 2.0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 18, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF_SET(__pyx_v_middle_index, __pyx_t_1);
    __pyx_t_1 = 0;
 019: 
+020:     for i_avg in range(n_mean):
  __pyx_t_8 = __Pyx_PyInt_As_long(__pyx_v_n_mean); if (unlikely((__pyx_t_8 == (long)-1) && PyErr_Occurred())) __PYX_ERR(0, 20, __pyx_L1_error)
  __pyx_t_9 = __pyx_t_8;
  for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
    __pyx_v_i_avg = __pyx_t_10;
+021:         for index_test in range(l_msa.shape[0]):
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_l_msa, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 21, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 21, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_11 = __Pyx_PyInt_As_long(__pyx_t_3); if (unlikely((__pyx_t_11 == (long)-1) && PyErr_Occurred())) __PYX_ERR(0, 21, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __pyx_t_12 = __pyx_t_11;
    for (__pyx_t_13 = 0; __pyx_t_13 < __pyx_t_12; __pyx_t_13+=1) {
      __pyx_v_index_test = __pyx_t_13;
+022:             msa = np.array(((l_msa[index_test]+1)/2), dtype=np.int8)
      __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 22, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_array); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_l_msa, __pyx_v_index_test, int, 1, __Pyx_PyInt_From_int, 0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 22, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_2 = __Pyx_PyInt_AddObjC(__pyx_t_3, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 22, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __pyx_t_3 = __Pyx_PyInt_TrueDivideObjC(__pyx_t_2, __pyx_int_2, 2, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 22, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 22, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_GIVEREF(__pyx_t_3);
      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3);
      __pyx_t_3 = 0;
      __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 22, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_GetModuleGlobalName(__pyx_t_14, __pyx_n_s_np); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 22, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_14);
      __pyx_t_15 = __Pyx_PyObject_GetAttrStr(__pyx_t_14, __pyx_n_s_int8); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 22, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_15);
      __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
      if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_15) < 0) __PYX_ERR(0, 22, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
      __pyx_t_15 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 22, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_15);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __Pyx_XDECREF_SET(__pyx_v_msa, __pyx_t_15);
      __pyx_t_15 = 0;
+023:             l_perm = np.random.permutation(l_msa.shape[1])
      __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 23, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_random); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 23, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_permutation); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 23, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_l_msa, __pyx_n_s_shape); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 23, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 23, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_t_2 = NULL;
      if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_3))) {
        __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
        if (likely(__pyx_t_2)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
          __Pyx_INCREF(__pyx_t_2);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_3, function);
        }
      }
      __pyx_t_15 = (__pyx_t_2) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_2, __pyx_t_1) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_1);
      __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 23, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_15);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __Pyx_XDECREF_SET(__pyx_v_l_perm, __pyx_t_15);
      __pyx_t_15 = 0;
+024:             msa_train = msa[l_perm[:s_train]]
      __pyx_t_15 = __Pyx_PyObject_GetSlice(__pyx_v_l_perm, 0, 0, NULL, &__pyx_v_s_train, NULL, 0, 0, 0); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 24, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_15);
      __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_v_msa, __pyx_t_15); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 24, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
      __Pyx_XDECREF_SET(__pyx_v_msa_train, __pyx_t_3);
      __pyx_t_3 = 0;
+025:             if fast:
      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_fast); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 25, __pyx_L1_error)
      if (__pyx_t_6) {
/* … */
        goto __pyx_L8;
      }
+026:                 index_max = min(s_train + 50*n_pair,np.size(l_msa, axis=1))
        __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 26, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __pyx_t_15 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_size); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 26, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_15);
        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
        __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 26, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __Pyx_INCREF(__pyx_v_l_msa);
        __Pyx_GIVEREF(__pyx_v_l_msa);
        PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_l_msa);
        __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 26, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_axis, __pyx_int_1) < 0) __PYX_ERR(0, 26, __pyx_L1_error)
        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_15, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 26, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __pyx_t_1 = PyNumber_Multiply(__pyx_int_50, __pyx_v_n_pair); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 26, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __pyx_t_3 = PyNumber_Add(__pyx_v_s_train, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 26, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __pyx_t_15 = PyObject_RichCompare(__pyx_t_2, __pyx_t_3, Py_LT); __Pyx_XGOTREF(__pyx_t_15); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 26, __pyx_L1_error)
        __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_15); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 26, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
        if (__pyx_t_6) {
          __Pyx_INCREF(__pyx_t_2);
          __pyx_t_1 = __pyx_t_2;
        } else {
          __Pyx_INCREF(__pyx_t_3);
          __pyx_t_1 = __pyx_t_3;
        }
        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
        __pyx_t_2 = __pyx_t_1;
        __Pyx_INCREF(__pyx_t_2);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __Pyx_XDECREF_SET(__pyx_v_index_max, __pyx_t_2);
        __pyx_t_2 = 0;
+027:                 msa_test = msa[l_perm[s_train:index_max]]
        __pyx_t_2 = __Pyx_PyObject_GetSlice(__pyx_v_l_perm, 0, 0, &__pyx_v_s_train, &__pyx_v_index_max, NULL, 0, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 27, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_msa, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 27, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
        __Pyx_XDECREF_SET(__pyx_v_msa_test, __pyx_t_1);
        __pyx_t_1 = 0;
 028:             else:
+029:                 msa_test = msa[l_perm[s_train:]]
      /*else*/ {
        __pyx_t_1 = __Pyx_PyObject_GetSlice(__pyx_v_l_perm, 0, 0, &__pyx_v_s_train, NULL, NULL, 0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 29, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_v_msa, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 29, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __Pyx_XDECREF_SET(__pyx_v_msa_test, __pyx_t_2);
        __pyx_t_2 = 0;
      }
      __pyx_L8:;
 030: 
+031:             PMI_matrix = PMI_cython(msa_train, reg, middle_index)
      __pyx_t_16 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_char(__pyx_v_msa_train, PyBUF_WRITABLE); if (unlikely(!__pyx_t_16.memview)) __PYX_ERR(0, 31, __pyx_L1_error)
      __pyx_t_7 = __pyx_PyFloat_AsDouble(__pyx_v_reg); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 31, __pyx_L1_error)
      __pyx_t_17.__pyx_n = 1;
      __pyx_t_17.middle_index_prot = __pyx_v_middle_index;
      __pyx_t_2 = __pyx_f_11mutual_info_PMI_cython(__pyx_t_16, __pyx_t_7, 0, &__pyx_t_17); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 31, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __PYX_XDEC_MEMVIEW(&__pyx_t_16, 1);
      __pyx_t_16.memview = NULL;
      __pyx_t_16.data = NULL;
      __Pyx_XDECREF_SET(__pyx_v_PMI_matrix, __pyx_t_2);
      __pyx_t_2 = 0;
+032:             ind_species = n_pair
      __pyx_t_18 = __Pyx_PyInt_As_int(__pyx_v_n_pair); if (unlikely((__pyx_t_18 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 32, __pyx_L1_error)
      __pyx_v_ind_species = __pyx_t_18;
 033: 
+034:             while ind_species<msa_test.shape[0]:
      while (1) {
        __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_ind_species); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 34, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_msa_test, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 34, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 34, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_3, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 34, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
        __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 34, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        if (!__pyx_t_6) break;
+035:                 Cost = np.zeros((n_pair,n_pair))
        __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 35, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_zeros); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 35, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
        __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 35, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __Pyx_INCREF(__pyx_v_n_pair);
        __Pyx_GIVEREF(__pyx_v_n_pair);
        PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_n_pair);
        __Pyx_INCREF(__pyx_v_n_pair);
        __Pyx_GIVEREF(__pyx_v_n_pair);
        PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_n_pair);
        __pyx_t_15 = NULL;
        if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
          __pyx_t_15 = PyMethod_GET_SELF(__pyx_t_2);
          if (likely(__pyx_t_15)) {
            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
            __Pyx_INCREF(__pyx_t_15);
            __Pyx_INCREF(function);
            __Pyx_DECREF_SET(__pyx_t_2, function);
          }
        }
        __pyx_t_1 = (__pyx_t_15) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_15, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
        __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0;
        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
        if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 35, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
        __Pyx_XDECREF_SET(__pyx_v_Cost, __pyx_t_1);
        __pyx_t_1 = 0;
+036:                 Score_Sij_cython(Cost, msa_test[ind_species-n_pair:ind_species], PMI_matrix, middle_index)
        __pyx_t_19 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_double(__pyx_v_Cost, PyBUF_WRITABLE); if (unlikely(!__pyx_t_19.memview)) __PYX_ERR(0, 36, __pyx_L1_error)
        __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_ind_species); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 36, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_v_n_pair); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 36, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __pyx_t_1 = __Pyx_PyObject_GetSlice(__pyx_v_msa_test, 0, __pyx_v_ind_species, &__pyx_t_2, NULL, NULL, 0, 1, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 36, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
        __pyx_t_16 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_char(__pyx_t_1, PyBUF_WRITABLE); if (unlikely(!__pyx_t_16.memview)) __PYX_ERR(0, 36, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __pyx_t_20 = __Pyx_PyObject_to_MemoryviewSlice_d_d_d_dc_double(__pyx_v_PMI_matrix, PyBUF_WRITABLE); if (unlikely(!__pyx_t_20.memview)) __PYX_ERR(0, 36, __pyx_L1_error)
        __pyx_t_18 = __Pyx_PyInt_As_int(__pyx_v_middle_index); if (unlikely((__pyx_t_18 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 36, __pyx_L1_error)
        __pyx_f_11mutual_info_Score_Sij_cython(__pyx_t_19, __pyx_t_16, __pyx_t_20, __pyx_t_18);
        __PYX_XDEC_MEMVIEW(&__pyx_t_19, 1);
        __pyx_t_19.memview = NULL;
        __pyx_t_19.data = NULL;
        __PYX_XDEC_MEMVIEW(&__pyx_t_16, 1);
        __pyx_t_16.memview = NULL;
        __pyx_t_16.data = NULL;
        __PYX_XDEC_MEMVIEW(&__pyx_t_20, 1);
        __pyx_t_20.memview = NULL;
        __pyx_t_20.data = NULL;
+037:                 Permutation_worker_row = np.random.permutation(Cost.shape[0])
        __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 37, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_random); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 37, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
        __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_permutation); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 37, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
        __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_Cost, __pyx_n_s_shape); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 37, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __pyx_t_15 = __Pyx_GetItemInt(__pyx_t_3, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 37, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_15);
        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
        __pyx_t_3 = NULL;
        if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
          __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
          if (likely(__pyx_t_3)) {
            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
            __Pyx_INCREF(__pyx_t_3);
            __Pyx_INCREF(function);
            __Pyx_DECREF_SET(__pyx_t_2, function);
          }
        }
        __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_t_15) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_15);
        __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
        __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
        if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 37, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
        __Pyx_XDECREF_SET(__pyx_v_Permutation_worker_row, __pyx_t_1);
        __pyx_t_1 = 0;
+038:                 Cost = Cost[Permutation_worker_row]
        __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_Cost, __pyx_v_Permutation_worker_row); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 38, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF_SET(__pyx_v_Cost, __pyx_t_1);
        __pyx_t_1 = 0;
+039:                 row_ind, col_ind = linear_sum_assignment(Cost)
        __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_linear_sum_assignment); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 39, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __pyx_t_15 = NULL;
        if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
          __pyx_t_15 = PyMethod_GET_SELF(__pyx_t_2);
          if (likely(__pyx_t_15)) {
            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
            __Pyx_INCREF(__pyx_t_15);
            __Pyx_INCREF(function);
            __Pyx_DECREF_SET(__pyx_t_2, function);
          }
        }
        __pyx_t_1 = (__pyx_t_15) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_15, __pyx_v_Cost) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_Cost);
        __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0;
        if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 39, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
        if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
          PyObject* sequence = __pyx_t_1;
          Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);
          if (unlikely(size != 2)) {
            if (size > 2) __Pyx_RaiseTooManyValuesError(2);
            else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
            __PYX_ERR(0, 39, __pyx_L1_error)
          }
          #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
          if (likely(PyTuple_CheckExact(sequence))) {
            __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); 
            __pyx_t_15 = PyTuple_GET_ITEM(sequence, 1); 
          } else {
            __pyx_t_2 = PyList_GET_ITEM(sequence, 0); 
            __pyx_t_15 = PyList_GET_ITEM(sequence, 1); 
          }
          __Pyx_INCREF(__pyx_t_2);
          __Pyx_INCREF(__pyx_t_15);
          #else
          __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 39, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_2);
          __pyx_t_15 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 39, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_15);
          #endif
          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        } else {
          Py_ssize_t index = -1;
          __pyx_t_3 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 39, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_3);
          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
          __pyx_t_21 = Py_TYPE(__pyx_t_3)->tp_iternext;
          index = 0; __pyx_t_2 = __pyx_t_21(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L11_unpacking_failed;
          __Pyx_GOTREF(__pyx_t_2);
          index = 1; __pyx_t_15 = __pyx_t_21(__pyx_t_3); if (unlikely(!__pyx_t_15)) goto __pyx_L11_unpacking_failed;
          __Pyx_GOTREF(__pyx_t_15);
          if (__Pyx_IternextUnpackEndCheck(__pyx_t_21(__pyx_t_3), 2) < 0) __PYX_ERR(0, 39, __pyx_L1_error)
          __pyx_t_21 = NULL;
          __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
          goto __pyx_L12_unpacking_done;
          __pyx_L11_unpacking_failed:;
          __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
          __pyx_t_21 = NULL;
          if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
          __PYX_ERR(0, 39, __pyx_L1_error)
          __pyx_L12_unpacking_done:;
        }
        __Pyx_XDECREF_SET(__pyx_v_row_ind, __pyx_t_2);
        __pyx_t_2 = 0;
        __Pyx_XDECREF_SET(__pyx_v_col_ind, __pyx_t_15);
        __pyx_t_15 = 0;
+040:                 Percentage_True_partner += Permutation_worker_row[row_ind] == col_ind # The true index of worker i is Permutation_worker[i]
        __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_Percentage_True_partner, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 40, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __pyx_t_15 = __Pyx_PyObject_GetItem(__pyx_v_Permutation_worker_row, __pyx_v_row_ind); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 40, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_15);
        __pyx_t_2 = PyObject_RichCompare(__pyx_t_15, __pyx_v_col_ind, Py_EQ); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 40, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
        __pyx_t_15 = PyNumber_InPlaceAdd(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 40, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_15);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
        __pyx_t_4 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_15, PyBUF_WRITABLE); if (unlikely(!__pyx_t_4.memview)) __PYX_ERR(0, 40, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
        __PYX_XDEC_MEMVIEW(&__pyx_v_Percentage_True_partner, 1);
        __pyx_v_Percentage_True_partner = __pyx_t_4;
        __pyx_t_4.memview = NULL;
        __pyx_t_4.data = NULL;
+041:                 counter_average += 1
        __pyx_v_counter_average = (__pyx_v_counter_average + 1);
+042:                 ind_species += n_pair
        __pyx_t_15 = __Pyx_PyInt_From_int(__pyx_v_ind_species); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 42, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_15);
        __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_15, __pyx_v_n_pair); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 42, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
        __pyx_t_18 = __Pyx_PyInt_As_int(__pyx_t_2); if (unlikely((__pyx_t_18 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 42, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
        __pyx_v_ind_species = __pyx_t_18;
      }
    }
  }
 043: 
+044:     return np.mean(Percentage_True_partner)/counter_average
  __Pyx_XDECREF(__pyx_r);
  __Pyx_GetModuleGlobalName(__pyx_t_15, __pyx_n_s_np); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 44, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_15);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_15, __pyx_n_s_mean); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 44, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
  __pyx_t_15 = __pyx_memoryview_fromslice(__pyx_v_Percentage_True_partner, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 44, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_15);
  __pyx_t_3 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_1))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_1, function);
    }
  }
  __pyx_t_2 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_3, __pyx_t_15) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_15);
  __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 44, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_counter_average); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 44, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_15 = __Pyx_PyNumber_Divide(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 44, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_15);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_r = __pyx_t_15;
  __pyx_t_15 = 0;
  goto __pyx_L0;
 045: 
 046: 
+047: cdef void Score_Sij_cython(double[:,::1] S_AB, char[:,::1] msa_test, double[:,:,:,::1] PMI, int middle_index):
static void __pyx_f_11mutual_info_Score_Sij_cython(__Pyx_memviewslice __pyx_v_S_AB, __Pyx_memviewslice __pyx_v_msa_test, __Pyx_memviewslice __pyx_v_PMI, int __pyx_v_middle_index) {
  int __pyx_v_ind_liste;
  int __pyx_v_ind_liste_2;
  int __pyx_v_i;
  int __pyx_v_j;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("Score_Sij_cython", 0);
/* … */
  /* function exit code */
  __Pyx_RefNannyFinishContext();
}
 048:     cdef:
 049:         int ind_liste, ind_liste_2, i, j
 050: 
+051:     for ind_liste in prange(S_AB.shape[0], nogil=True):
  {
      #ifdef WITH_THREAD
      PyThreadState *_save;
      Py_UNBLOCK_THREADS
      __Pyx_FastGIL_Remember();
      #endif
      /*try:*/ {
        __pyx_t_1 = (__pyx_v_S_AB.shape[0]);
        if ((1 == 0)) abort();
        {
            #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
                #undef likely
                #undef unlikely
                #define likely(x)   (x)
                #define unlikely(x) (x)
            #endif
            __pyx_t_3 = (__pyx_t_1 - 0 + 1 - 1/abs(1)) / 1;
            if (__pyx_t_3 > 0)
            {
                #ifdef _OPENMP
                #pragma omp parallel
                #endif /* _OPENMP */
                {
                    #ifdef _OPENMP
                    #pragma omp for lastprivate(__pyx_v_i) firstprivate(__pyx_v_ind_liste) lastprivate(__pyx_v_ind_liste) lastprivate(__pyx_v_ind_liste_2) lastprivate(__pyx_v_j)
                    #endif /* _OPENMP */
                    for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_3; __pyx_t_2++){
                        {
                            __pyx_v_ind_liste = (int)(0 + 1 * __pyx_t_2);
                            /* Initialize private variables to invalid values */
                            __pyx_v_i = ((int)0xbad0bad0);
                            __pyx_v_ind_liste_2 = ((int)0xbad0bad0);
                            __pyx_v_j = ((int)0xbad0bad0);
/* … */
      /*finally:*/ {
        /*normal exit:*/{
          #ifdef WITH_THREAD
          __Pyx_FastGIL_Forget();
          Py_BLOCK_THREADS
          #endif
          goto __pyx_L5;
        }
        __pyx_L5:;
      }
  }
+052:         for ind_liste_2 in range(S_AB.shape[1]):
                            __pyx_t_4 = (__pyx_v_S_AB.shape[1]);
                            __pyx_t_5 = __pyx_t_4;
                            for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
                              __pyx_v_ind_liste_2 = __pyx_t_6;
+053:             for i in range(middle_index):
                              __pyx_t_7 = __pyx_v_middle_index;
                              __pyx_t_8 = __pyx_t_7;
                              for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) {
                                __pyx_v_i = __pyx_t_9;
+054:                 for j in range(middle_index, msa_test.shape[1]):
                                __pyx_t_10 = (__pyx_v_msa_test.shape[1]);
                                __pyx_t_11 = __pyx_t_10;
                                for (__pyx_t_12 = __pyx_v_middle_index; __pyx_t_12 < __pyx_t_11; __pyx_t_12+=1) {
                                  __pyx_v_j = __pyx_t_12;
+055:                     S_AB[ind_liste,ind_liste_2] -= PMI[i,j,msa_test[ind_liste,i],msa_test[ind_liste_2,j]]
                                  __pyx_t_13 = __pyx_v_ind_liste;
                                  __pyx_t_14 = __pyx_v_i;
                                  __pyx_t_15 = __pyx_v_ind_liste_2;
                                  __pyx_t_16 = __pyx_v_j;
                                  __pyx_t_17 = __pyx_v_i;
                                  __pyx_t_18 = __pyx_v_j;
                                  __pyx_t_19 = (*((char *) ( /* dim=1 */ ((char *) (((char *) ( /* dim=0 */ (__pyx_v_msa_test.data + __pyx_t_13 * __pyx_v_msa_test.strides[0]) )) + __pyx_t_14)) )));
                                  __pyx_t_20 = (*((char *) ( /* dim=1 */ ((char *) (((char *) ( /* dim=0 */ (__pyx_v_msa_test.data + __pyx_t_15 * __pyx_v_msa_test.strides[0]) )) + __pyx_t_16)) )));
                                  __pyx_t_21 = __pyx_v_ind_liste;
                                  __pyx_t_22 = __pyx_v_ind_liste_2;
                                  *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_S_AB.data + __pyx_t_21 * __pyx_v_S_AB.strides[0]) )) + __pyx_t_22)) )) -= (*((double *) ( /* dim=3 */ ((char *) (((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_PMI.data + __pyx_t_17 * __pyx_v_PMI.strides[0]) ) + __pyx_t_18 * __pyx_v_PMI.strides[1]) ) + __pyx_t_19 * __pyx_v_PMI.strides[2]) )) + __pyx_t_20)) )));
                                }
                              }
                            }
                        }
                    }
                }
            }
        }
        #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
            #undef likely
            #undef unlikely
            #define likely(x)   __builtin_expect(!!(x), 1)
            #define unlikely(x) __builtin_expect(!!(x), 0)
        #endif
      }
 056: 
 057: 
+058: cpdef PMI_cython(char[:,::1] msa, double pseudocount, middle_index_prot=None):
static PyObject *__pyx_pw_11mutual_info_3PMI_cython(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyObject *__pyx_f_11mutual_info_PMI_cython(__Pyx_memviewslice __pyx_v_msa, double __pyx_v_pseudocount, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_11mutual_info_PMI_cython *__pyx_optional_args) {
  PyObject *__pyx_v_middle_index_prot = ((PyObject *)Py_None);
  int __pyx_v_site_i;
  int __pyx_v_site_j;
  int __pyx_v_index_spin_1;
  int __pyx_v_index_spin_2;
  int __pyx_v_index_try;
  int __pyx_v_middle_index;
  CYTHON_UNUSED float __pyx_v_compteur;
  __Pyx_memviewslice __pyx_v_PMI = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_Fij = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_Frequence_1body = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("PMI_cython", 0);
  if (__pyx_optional_args) {
    if (__pyx_optional_args->__pyx_n > 0) {
      __pyx_v_middle_index_prot = __pyx_optional_args->middle_index_prot;
    }
  }
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __PYX_XDEC_MEMVIEW(&__pyx_t_6, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_t_7, 1);
  __Pyx_AddTraceback("mutual_info.PMI_cython", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = 0;
  __pyx_L0:;
  __PYX_XDEC_MEMVIEW(&__pyx_v_PMI, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_Fij, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_Frequence_1body, 1);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* Python wrapper */
static PyObject *__pyx_pw_11mutual_info_3PMI_cython(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyObject *__pyx_pw_11mutual_info_3PMI_cython(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  __Pyx_memviewslice __pyx_v_msa = { 0, 0, { 0 }, { 0 }, { 0 } };
  double __pyx_v_pseudocount;
  PyObject *__pyx_v_middle_index_prot = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("PMI_cython (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_msa,&__pyx_n_s_pseudocount,&__pyx_n_s_middle_index_prot,0};
    PyObject* values[3] = {0,0,0};
    values[2] = ((PyObject *)Py_None);
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_msa)) != 0)) kw_args--;
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pseudocount)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("PMI_cython", 0, 2, 3, 1); __PYX_ERR(0, 58, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_middle_index_prot);
          if (value) { values[2] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "PMI_cython") < 0)) __PYX_ERR(0, 58, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_msa = __Pyx_PyObject_to_MemoryviewSlice_d_dc_char(values[0], PyBUF_WRITABLE); if (unlikely(!__pyx_v_msa.memview)) __PYX_ERR(0, 58, __pyx_L3_error)
    __pyx_v_pseudocount = __pyx_PyFloat_AsDouble(values[1]); if (unlikely((__pyx_v_pseudocount == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 58, __pyx_L3_error)
    __pyx_v_middle_index_prot = values[2];
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("PMI_cython", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 58, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("mutual_info.PMI_cython", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_11mutual_info_2PMI_cython(__pyx_self, __pyx_v_msa, __pyx_v_pseudocount, __pyx_v_middle_index_prot);

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_11mutual_info_2PMI_cython(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_msa, double __pyx_v_pseudocount, PyObject *__pyx_v_middle_index_prot) {
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("PMI_cython", 0);
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_2.__pyx_n = 1;
  __pyx_t_2.middle_index_prot = __pyx_v_middle_index_prot;
  __pyx_t_1 = __pyx_f_11mutual_info_PMI_cython(__pyx_v_msa, __pyx_v_pseudocount, 0, &__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 58, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_r = __pyx_t_1;
  __pyx_t_1 = 0;
  goto __pyx_L0;

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_AddTraceback("mutual_info.PMI_cython", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __PYX_XDEC_MEMVIEW(&__pyx_v_msa, 1);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
struct __pyx_opt_args_11mutual_info_PMI_cython {
  int __pyx_n;
  PyObject *middle_index_prot;
};
 059:     cdef :
 060:         int site_i,site_j,index_spin_1,index_spin_2,index_try
 061:         int middle_index
+062:         float compteur = 0
  __pyx_v_compteur = 0.0;
 063:         ##PMI[site_i,site_j,spin_i,spin_j]
+064:         double[:,:,:,::1] PMI = np.zeros((msa.shape[1],msa.shape[1], 2, 2))
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 64, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_zeros); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 64, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = PyInt_FromSsize_t((__pyx_v_msa.shape[1])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 64, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_4 = PyInt_FromSsize_t((__pyx_v_msa.shape[1])); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 64, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 64, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_GIVEREF(__pyx_t_2);
  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_4);
  __Pyx_INCREF(__pyx_int_2);
  __Pyx_GIVEREF(__pyx_int_2);
  PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_int_2);
  __Pyx_INCREF(__pyx_int_2);
  __Pyx_GIVEREF(__pyx_int_2);
  PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_int_2);
  __pyx_t_2 = 0;
  __pyx_t_4 = 0;
  __pyx_t_4 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
    if (likely(__pyx_t_4)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
      __Pyx_INCREF(__pyx_t_4);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_3, function);
    }
  }
  __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5);
  __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 64, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_d_d_d_dc_double(__pyx_t_1, PyBUF_WRITABLE); if (unlikely(!__pyx_t_6.memview)) __PYX_ERR(0, 64, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_PMI = __pyx_t_6;
  __pyx_t_6.memview = NULL;
  __pyx_t_6.data = NULL;
+065:         double[:,:,:,::1] Fij = np.zeros((msa.shape[1],msa.shape[1], 2, 2))
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 65, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_zeros); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 65, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = PyInt_FromSsize_t((__pyx_v_msa.shape[1])); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 65, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = PyInt_FromSsize_t((__pyx_v_msa.shape[1])); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 65, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_2 = PyTuple_New(4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 65, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_GIVEREF(__pyx_t_3);
  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4);
  __Pyx_INCREF(__pyx_int_2);
  __Pyx_GIVEREF(__pyx_int_2);
  PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_int_2);
  __Pyx_INCREF(__pyx_int_2);
  __Pyx_GIVEREF(__pyx_int_2);
  PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_int_2);
  __pyx_t_3 = 0;
  __pyx_t_4 = 0;
  __pyx_t_4 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
    if (likely(__pyx_t_4)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_4);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_5, function);
    }
  }
  __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_4, __pyx_t_2) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_2);
  __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 65, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_d_d_d_dc_double(__pyx_t_1, PyBUF_WRITABLE); if (unlikely(!__pyx_t_6.memview)) __PYX_ERR(0, 65, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_Fij = __pyx_t_6;
  __pyx_t_6.memview = NULL;
  __pyx_t_6.data = NULL;
+066:         double[:,::1] Frequence_1body = np.zeros((msa.shape[1], 2))
  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 66, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_zeros); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 66, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = PyInt_FromSsize_t((__pyx_v_msa.shape[1])); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 66, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 66, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_5);
  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_5);
  __Pyx_INCREF(__pyx_int_2);
  __Pyx_GIVEREF(__pyx_int_2);
  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_int_2);
  __pyx_t_5 = 0;
  __pyx_t_5 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2);
    if (likely(__pyx_t_5)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
      __Pyx_INCREF(__pyx_t_5);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_2, function);
    }
  }
  __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 66, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_double(__pyx_t_1, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 66, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_Frequence_1body = __pyx_t_7;
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
 067: 
+068:     if middle_index_prot is None:
  __pyx_t_8 = (__pyx_v_middle_index_prot == Py_None);
  __pyx_t_9 = (__pyx_t_8 != 0);
  if (__pyx_t_9) {
/* … */
    goto __pyx_L3;
  }
+069:         middle_index = int(float(msa.shape[1])/2.0)
    __pyx_v_middle_index = ((int)(((double)(__pyx_v_msa.shape[1])) / 2.0));
 070:     else:
+071:         middle_index = int(middle_index_prot)
  /*else*/ {
    __pyx_t_1 = __Pyx_PyNumber_Int(__pyx_v_middle_index_prot); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 71, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_10 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 71, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_v_middle_index = __pyx_t_10;
  }
  __pyx_L3:;
 072: 
+073:     two_body_freq_cython(Fij, msa, pseudocount, middle_index)
  __pyx_f_11mutual_info_two_body_freq_cython(__pyx_v_Fij, __pyx_v_msa, __pyx_v_pseudocount, __pyx_v_middle_index);
 074: 
+075:     for site_i in prange(msa.shape[1], nogil=True):
  {
      #ifdef WITH_THREAD
      PyThreadState *_save;
      Py_UNBLOCK_THREADS
      __Pyx_FastGIL_Remember();
      #endif
      /*try:*/ {
        __pyx_t_11 = (__pyx_v_msa.shape[1]);
        if ((1 == 0)) abort();
        {
            #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
                #undef likely
                #undef unlikely
                #define likely(x)   (x)
                #define unlikely(x) (x)
            #endif
            __pyx_t_13 = (__pyx_t_11 - 0 + 1 - 1/abs(1)) / 1;
            if (__pyx_t_13 > 0)
            {
                #ifdef _OPENMP
                #pragma omp parallel
                #endif /* _OPENMP */
                {
                    #ifdef _OPENMP
                    #pragma omp for lastprivate(__pyx_v_index_try) firstprivate(__pyx_v_site_i) lastprivate(__pyx_v_site_i)
                    #endif /* _OPENMP */
                    for (__pyx_t_12 = 0; __pyx_t_12 < __pyx_t_13; __pyx_t_12++){
                        {
                            __pyx_v_site_i = (int)(0 + 1 * __pyx_t_12);
                            /* Initialize private variables to invalid values */
                            __pyx_v_index_try = ((int)0xbad0bad0);
/* … */
      /*finally:*/ {
        /*normal exit:*/{
          #ifdef WITH_THREAD
          __Pyx_FastGIL_Forget();
          Py_BLOCK_THREADS
          #endif
          goto __pyx_L6;
        }
        __pyx_L6:;
      }
  }
+076:         for index_try in range(msa.shape[0]):
                            __pyx_t_14 = (__pyx_v_msa.shape[0]);
                            __pyx_t_15 = __pyx_t_14;
                            for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_15; __pyx_t_10+=1) {
                              __pyx_v_index_try = __pyx_t_10;
+077:             Frequence_1body[site_i, msa[index_try, site_i]] += 1
                              __pyx_t_16 = __pyx_v_index_try;
                              __pyx_t_17 = __pyx_v_site_i;
                              __pyx_t_18 = __pyx_v_site_i;
                              __pyx_t_19 = (*((char *) ( /* dim=1 */ ((char *) (((char *) ( /* dim=0 */ (__pyx_v_msa.data + __pyx_t_16 * __pyx_v_msa.strides[0]) )) + __pyx_t_17)) )));
                              *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_Frequence_1body.data + __pyx_t_18 * __pyx_v_Frequence_1body.strides[0]) )) + __pyx_t_19)) )) += 1.0;
                            }
 078: 
+079:         Frequence_1body[site_i,0] = pseudocount/2 + (1-pseudocount)*Frequence_1body[site_i,0]/msa.shape[0]
                            __pyx_t_17 = __pyx_v_site_i;
                            __pyx_t_16 = 0;
                            __pyx_t_19 = __pyx_v_site_i;
                            __pyx_t_18 = 0;
                            *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_Frequence_1body.data + __pyx_t_19 * __pyx_v_Frequence_1body.strides[0]) )) + __pyx_t_18)) )) = ((__pyx_v_pseudocount / 2.0) + (((1.0 - __pyx_v_pseudocount) * (*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_Frequence_1body.data + __pyx_t_17 * __pyx_v_Frequence_1body.strides[0]) )) + __pyx_t_16)) )))) / ((double)(__pyx_v_msa.shape[0]))));
+080:         Frequence_1body[site_i,1] = pseudocount/2 + (1-pseudocount)*Frequence_1body[site_i,1]/msa.shape[0]#1 - Frequence_1body[site_i,0]
                            __pyx_t_16 = __pyx_v_site_i;
                            __pyx_t_17 = 1;
                            __pyx_t_18 = __pyx_v_site_i;
                            __pyx_t_19 = 1;
                            *((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_Frequence_1body.data + __pyx_t_18 * __pyx_v_Frequence_1body.strides[0]) )) + __pyx_t_19)) )) = ((__pyx_v_pseudocount / 2.0) + (((1.0 - __pyx_v_pseudocount) * (*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_Frequence_1body.data + __pyx_t_16 * __pyx_v_Frequence_1body.strides[0]) )) + __pyx_t_17)) )))) / ((double)(__pyx_v_msa.shape[0]))));
                        }
                    }
                }
            }
        }
        #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
            #undef likely
            #undef unlikely
            #define likely(x)   __builtin_expect(!!(x), 1)
            #define unlikely(x) __builtin_expect(!!(x), 0)
        #endif
      }
 081: 
+082:     for site_i in range(middle_index):
  __pyx_t_10 = __pyx_v_middle_index;
  __pyx_t_20 = __pyx_t_10;
  for (__pyx_t_21 = 0; __pyx_t_21 < __pyx_t_20; __pyx_t_21+=1) {
    __pyx_v_site_i = __pyx_t_21;
+083:         for site_j in range(middle_index,msa.shape[1]):
    __pyx_t_13 = (__pyx_v_msa.shape[1]);
    __pyx_t_12 = __pyx_t_13;
    for (__pyx_t_22 = __pyx_v_middle_index; __pyx_t_22 < __pyx_t_12; __pyx_t_22+=1) {
      __pyx_v_site_j = __pyx_t_22;
+084:             for index_spin_1 in range(2):
      for (__pyx_t_23 = 0; __pyx_t_23 < 2; __pyx_t_23+=1) {
        __pyx_v_index_spin_1 = __pyx_t_23;
+085:                 for index_spin_2 in range(2):
        for (__pyx_t_24 = 0; __pyx_t_24 < 2; __pyx_t_24+=1) {
          __pyx_v_index_spin_2 = __pyx_t_24;
+086:                     PMI[site_i,site_j,index_spin_1,index_spin_2] = log(Fij[site_i,site_j,index_spin_1,index_spin_2]/(Frequence_1body[site_i,index_spin_1]*Frequence_1body[site_j,index_spin_2]))
          __pyx_t_17 = __pyx_v_site_i;
          __pyx_t_16 = __pyx_v_site_j;
          __pyx_t_19 = __pyx_v_index_spin_1;
          __pyx_t_18 = __pyx_v_index_spin_2;
          __pyx_t_25 = __pyx_v_site_i;
          __pyx_t_26 = __pyx_v_index_spin_1;
          __pyx_t_27 = __pyx_v_site_j;
          __pyx_t_28 = __pyx_v_index_spin_2;
          __pyx_t_29 = __pyx_v_site_i;
          __pyx_t_30 = __pyx_v_site_j;
          __pyx_t_31 = __pyx_v_index_spin_1;
          __pyx_t_32 = __pyx_v_index_spin_2;
          *((double *) ( /* dim=3 */ ((char *) (((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_PMI.data + __pyx_t_29 * __pyx_v_PMI.strides[0]) ) + __pyx_t_30 * __pyx_v_PMI.strides[1]) ) + __pyx_t_31 * __pyx_v_PMI.strides[2]) )) + __pyx_t_32)) )) = log(((*((double *) ( /* dim=3 */ ((char *) (((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_Fij.data + __pyx_t_17 * __pyx_v_Fij.strides[0]) ) + __pyx_t_16 * __pyx_v_Fij.strides[1]) ) + __pyx_t_19 * __pyx_v_Fij.strides[2]) )) + __pyx_t_18)) ))) / ((*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_Frequence_1body.data + __pyx_t_25 * __pyx_v_Frequence_1body.strides[0]) )) + __pyx_t_26)) ))) * (*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_Frequence_1body.data + __pyx_t_27 * __pyx_v_Frequence_1body.strides[0]) )) + __pyx_t_28)) ))))));
        }
      }
    }
  }
 087: 
+088:     return np.asarray(PMI)
  __Pyx_XDECREF(__pyx_r);
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 88, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_asarray); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 88, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __pyx_memoryview_fromslice(__pyx_v_PMI, 4, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 88, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_5 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
    if (likely(__pyx_t_5)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
      __Pyx_INCREF(__pyx_t_5);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_4, function);
    }
  }
  __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_2) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_2);
  __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 88, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_r = __pyx_t_1;
  __pyx_t_1 = 0;
  goto __pyx_L0;
 089: 
+090: cdef void two_body_freq_cython(double[:,:,:,::1] Fij, char[:,::1] msa, double pseudocount, int middle_index):
static void __pyx_f_11mutual_info_two_body_freq_cython(__Pyx_memviewslice __pyx_v_Fij, __Pyx_memviewslice __pyx_v_msa, double __pyx_v_pseudocount, int __pyx_v_middle_index) {
  int __pyx_v_site_i;
  int __pyx_v_site_j;
  int __pyx_v_index_try;
  int __pyx_v_index_spin_1;
  int __pyx_v_index_spin_2;
  double __pyx_v_delta_freq;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("two_body_freq_cython", 0);
/* … */
  /* function exit code */
  __Pyx_RefNannyFinishContext();
}
 091:     cdef:
 092:         int site_i,site_j,index_try,index_spin_1,index_spin_2
+093:         double delta_freq =  1.0/(msa.shape[0])
  __pyx_v_delta_freq = (1.0 / ((double)(__pyx_v_msa.shape[0])));
 094: 
+095:     for site_i in prange(middle_index, nogil=True):
  {
      #ifdef WITH_THREAD
      PyThreadState *_save;
      Py_UNBLOCK_THREADS
      __Pyx_FastGIL_Remember();
      #endif
      /*try:*/ {
        __pyx_t_1 = __pyx_v_middle_index;
        if ((1 == 0)) abort();
        {
            #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
                #undef likely
                #undef unlikely
                #define likely(x)   (x)
                #define unlikely(x) (x)
            #endif
            __pyx_t_3 = (__pyx_t_1 - 0 + 1 - 1/abs(1)) / 1;
            if (__pyx_t_3 > 0)
            {
                #ifdef _OPENMP
                #pragma omp parallel
                #endif /* _OPENMP */
                {
                    #ifdef _OPENMP
                    #pragma omp for lastprivate(__pyx_v_index_spin_1) lastprivate(__pyx_v_index_spin_2) lastprivate(__pyx_v_index_try) firstprivate(__pyx_v_site_i) lastprivate(__pyx_v_site_i) lastprivate(__pyx_v_site_j)
                    #endif /* _OPENMP */
                    for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_3; __pyx_t_2++){
                        {
                            __pyx_v_site_i = (int)(0 + 1 * __pyx_t_2);
                            /* Initialize private variables to invalid values */
                            __pyx_v_index_spin_1 = ((int)0xbad0bad0);
                            __pyx_v_index_spin_2 = ((int)0xbad0bad0);
                            __pyx_v_index_try = ((int)0xbad0bad0);
                            __pyx_v_site_j = ((int)0xbad0bad0);
/* … */
      /*finally:*/ {
        /*normal exit:*/{
          #ifdef WITH_THREAD
          __Pyx_FastGIL_Forget();
          Py_BLOCK_THREADS
          #endif
          goto __pyx_L5;
        }
        __pyx_L5:;
      }
  }
+096:         for site_j in range(middle_index, msa.shape[1]):
                            __pyx_t_4 = (__pyx_v_msa.shape[1]);
                            __pyx_t_5 = __pyx_t_4;
                            for (__pyx_t_6 = __pyx_v_middle_index; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
                              __pyx_v_site_j = __pyx_t_6;
+097:             for index_try in range(msa.shape[0]):
                              __pyx_t_7 = (__pyx_v_msa.shape[0]);
                              __pyx_t_8 = __pyx_t_7;
                              for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) {
                                __pyx_v_index_try = __pyx_t_9;
+098:                 Fij[site_i,site_j,msa[index_try, site_i],msa[index_try, site_j]] += delta_freq
                                __pyx_t_10 = __pyx_v_index_try;
                                __pyx_t_11 = __pyx_v_site_i;
                                __pyx_t_12 = __pyx_v_index_try;
                                __pyx_t_13 = __pyx_v_site_j;
                                __pyx_t_14 = __pyx_v_site_i;
                                __pyx_t_15 = __pyx_v_site_j;
                                __pyx_t_16 = (*((char *) ( /* dim=1 */ ((char *) (((char *) ( /* dim=0 */ (__pyx_v_msa.data + __pyx_t_10 * __pyx_v_msa.strides[0]) )) + __pyx_t_11)) )));
                                __pyx_t_17 = (*((char *) ( /* dim=1 */ ((char *) (((char *) ( /* dim=0 */ (__pyx_v_msa.data + __pyx_t_12 * __pyx_v_msa.strides[0]) )) + __pyx_t_13)) )));
                                *((double *) ( /* dim=3 */ ((char *) (((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_Fij.data + __pyx_t_14 * __pyx_v_Fij.strides[0]) ) + __pyx_t_15 * __pyx_v_Fij.strides[1]) ) + __pyx_t_16 * __pyx_v_Fij.strides[2]) )) + __pyx_t_17)) )) += __pyx_v_delta_freq;
                              }
 099: 
+100:             for index_spin_1 in range(2):
                              for (__pyx_t_9 = 0; __pyx_t_9 < 2; __pyx_t_9+=1) {
                                __pyx_v_index_spin_1 = __pyx_t_9;
+101:                 for index_spin_2 in range(2):
                                for (__pyx_t_18 = 0; __pyx_t_18 < 2; __pyx_t_18+=1) {
                                  __pyx_v_index_spin_2 = __pyx_t_18;
+102:                     Fij[site_i,site_j,index_spin_1,index_spin_2] = pseudocount/4 + (1-pseudocount)*Fij[site_i,site_j,index_spin_1,index_spin_2]
                                  __pyx_t_13 = __pyx_v_site_i;
                                  __pyx_t_12 = __pyx_v_site_j;
                                  __pyx_t_11 = __pyx_v_index_spin_1;
                                  __pyx_t_10 = __pyx_v_index_spin_2;
                                  __pyx_t_17 = __pyx_v_site_i;
                                  __pyx_t_16 = __pyx_v_site_j;
                                  __pyx_t_15 = __pyx_v_index_spin_1;
                                  __pyx_t_14 = __pyx_v_index_spin_2;
                                  *((double *) ( /* dim=3 */ ((char *) (((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_Fij.data + __pyx_t_17 * __pyx_v_Fij.strides[0]) ) + __pyx_t_16 * __pyx_v_Fij.strides[1]) ) + __pyx_t_15 * __pyx_v_Fij.strides[2]) )) + __pyx_t_14)) )) = ((__pyx_v_pseudocount / 4.0) + ((1.0 - __pyx_v_pseudocount) * (*((double *) ( /* dim=3 */ ((char *) (((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_Fij.data + __pyx_t_13 * __pyx_v_Fij.strides[0]) ) + __pyx_t_12 * __pyx_v_Fij.strides[1]) ) + __pyx_t_11 * __pyx_v_Fij.strides[2]) )) + __pyx_t_10)) )))));
                                }
                              }
                            }
                        }
                    }
                }
            }
        }
        #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
            #undef likely
            #undef unlikely
            #define likely(x)   __builtin_expect(!!(x), 1)
            #define unlikely(x) __builtin_expect(!!(x), 0)
        #endif
      }
 103: