Cython: kernel_evaluations.pyx

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: kernel_evaluations.c

    +001: #!/usr/bin/env python

      __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;

     002:

     003: # cython: language_level=3

     004: # cython: profile=True

     005:

    +006: __author__ = 'Florian Hase, Matteo Aldeghi'

      if (PyDict_SetItem(__pyx_d, __pyx_n_s_author, __pyx_kp_u_Florian_Hase_Matteo_Aldeghi) < 0) __PYX_ERR(0, 6, __pyx_L1_error)

     007:

     008: import  cython

     009: cimport cython

    +010: import  numpy as np

      __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 10, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 10, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;

     011: cimport numpy as np

     012: from libc.math cimport exp, round

     013:

     014:

     015: # ==================

     016: # Distance functions

     017: # ==================

     018: @cython.cdivision(True)

    +019: cdef double _gauss(double x, double loc, double sqrt_prec):

    static double __pyx_f_7gryffin_16bayesian_network_18kernel_evaluations__gauss(double __pyx_v_x, double __pyx_v_loc, double __pyx_v_sqrt_prec) {
      double __pyx_v_argument;
      double __pyx_v_result;
      double __pyx_r;
      __Pyx_TraceDeclarations
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("_gauss", 0);
      __Pyx_TraceCall("_gauss", __pyx_f[0], 19, 0, __PYX_ERR(0, 19, __pyx_L1_error));
    /* … */
      /* function exit code */
      __pyx_L1_error:;
      __Pyx_WriteUnraisable("gryffin.bayesian_network.kernel_evaluations._gauss", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
      __pyx_r = 0;
      __pyx_L0:;
      __Pyx_TraceReturn(Py_None, 0);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

     020:     cdef double argument, result

    +021:     argument = 0.5 * (sqrt_prec * (x - loc))**2

      __pyx_v_argument = (0.5 * pow((__pyx_v_sqrt_prec * (__pyx_v_x - __pyx_v_loc)), 2.0));

    +022:     if argument > 200.:

      __pyx_t_1 = ((__pyx_v_argument > 200.) != 0);
      if (__pyx_t_1) {
    /* … */
        goto __pyx_L3;
      }

    +023:         result = 0.

        __pyx_v_result = 0.;

     024:     else:

    +025:         result = exp(-argument) * sqrt_prec * 0.3989422804014327  # the number is 1. / np.sqrt(2 * np.pi)

      /*else*/ {
        __pyx_v_result = ((exp((-__pyx_v_argument)) * __pyx_v_sqrt_prec) * 0.3989422804014327);
      }
      __pyx_L3:;

    +026:     return result

      __pyx_r = __pyx_v_result;
      goto __pyx_L0;

     027:

     028:

     029: @cython.cdivision(True)

    +030: cdef double _gauss_periodic(double x, double loc, double sqrt_prec, double var_range):

    static double __pyx_f_7gryffin_16bayesian_network_18kernel_evaluations__gauss_periodic(double __pyx_v_x, double __pyx_v_loc, double __pyx_v_sqrt_prec, double __pyx_v_var_range) {
      double __pyx_v_argument;
      double __pyx_v_result;
      double __pyx_v_distance;
      double __pyx_r;
      __Pyx_TraceDeclarations
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("_gauss_periodic", 0);
      __Pyx_TraceCall("_gauss_periodic", __pyx_f[0], 30, 0, __PYX_ERR(0, 30, __pyx_L1_error));
    /* … */
      /* function exit code */
      __pyx_L1_error:;
      __Pyx_WriteUnraisable("gryffin.bayesian_network.kernel_evaluations._gauss_periodic", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
      __pyx_r = 0;
      __pyx_L0:;
      __Pyx_TraceReturn(Py_None, 0);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

     031:

     032:     cdef double argument, result, distance

     033:

    +034:     distance = abs(x - loc)

      __pyx_v_distance = fabs((__pyx_v_x - __pyx_v_loc));

    +035:     if var_range - distance < distance:

      __pyx_t_1 = (((__pyx_v_var_range - __pyx_v_distance) < __pyx_v_distance) != 0);
      if (__pyx_t_1) {
    /* … */
      }

    +036:         distance = var_range - distance

        __pyx_v_distance = (__pyx_v_var_range - __pyx_v_distance);

     037:

    +038:     argument = 0.5 * (distance * sqrt_prec)**2

      __pyx_v_argument = (0.5 * pow((__pyx_v_distance * __pyx_v_sqrt_prec), 2.0));

    +039:     if argument > 200.:

      __pyx_t_1 = ((__pyx_v_argument > 200.) != 0);
      if (__pyx_t_1) {
    /* … */
        goto __pyx_L4;
      }

    +040:         result = 0.

        __pyx_v_result = 0.;

     041:     else:

    +042:         result = exp(-argument) * sqrt_prec * 0.3989422804014327  # the number is 1. / np.sqrt(2 * np.pi)

      /*else*/ {
        __pyx_v_result = ((exp((-__pyx_v_argument)) * __pyx_v_sqrt_prec) * 0.3989422804014327);
      }
      __pyx_L4:;

    +043:     return result

      __pyx_r = __pyx_v_result;
      goto __pyx_L0;

     044:

     045:

     046: # ==========

     047: # Main Class

     048: # ==========

    +049: cdef class KernelEvaluator:

    struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator {
      PyObject_HEAD
      struct __pyx_vtabstruct_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *__pyx_vtab;
      int num_samples;
      int num_obs;
      int num_kernels;
      int num_cats;
      int num_continuous;
      double lower_prob_bound;
      double inv_vol;
      PyArrayObject *np_locs;
      PyArrayObject *np_sqrt_precs;
      PyArrayObject *np_cat_probs;
      PyArrayObject *np_kernel_types;
      PyArrayObject *np_kernel_sizes;
      PyArrayObject *np_kernel_ranges;
      PyArrayObject *np_objs;
      PyArrayObject *np_probs;
    };
    /* … */
    struct __pyx_vtabstruct_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator {
      __Pyx_memviewslice (*_probs)(struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *, __Pyx_memviewslice);
      PyObject *(*get_kernel_contrib)(struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *, PyArrayObject *, int __pyx_skip_dispatch);
      PyObject *(*get_regression_surrogate)(struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *, PyArrayObject *, int __pyx_skip_dispatch);
      PyObject *(*get_binary_kernel_densities)(struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *, PyArrayObject *, int __pyx_skip_dispatch);
      PyObject *(*get_probability_of_infeasibility)(struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *, PyArrayObject *, double, double, int __pyx_skip_dispatch);
      PyObject *(*get_probability_of_feasibility)(struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *, PyArrayObject *, double, double, int __pyx_skip_dispatch);
    };
    static struct __pyx_vtabstruct_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *__pyx_vtabptr_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator;

     050:

     051:     cdef int num_samples, num_obs, num_kernels, num_cats, num_continuous

     052:     cdef double lower_prob_bound, inv_vol

     053:

     054:     cdef np.ndarray np_locs, np_sqrt_precs, np_cat_probs

     055:     cdef np.ndarray np_kernel_types, np_kernel_sizes, np_kernel_ranges

     056:     cdef np.ndarray np_objs

     057:     cdef np.ndarray np_probs

     058:

    +059:     var_dict = {}

      __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 59, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem((PyObject *)__pyx_ptype_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator->tp_dict, __pyx_n_s_var_dict, __pyx_t_1) < 0) __PYX_ERR(0, 59, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      PyType_Modified(__pyx_ptype_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator);

     060:

    +061:     def __init__(self, locs, sqrt_precs, cat_probs, kernel_types, kernel_sizes, kernel_ranges,

    /* Python wrapper */
    static int __pyx_pw_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
    static int __pyx_pw_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
      PyObject *__pyx_v_locs = 0;
      PyObject *__pyx_v_sqrt_precs = 0;
      PyObject *__pyx_v_cat_probs = 0;
      PyObject *__pyx_v_kernel_types = 0;
      PyObject *__pyx_v_kernel_sizes = 0;
      PyObject *__pyx_v_kernel_ranges = 0;
      PyObject *__pyx_v_lower_prob_bound = 0;
      PyObject *__pyx_v_objs = 0;
      PyObject *__pyx_v_inv_vol = 0;
      int __pyx_r;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
      {
        static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_locs,&__pyx_n_s_sqrt_precs,&__pyx_n_s_cat_probs,&__pyx_n_s_kernel_types,&__pyx_n_s_kernel_sizes,&__pyx_n_s_kernel_ranges,&__pyx_n_s_lower_prob_bound,&__pyx_n_s_objs,&__pyx_n_s_inv_vol,0};
        PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
        if (unlikely(__pyx_kwds)) {
          Py_ssize_t kw_args;
          const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
          switch (pos_args) {
            case  9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
            CYTHON_FALLTHROUGH;
            case  8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
            CYTHON_FALLTHROUGH;
            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_locs)) != 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_sqrt_precs)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 1); __PYX_ERR(0, 61, __pyx_L3_error)
            }
            CYTHON_FALLTHROUGH;
            case  2:
            if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_cat_probs)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 2); __PYX_ERR(0, 61, __pyx_L3_error)
            }
            CYTHON_FALLTHROUGH;
            case  3:
            if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_kernel_types)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 3); __PYX_ERR(0, 61, __pyx_L3_error)
            }
            CYTHON_FALLTHROUGH;
            case  4:
            if (likely((values[4] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_kernel_sizes)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 4); __PYX_ERR(0, 61, __pyx_L3_error)
            }
            CYTHON_FALLTHROUGH;
            case  5:
            if (likely((values[5] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_kernel_ranges)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 5); __PYX_ERR(0, 61, __pyx_L3_error)
            }
            CYTHON_FALLTHROUGH;
            case  6:
            if (likely((values[6] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_lower_prob_bound)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 6); __PYX_ERR(0, 61, __pyx_L3_error)
            }
            CYTHON_FALLTHROUGH;
            case  7:
            if (likely((values[7] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_objs)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 7); __PYX_ERR(0, 61, __pyx_L3_error)
            }
            CYTHON_FALLTHROUGH;
            case  8:
            if (likely((values[8] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_inv_vol)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 8); __PYX_ERR(0, 61, __pyx_L3_error)
            }
          }
          if (unlikely(kw_args > 0)) {
            if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 61, __pyx_L3_error)
          }
        } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
          goto __pyx_L5_argtuple_error;
        } else {
          values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
          values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
          values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
          values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
          values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
          values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
          values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
          values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
          values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
        }
        __pyx_v_locs = values[0];
        __pyx_v_sqrt_precs = values[1];
        __pyx_v_cat_probs = values[2];
        __pyx_v_kernel_types = values[3];
        __pyx_v_kernel_sizes = values[4];
        __pyx_v_kernel_ranges = values[5];
        __pyx_v_lower_prob_bound = values[6];
        __pyx_v_objs = values[7];
        __pyx_v_inv_vol = values[8];
      }
      goto __pyx_L4_argument_unpacking_done;
      __pyx_L5_argtuple_error:;
      __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 61, __pyx_L3_error)
      __pyx_L3_error:;
      __Pyx_AddTraceback("gryffin.bayesian_network.kernel_evaluations.KernelEvaluator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __Pyx_RefNannyFinishContext();
      return -1;
      __pyx_L4_argument_unpacking_done:;
      __pyx_r = __pyx_pf_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator___init__(((struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *)__pyx_v_self), __pyx_v_locs, __pyx_v_sqrt_precs, __pyx_v_cat_probs, __pyx_v_kernel_types, __pyx_v_kernel_sizes, __pyx_v_kernel_ranges, __pyx_v_lower_prob_bound, __pyx_v_objs, __pyx_v_inv_vol);
      int __pyx_lineno = 0;
      const char *__pyx_filename = NULL;
      int __pyx_clineno = 0;

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

    static int __pyx_pf_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator___init__(struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *__pyx_v_self, PyObject *__pyx_v_locs, PyObject *__pyx_v_sqrt_precs, PyObject *__pyx_v_cat_probs, PyObject *__pyx_v_kernel_types, PyObject *__pyx_v_kernel_sizes, PyObject *__pyx_v_kernel_ranges, PyObject *__pyx_v_lower_prob_bound, PyObject *__pyx_v_objs, PyObject *__pyx_v_inv_vol) {
      int __pyx_r;
      __Pyx_TraceDeclarations
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("__init__", 0);
      __Pyx_TraceCall("__init__", __pyx_f[0], 61, 0, __PYX_ERR(0, 61, __pyx_L1_error));
    /* … */
      /* function exit code */
      __pyx_r = 0;
      goto __pyx_L0;
      __pyx_L1_error:;
      __Pyx_XDECREF(__pyx_t_1);
      __Pyx_XDECREF(__pyx_t_2);
      __Pyx_XDECREF(__pyx_t_5);
      __Pyx_XDECREF(__pyx_t_6);
      __Pyx_XDECREF(__pyx_t_7);
      __Pyx_AddTraceback("gryffin.bayesian_network.kernel_evaluations.KernelEvaluator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = -1;
      __pyx_L0:;
      __Pyx_TraceReturn(Py_None, 0);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

     062:                  lower_prob_bound, objs, inv_vol):

     063:

    +064:         self.np_locs          = locs

      if (!(likely(((__pyx_v_locs) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_locs, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 64, __pyx_L1_error)
      __pyx_t_1 = __pyx_v_locs;
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_GIVEREF(__pyx_t_1);
      __Pyx_GOTREF(__pyx_v_self->np_locs);
      __Pyx_DECREF(((PyObject *)__pyx_v_self->np_locs));
      __pyx_v_self->np_locs = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +065:         self.np_sqrt_precs    = sqrt_precs

      if (!(likely(((__pyx_v_sqrt_precs) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_sqrt_precs, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 65, __pyx_L1_error)
      __pyx_t_1 = __pyx_v_sqrt_precs;
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_GIVEREF(__pyx_t_1);
      __Pyx_GOTREF(__pyx_v_self->np_sqrt_precs);
      __Pyx_DECREF(((PyObject *)__pyx_v_self->np_sqrt_precs));
      __pyx_v_self->np_sqrt_precs = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +066:         self.np_cat_probs     = cat_probs

      if (!(likely(((__pyx_v_cat_probs) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_cat_probs, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 66, __pyx_L1_error)
      __pyx_t_1 = __pyx_v_cat_probs;
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_GIVEREF(__pyx_t_1);
      __Pyx_GOTREF(__pyx_v_self->np_cat_probs);
      __Pyx_DECREF(((PyObject *)__pyx_v_self->np_cat_probs));
      __pyx_v_self->np_cat_probs = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +067:         self.np_kernel_types  = kernel_types

      if (!(likely(((__pyx_v_kernel_types) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_kernel_types, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 67, __pyx_L1_error)
      __pyx_t_1 = __pyx_v_kernel_types;
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_GIVEREF(__pyx_t_1);
      __Pyx_GOTREF(__pyx_v_self->np_kernel_types);
      __Pyx_DECREF(((PyObject *)__pyx_v_self->np_kernel_types));
      __pyx_v_self->np_kernel_types = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +068:         self.np_kernel_sizes  = kernel_sizes

      if (!(likely(((__pyx_v_kernel_sizes) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_kernel_sizes, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 68, __pyx_L1_error)
      __pyx_t_1 = __pyx_v_kernel_sizes;
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_GIVEREF(__pyx_t_1);
      __Pyx_GOTREF(__pyx_v_self->np_kernel_sizes);
      __Pyx_DECREF(((PyObject *)__pyx_v_self->np_kernel_sizes));
      __pyx_v_self->np_kernel_sizes = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +069:         self.np_kernel_ranges = kernel_ranges

      if (!(likely(((__pyx_v_kernel_ranges) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_kernel_ranges, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 69, __pyx_L1_error)
      __pyx_t_1 = __pyx_v_kernel_ranges;
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_GIVEREF(__pyx_t_1);
      __Pyx_GOTREF(__pyx_v_self->np_kernel_ranges);
      __Pyx_DECREF(((PyObject *)__pyx_v_self->np_kernel_ranges));
      __pyx_v_self->np_kernel_ranges = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

    +070:         self.np_objs          = objs

      if (!(likely(((__pyx_v_objs) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_objs, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 70, __pyx_L1_error)
      __pyx_t_1 = __pyx_v_objs;
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_GIVEREF(__pyx_t_1);
      __Pyx_GOTREF(__pyx_v_self->np_objs);
      __Pyx_DECREF(((PyObject *)__pyx_v_self->np_objs));
      __pyx_v_self->np_objs = ((PyArrayObject *)__pyx_t_1);
      __pyx_t_1 = 0;

     071:

    +072:         self.num_samples      = locs.shape[0]

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_locs, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 72, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 72, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_t_3 = __Pyx_PyInt_As_int(__pyx_t_2); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 72, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_v_self->num_samples = __pyx_t_3;

    +073:         self.num_obs          = locs.shape[1]

      __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_locs, __pyx_n_s_shape); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 73, __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, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 73, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_t_3 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 73, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_v_self->num_obs = __pyx_t_3;

    +074:         self.num_kernels      = locs.shape[2]

      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_locs, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 74, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 74, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_t_3 = __Pyx_PyInt_As_int(__pyx_t_2); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 74, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_v_self->num_kernels = __pyx_t_3;

    +075:         self.lower_prob_bound = lower_prob_bound

      __pyx_t_4 = __pyx_PyFloat_AsDouble(__pyx_v_lower_prob_bound); if (unlikely((__pyx_t_4 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 75, __pyx_L1_error)
      __pyx_v_self->lower_prob_bound = __pyx_t_4;

    +076:         self.inv_vol          = inv_vol

      __pyx_t_4 = __pyx_PyFloat_AsDouble(__pyx_v_inv_vol); if (unlikely((__pyx_t_4 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 76, __pyx_L1_error)
      __pyx_v_self->inv_vol = __pyx_t_4;

     077:

    +078:         self.np_probs = np.zeros(self.num_obs, dtype = np.float64)

      __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 78, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_zeros); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 78, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_self->num_obs); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 78, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 78, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_GIVEREF(__pyx_t_2);
      PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2);
      __pyx_t_2 = 0;
      __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 78, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_np); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 78, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 78, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_7) < 0) __PYX_ERR(0, 78, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_5, __pyx_t_2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 78, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      if (!(likely(((__pyx_t_7) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_7, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 78, __pyx_L1_error)
      __Pyx_GIVEREF(__pyx_t_7);
      __Pyx_GOTREF(__pyx_v_self->np_probs);
      __Pyx_DECREF(((PyObject *)__pyx_v_self->np_probs));
      __pyx_v_self->np_probs = ((PyArrayObject *)__pyx_t_7);
      __pyx_t_7 = 0;

     079:

     080:         # number of continuous variables (continuous kernels have id 0 or 1)

    +081:         self.num_continuous = np.sum(kernel_types < 1.5)

      __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 81, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_sum); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 81, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_t_2 = PyObject_RichCompare(__pyx_v_kernel_types, __pyx_float_1_5, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 81, __pyx_L1_error)
      __pyx_t_1 = NULL;
      if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
        __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_5);
        if (likely(__pyx_t_1)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
          __Pyx_INCREF(__pyx_t_1);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_5, function);
        }
      }
      __pyx_t_7 = (__pyx_t_1) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_1, __pyx_t_2) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_2);
      __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 81, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __pyx_t_3 = __Pyx_PyInt_As_int(__pyx_t_7); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 81, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      __pyx_v_self->num_continuous = __pyx_t_3;

     082:

     083:     @cython.boundscheck(False)

     084:     @cython.cdivision(True)

    +085:     cdef double [:] _probs(self, double [:] sample):

    static __Pyx_memviewslice __pyx_f_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator__probs(struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *__pyx_v_self, __Pyx_memviewslice __pyx_v_sample) {
      int __pyx_v_sample_index;
      int __pyx_v_obs_index;
      int __pyx_v_feature_index;
      int __pyx_v_kernel_index;
      double __pyx_v_total_prob;
      double __pyx_v_prec_prod;
      double __pyx_v_exp_arg_sum;
      double __pyx_v_distance;
      __Pyx_memviewslice __pyx_v_locs = { 0, 0, { 0 }, { 0 }, { 0 } };
      __Pyx_memviewslice __pyx_v_sqrt_precs = { 0, 0, { 0 }, { 0 }, { 0 } };
      __Pyx_memviewslice __pyx_v_cat_probs = { 0, 0, { 0 }, { 0 }, { 0 } };
      __Pyx_memviewslice __pyx_v_kernel_types = { 0, 0, { 0 }, { 0 }, { 0 } };
      __Pyx_memviewslice __pyx_v_kernel_sizes = { 0, 0, { 0 }, { 0 }, { 0 } };
      __Pyx_memviewslice __pyx_v_kernel_ranges = { 0, 0, { 0 }, { 0 }, { 0 } };
      double __pyx_v_inv_sqrt_two_pi;
      __Pyx_memviewslice __pyx_v_probs = { 0, 0, { 0 }, { 0 }, { 0 } };
      double __pyx_v_obs_probs;
      __Pyx_memviewslice __pyx_r = { 0, 0, { 0 }, { 0 }, { 0 } };
      __Pyx_TraceDeclarations
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("_probs", 0);
      __Pyx_TraceCall("_probs", __pyx_f[0], 85, 0, __PYX_ERR(0, 85, __pyx_L1_error));
    /* … */
      /* function exit code */
      __pyx_L1_error:;
      __PYX_XDEC_MEMVIEW(&__pyx_t_1, 1);
      __PYX_XDEC_MEMVIEW(&__pyx_t_2, 1);
      __PYX_XDEC_MEMVIEW(&__pyx_t_3, 1);
      __pyx_r.data = NULL;
      __pyx_r.memview = NULL;
      __Pyx_AddTraceback("gryffin.bayesian_network.kernel_evaluations.KernelEvaluator._probs", __pyx_clineno, __pyx_lineno, __pyx_filename);
      goto __pyx_L2;
      __pyx_L0:;
      if (unlikely(!__pyx_r.memview)) {
        PyErr_SetString(PyExc_TypeError, "Memoryview return value is not initialized");
      }
      __pyx_L2:;
      __PYX_XDEC_MEMVIEW(&__pyx_v_locs, 1);
      __PYX_XDEC_MEMVIEW(&__pyx_v_sqrt_precs, 1);
      __PYX_XDEC_MEMVIEW(&__pyx_v_cat_probs, 1);
      __PYX_XDEC_MEMVIEW(&__pyx_v_kernel_types, 1);
      __PYX_XDEC_MEMVIEW(&__pyx_v_kernel_sizes, 1);
      __PYX_XDEC_MEMVIEW(&__pyx_v_kernel_ranges, 1);
      __PYX_XDEC_MEMVIEW(&__pyx_v_probs, 1);
      __Pyx_TraceReturn(Py_None, 0);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

     086:

     087:         cdef int    sample_index, obs_index, feature_index, kernel_index

     088:         cdef double total_prob, prec_prod, exp_arg_sum, distance

     089:

    +090:         cdef double [:, :, :] locs       = self.np_locs

      __pyx_t_1 = __Pyx_PyObject_to_MemoryviewSlice_dsdsds_double(((PyObject *)__pyx_v_self->np_locs), PyBUF_WRITABLE); if (unlikely(!__pyx_t_1.memview)) __PYX_ERR(0, 90, __pyx_L1_error)
      __pyx_v_locs = __pyx_t_1;
      __pyx_t_1.memview = NULL;
      __pyx_t_1.data = NULL;

    +091:         cdef double [:, :, :] sqrt_precs = self.np_sqrt_precs

      __pyx_t_1 = __Pyx_PyObject_to_MemoryviewSlice_dsdsds_double(((PyObject *)__pyx_v_self->np_sqrt_precs), PyBUF_WRITABLE); if (unlikely(!__pyx_t_1.memview)) __PYX_ERR(0, 91, __pyx_L1_error)
      __pyx_v_sqrt_precs = __pyx_t_1;
      __pyx_t_1.memview = NULL;
      __pyx_t_1.data = NULL;

    +092:         cdef double [:, :, :] cat_probs  = self.np_cat_probs

      __pyx_t_1 = __Pyx_PyObject_to_MemoryviewSlice_dsdsds_double(((PyObject *)__pyx_v_self->np_cat_probs), PyBUF_WRITABLE); if (unlikely(!__pyx_t_1.memview)) __PYX_ERR(0, 92, __pyx_L1_error)
      __pyx_v_cat_probs = __pyx_t_1;
      __pyx_t_1.memview = NULL;
      __pyx_t_1.data = NULL;

     093:

    +094:         cdef int [:] kernel_types = self.np_kernel_types

      __pyx_t_2 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(((PyObject *)__pyx_v_self->np_kernel_types), PyBUF_WRITABLE); if (unlikely(!__pyx_t_2.memview)) __PYX_ERR(0, 94, __pyx_L1_error)
      __pyx_v_kernel_types = __pyx_t_2;
      __pyx_t_2.memview = NULL;
      __pyx_t_2.data = NULL;

    +095:         cdef int [:] kernel_sizes = self.np_kernel_sizes

      __pyx_t_2 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(((PyObject *)__pyx_v_self->np_kernel_sizes), PyBUF_WRITABLE); if (unlikely(!__pyx_t_2.memview)) __PYX_ERR(0, 95, __pyx_L1_error)
      __pyx_v_kernel_sizes = __pyx_t_2;
      __pyx_t_2.memview = NULL;
      __pyx_t_2.data = NULL;

    +096:         cdef double [:] kernel_ranges = self.np_kernel_ranges

      __pyx_t_3 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(((PyObject *)__pyx_v_self->np_kernel_ranges), PyBUF_WRITABLE); if (unlikely(!__pyx_t_3.memview)) __PYX_ERR(0, 96, __pyx_L1_error)
      __pyx_v_kernel_ranges = __pyx_t_3;
      __pyx_t_3.memview = NULL;
      __pyx_t_3.data = NULL;

     097:

    +098:         cdef double inv_sqrt_two_pi = 0.3989422804014327

      __pyx_v_inv_sqrt_two_pi = 0.3989422804014327;

     099:

    +100:         cdef double [:] probs = self.np_probs

      __pyx_t_3 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(((PyObject *)__pyx_v_self->np_probs), PyBUF_WRITABLE); if (unlikely(!__pyx_t_3.memview)) __PYX_ERR(0, 100, __pyx_L1_error)
      __pyx_v_probs = __pyx_t_3;
      __pyx_t_3.memview = NULL;
      __pyx_t_3.data = NULL;

    +101:         for obs_index in range(self.num_obs):

      __pyx_t_4 = __pyx_v_self->num_obs;
      __pyx_t_5 = __pyx_t_4;
      for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
        __pyx_v_obs_index = __pyx_t_6;

    +102:             probs[obs_index] = 0.

        __pyx_t_7 = __pyx_v_obs_index;
        if (__pyx_t_7 < 0) __pyx_t_7 += __pyx_v_probs.shape[0];
        *((double *) ( /* dim=0 */ (__pyx_v_probs.data + __pyx_t_7 * __pyx_v_probs.strides[0]) )) = 0.;
      }

     103:

     104:         cdef double cat_prob

     105:         cdef double obs_probs

     106:

     107:         # for each kernel location

    +108:         for obs_index in range(self.num_obs):

      __pyx_t_4 = __pyx_v_self->num_obs;
      __pyx_t_5 = __pyx_t_4;
      for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
        __pyx_v_obs_index = __pyx_t_6;

    +109:             obs_probs = 0.

        __pyx_v_obs_probs = 0.;

     110:

     111:             # for each BNN sample

    +112:             for sample_index in range(self.num_samples):

        __pyx_t_8 = __pyx_v_self->num_samples;
        __pyx_t_9 = __pyx_t_8;
        for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
          __pyx_v_sample_index = __pyx_t_10;

    +113:                 total_prob     = 1.

          __pyx_v_total_prob = 1.;

    +114:                 prec_prod      = 1.

          __pyx_v_prec_prod = 1.;

    +115:                 exp_arg_sum    = 0.

          __pyx_v_exp_arg_sum = 0.;

    +116:                 feature_index, kernel_index = 0, 0

          __pyx_t_11 = 0;
          __pyx_t_12 = 0;
          __pyx_v_feature_index = __pyx_t_11;
          __pyx_v_kernel_index = __pyx_t_12;

     117:

     118:                 # for each kernel/dimension

    +119:                 while kernel_index < self.num_kernels:

          while (1) {
            __pyx_t_13 = ((__pyx_v_kernel_index < __pyx_v_self->num_kernels) != 0);
            if (!__pyx_t_13) break;

     120:                     # -----------------

     121:                     # continuous kernel

     122:                     # -----------------

    +123:                     if kernel_types[kernel_index] == 0:

            __pyx_t_7 = __pyx_v_kernel_index;
            if (__pyx_t_7 < 0) __pyx_t_7 += __pyx_v_kernel_types.shape[0];
            __pyx_t_13 = (((*((int *) ( /* dim=0 */ (__pyx_v_kernel_types.data + __pyx_t_7 * __pyx_v_kernel_types.strides[0]) ))) == 0) != 0);
            if (__pyx_t_13) {
    /* … */
              goto __pyx_L11;
            }

     124:                         # get product of inverse standard deviations

    +125:                         prec_prod = prec_prod * sqrt_precs[sample_index, obs_index, kernel_index]

              __pyx_t_7 = __pyx_v_sample_index;
              __pyx_t_14 = __pyx_v_obs_index;
              __pyx_t_15 = __pyx_v_kernel_index;
              if (__pyx_t_7 < 0) __pyx_t_7 += __pyx_v_sqrt_precs.shape[0];
              if (__pyx_t_14 < 0) __pyx_t_14 += __pyx_v_sqrt_precs.shape[1];
              if (__pyx_t_15 < 0) __pyx_t_15 += __pyx_v_sqrt_precs.shape[2];
              __pyx_v_prec_prod = (__pyx_v_prec_prod * (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_sqrt_precs.data + __pyx_t_7 * __pyx_v_sqrt_precs.strides[0]) ) + __pyx_t_14 * __pyx_v_sqrt_precs.strides[1]) ) + __pyx_t_15 * __pyx_v_sqrt_precs.strides[2]) ))));

     126:                         # get sum of the exponent argument

    +127:                         exp_arg_sum = exp_arg_sum + (sqrt_precs[sample_index, obs_index, kernel_index] * (sample[feature_index] - locs[sample_index, obs_index, kernel_index]))**2

              __pyx_t_15 = __pyx_v_sample_index;
              __pyx_t_14 = __pyx_v_obs_index;
              __pyx_t_7 = __pyx_v_kernel_index;
              if (__pyx_t_15 < 0) __pyx_t_15 += __pyx_v_sqrt_precs.shape[0];
              if (__pyx_t_14 < 0) __pyx_t_14 += __pyx_v_sqrt_precs.shape[1];
              if (__pyx_t_7 < 0) __pyx_t_7 += __pyx_v_sqrt_precs.shape[2];
              __pyx_t_16 = __pyx_v_feature_index;
              if (__pyx_t_16 < 0) __pyx_t_16 += __pyx_v_sample.shape[0];
              __pyx_t_17 = __pyx_v_sample_index;
              __pyx_t_18 = __pyx_v_obs_index;
              __pyx_t_19 = __pyx_v_kernel_index;
              if (__pyx_t_17 < 0) __pyx_t_17 += __pyx_v_locs.shape[0];
              if (__pyx_t_18 < 0) __pyx_t_18 += __pyx_v_locs.shape[1];
              if (__pyx_t_19 < 0) __pyx_t_19 += __pyx_v_locs.shape[2];
              __pyx_v_exp_arg_sum = (__pyx_v_exp_arg_sum + pow(((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_sqrt_precs.data + __pyx_t_15 * __pyx_v_sqrt_precs.strides[0]) ) + __pyx_t_14 * __pyx_v_sqrt_precs.strides[1]) ) + __pyx_t_7 * __pyx_v_sqrt_precs.strides[2]) ))) * ((*((double *) ( /* dim=0 */ (__pyx_v_sample.data + __pyx_t_16 * __pyx_v_sample.strides[0]) ))) - (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_locs.data + __pyx_t_17 * __pyx_v_locs.strides[0]) ) + __pyx_t_18 * __pyx_v_locs.strides[1]) ) + __pyx_t_19 * __pyx_v_locs.strides[2]) ))))), 2.0));

     128:

     129:                     # --------------------------

     130:                     # continuous periodic kernel

     131:                     # --------------------------

    +132:                     elif kernel_types[kernel_index] == 1:

            __pyx_t_19 = __pyx_v_kernel_index;
            if (__pyx_t_19 < 0) __pyx_t_19 += __pyx_v_kernel_types.shape[0];
            __pyx_t_13 = (((*((int *) ( /* dim=0 */ (__pyx_v_kernel_types.data + __pyx_t_19 * __pyx_v_kernel_types.strides[0]) ))) == 1) != 0);
            if (__pyx_t_13) {
    /* … */
              goto __pyx_L11;
            }

     133:                         # get product of inverse standard deviations

    +134:                         prec_prod = prec_prod * sqrt_precs[sample_index, obs_index, kernel_index]

              __pyx_t_19 = __pyx_v_sample_index;
              __pyx_t_18 = __pyx_v_obs_index;
              __pyx_t_17 = __pyx_v_kernel_index;
              if (__pyx_t_19 < 0) __pyx_t_19 += __pyx_v_sqrt_precs.shape[0];
              if (__pyx_t_18 < 0) __pyx_t_18 += __pyx_v_sqrt_precs.shape[1];
              if (__pyx_t_17 < 0) __pyx_t_17 += __pyx_v_sqrt_precs.shape[2];
              __pyx_v_prec_prod = (__pyx_v_prec_prod * (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_sqrt_precs.data + __pyx_t_19 * __pyx_v_sqrt_precs.strides[0]) ) + __pyx_t_18 * __pyx_v_sqrt_precs.strides[1]) ) + __pyx_t_17 * __pyx_v_sqrt_precs.strides[2]) ))));

     135:                         # get distance between gaussian mean and sample location

    +136:                         distance = abs(sample[feature_index] - locs[sample_index, obs_index, kernel_index])

              __pyx_t_17 = __pyx_v_feature_index;
              if (__pyx_t_17 < 0) __pyx_t_17 += __pyx_v_sample.shape[0];
              __pyx_t_18 = __pyx_v_sample_index;
              __pyx_t_19 = __pyx_v_obs_index;
              __pyx_t_16 = __pyx_v_kernel_index;
              if (__pyx_t_18 < 0) __pyx_t_18 += __pyx_v_locs.shape[0];
              if (__pyx_t_19 < 0) __pyx_t_19 += __pyx_v_locs.shape[1];
              if (__pyx_t_16 < 0) __pyx_t_16 += __pyx_v_locs.shape[2];
              __pyx_v_distance = fabs(((*((double *) ( /* dim=0 */ (__pyx_v_sample.data + __pyx_t_17 * __pyx_v_sample.strides[0]) ))) - (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_locs.data + __pyx_t_18 * __pyx_v_locs.strides[0]) ) + __pyx_t_19 * __pyx_v_locs.strides[1]) ) + __pyx_t_16 * __pyx_v_locs.strides[2]) )))));

     137:                         # consider closest distance across boundaries

    +138:                         if kernel_ranges[kernel_index] - distance < distance:

              __pyx_t_16 = __pyx_v_kernel_index;
              if (__pyx_t_16 < 0) __pyx_t_16 += __pyx_v_kernel_ranges.shape[0];
              __pyx_t_13 = ((((*((double *) ( /* dim=0 */ (__pyx_v_kernel_ranges.data + __pyx_t_16 * __pyx_v_kernel_ranges.strides[0]) ))) - __pyx_v_distance) < __pyx_v_distance) != 0);
              if (__pyx_t_13) {
    /* … */
              }

    +139:                             distance = kernel_ranges[kernel_index] - distance

                __pyx_t_16 = __pyx_v_kernel_index;
                if (__pyx_t_16 < 0) __pyx_t_16 += __pyx_v_kernel_ranges.shape[0];
                __pyx_v_distance = ((*((double *) ( /* dim=0 */ (__pyx_v_kernel_ranges.data + __pyx_t_16 * __pyx_v_kernel_ranges.strides[0]) ))) - __pyx_v_distance);

     140:                         # get sum of the exponent argument

    +141:                         exp_arg_sum = exp_arg_sum + (sqrt_precs[sample_index, obs_index, kernel_index] * distance)**2

              __pyx_t_16 = __pyx_v_sample_index;
              __pyx_t_19 = __pyx_v_obs_index;
              __pyx_t_18 = __pyx_v_kernel_index;
              if (__pyx_t_16 < 0) __pyx_t_16 += __pyx_v_sqrt_precs.shape[0];
              if (__pyx_t_19 < 0) __pyx_t_19 += __pyx_v_sqrt_precs.shape[1];
              if (__pyx_t_18 < 0) __pyx_t_18 += __pyx_v_sqrt_precs.shape[2];
              __pyx_v_exp_arg_sum = (__pyx_v_exp_arg_sum + pow(((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_sqrt_precs.data + __pyx_t_16 * __pyx_v_sqrt_precs.strides[0]) ) + __pyx_t_19 * __pyx_v_sqrt_precs.strides[1]) ) + __pyx_t_18 * __pyx_v_sqrt_precs.strides[2]) ))) * __pyx_v_distance), 2.0));

     142:

     143:                     # ------------------

     144:                     # categorical kernel

     145:                     # ------------------

    +146:                     elif kernel_types[kernel_index] == 2:

            __pyx_t_18 = __pyx_v_kernel_index;
            if (__pyx_t_18 < 0) __pyx_t_18 += __pyx_v_kernel_types.shape[0];
            __pyx_t_13 = (((*((int *) ( /* dim=0 */ (__pyx_v_kernel_types.data + __pyx_t_18 * __pyx_v_kernel_types.strides[0]) ))) == 2) != 0);
            if (__pyx_t_13) {
    /* … */
            }
            __pyx_L11:;

     147:                         # total probability, if we have continuous variables only this stays at 1

    +148:                         total_prob *= cat_probs[sample_index, obs_index, kernel_index + <int>round(sample[feature_index])]

              __pyx_t_18 = __pyx_v_feature_index;
              if (__pyx_t_18 < 0) __pyx_t_18 += __pyx_v_sample.shape[0];
              __pyx_t_19 = __pyx_v_sample_index;
              __pyx_t_16 = __pyx_v_obs_index;
              __pyx_t_17 = (__pyx_v_kernel_index + ((int)round((*((double *) ( /* dim=0 */ (__pyx_v_sample.data + __pyx_t_18 * __pyx_v_sample.strides[0]) ))))));
              if (__pyx_t_19 < 0) __pyx_t_19 += __pyx_v_cat_probs.shape[0];
              if (__pyx_t_16 < 0) __pyx_t_16 += __pyx_v_cat_probs.shape[1];
              if (__pyx_t_17 < 0) __pyx_t_17 += __pyx_v_cat_probs.shape[2];
              __pyx_v_total_prob = (__pyx_v_total_prob * (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_cat_probs.data + __pyx_t_19 * __pyx_v_cat_probs.strides[0]) ) + __pyx_t_16 * __pyx_v_cat_probs.strides[1]) ) + __pyx_t_17 * __pyx_v_cat_probs.strides[2]) ))));

     149:

     150:                     # increment indices

    +151:                     kernel_index  += kernel_sizes[kernel_index]  # kernel size can be >1 for a certain param

            __pyx_t_18 = __pyx_v_kernel_index;
            if (__pyx_t_18 < 0) __pyx_t_18 += __pyx_v_kernel_sizes.shape[0];
            __pyx_v_kernel_index = (__pyx_v_kernel_index + (*((int *) ( /* dim=0 */ (__pyx_v_kernel_sizes.data + __pyx_t_18 * __pyx_v_kernel_sizes.strides[0]) ))));

    +152:                     feature_index += 1

            __pyx_v_feature_index = (__pyx_v_feature_index + 1);
          }

     153:

     154:                 # combine precision product with exponent argument, and categorical probability

    +155:                 obs_probs += total_prob * prec_prod * exp(-0.5 * exp_arg_sum)

          __pyx_v_obs_probs = (__pyx_v_obs_probs + ((__pyx_v_total_prob * __pyx_v_prec_prod) * exp((-0.5 * __pyx_v_exp_arg_sum))));

     156:

     157:                 # we assume 1000 BNN samples, so 100 is 10%

    +158:                 if sample_index == 100:

          __pyx_t_13 = ((__pyx_v_sample_index == 0x64) != 0);
          if (__pyx_t_13) {
    /* … */
            goto __pyx_L13;
          }

     159:                     # boosting criterion

    +160:                     if 0.01 * obs_probs * inv_sqrt_two_pi**self.num_continuous < self.lower_prob_bound:

            __pyx_t_13 = ((((0.01 * __pyx_v_obs_probs) * pow(__pyx_v_inv_sqrt_two_pi, ((double)__pyx_v_self->num_continuous))) < __pyx_v_self->lower_prob_bound) != 0);
            if (__pyx_t_13) {
    /* … */
            }

    +161:                         probs[obs_index] = 0.01 * obs_probs

              __pyx_t_18 = __pyx_v_obs_index;
              if (__pyx_t_18 < 0) __pyx_t_18 += __pyx_v_probs.shape[0];
              *((double *) ( /* dim=0 */ (__pyx_v_probs.data + __pyx_t_18 * __pyx_v_probs.strides[0]) )) = (0.01 * __pyx_v_obs_probs);

    +162:                         break

              goto __pyx_L8_break;

     163:                 else:

     164:                     # we take the average across the BNN samples

     165:                     # normalise the gaussian kernel probabilities

    +166:                     probs[obs_index] = (obs_probs * inv_sqrt_two_pi**self.num_continuous) / self.num_samples

          /*else*/ {
            __pyx_t_18 = __pyx_v_obs_index;
            if (__pyx_t_18 < 0) __pyx_t_18 += __pyx_v_probs.shape[0];
            *((double *) ( /* dim=0 */ (__pyx_v_probs.data + __pyx_t_18 * __pyx_v_probs.strides[0]) )) = ((__pyx_v_obs_probs * pow(__pyx_v_inv_sqrt_two_pi, ((double)__pyx_v_self->num_continuous))) / ((double)__pyx_v_self->num_samples));
          }
          __pyx_L13:;
        }
        __pyx_L8_break:;
      }

    +167:         return probs

      __PYX_INC_MEMVIEW(&__pyx_v_probs, 0);
      __pyx_r = __pyx_v_probs;
      goto __pyx_L0;

     168:

    +169:     cpdef get_kernel_contrib(self, np.ndarray sample):

    static PyObject *__pyx_pw_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_3get_kernel_contrib(PyObject *__pyx_v_self, PyObject *__pyx_v_sample); /*proto*/
    static PyObject *__pyx_f_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_get_kernel_contrib(struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *__pyx_v_self, PyArrayObject *__pyx_v_sample, int __pyx_skip_dispatch) {
      int __pyx_v_obs_index;
      double __pyx_v_temp_0;
      double __pyx_v_temp_1;
      double __pyx_v_inv_den;
      __Pyx_memviewslice __pyx_v_sample_memview = { 0, 0, { 0 }, { 0 }, { 0 } };
      PyObject *__pyx_v_probs_sample = NULL;
      double __pyx_v_num;
      double __pyx_v_den;
      __Pyx_memviewslice __pyx_v_objs = { 0, 0, { 0 }, { 0 }, { 0 } };
      PyObject *__pyx_r = NULL;
      __Pyx_TraceDeclarations
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("get_kernel_contrib", 0);
      __Pyx_TraceCall("get_kernel_contrib", __pyx_f[0], 169, 0, __PYX_ERR(0, 169, __pyx_L1_error));
      /* Check if called by wrapper */
      if (unlikely(__pyx_skip_dispatch)) ;
      /* Check if overridden in Python */
      else if (unlikely((Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0) || (Py_TYPE(((PyObject *)__pyx_v_self))->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)))) {
        #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
        static PY_UINT64_T __pyx_tp_dict_version = __PYX_DICT_VERSION_INIT, __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT;
        if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
          PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
          #endif
          __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_kernel_contrib); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 169, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_1);
          if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_3get_kernel_contrib)) {
            __Pyx_XDECREF(__pyx_r);
            __Pyx_INCREF(__pyx_t_1);
            __pyx_t_3 = __pyx_t_1; __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_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, ((PyObject *)__pyx_v_sample)) : __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_sample));
            __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
            if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 169, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_2);
            __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
            __pyx_r = __pyx_t_2;
            __pyx_t_2 = 0;
            __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
            goto __pyx_L0;
          }
          #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
          __pyx_tp_dict_version = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
          __pyx_obj_dict_version = __Pyx_get_object_dict_version(((PyObject *)__pyx_v_self));
          if (unlikely(__pyx_type_dict_guard != __pyx_tp_dict_version)) {
            __pyx_tp_dict_version = __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT;
          }
          #endif
          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
          #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
        }
        #endif
      }
    /* … */
      /* 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_XDEC_MEMVIEW(&__pyx_t_5, 1);
      __Pyx_AddTraceback("gryffin.bayesian_network.kernel_evaluations.KernelEvaluator.get_kernel_contrib", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = 0;
      __pyx_L0:;
      __PYX_XDEC_MEMVIEW(&__pyx_v_sample_memview, 1);
      __Pyx_XDECREF(__pyx_v_probs_sample);
      __PYX_XDEC_MEMVIEW(&__pyx_v_objs, 1);
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_TraceReturn(__pyx_r, 0);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    /* Python wrapper */
    static PyObject *__pyx_pw_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_3get_kernel_contrib(PyObject *__pyx_v_self, PyObject *__pyx_v_sample); /*proto*/
    static PyObject *__pyx_pw_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_3get_kernel_contrib(PyObject *__pyx_v_self, PyObject *__pyx_v_sample) {
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("get_kernel_contrib (wrapper)", 0);
      if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_sample), __pyx_ptype_5numpy_ndarray, 1, "sample", 0))) __PYX_ERR(0, 169, __pyx_L1_error)
      __pyx_r = __pyx_pf_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_2get_kernel_contrib(((struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *)__pyx_v_self), ((PyArrayObject *)__pyx_v_sample));
      int __pyx_lineno = 0;
      const char *__pyx_filename = NULL;
      int __pyx_clineno = 0;

      /* function exit code */
      goto __pyx_L0;
      __pyx_L1_error:;
      __pyx_r = NULL;
      __pyx_L0:;
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_2get_kernel_contrib(struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *__pyx_v_self, PyArrayObject *__pyx_v_sample) {
      PyObject *__pyx_r = NULL;
      __Pyx_TraceDeclarations
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("get_kernel_contrib", 0);
      __Pyx_TraceCall("get_kernel_contrib (wrapper)", __pyx_f[0], 169, 0, __PYX_ERR(0, 169, __pyx_L1_error));
      __Pyx_XDECREF(__pyx_r);
      __pyx_t_1 = __pyx_f_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_get_kernel_contrib(__pyx_v_self, __pyx_v_sample, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 169, __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("gryffin.bayesian_network.kernel_evaluations.KernelEvaluator.get_kernel_contrib", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      __pyx_L0:;
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_TraceReturn(__pyx_r, 0);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

     170:

     171:         cdef int obs_index

     172:         cdef double temp_0, temp_1

     173:         cdef double inv_den

     174:

    +175:         cdef double [:] sample_memview = sample

      __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(((PyObject *)__pyx_v_sample), PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 175, __pyx_L1_error)
      __pyx_v_sample_memview = __pyx_t_5;
      __pyx_t_5.memview = NULL;
      __pyx_t_5.data = NULL;

    +176:         probs_sample = self._probs(sample_memview)

      __pyx_t_5 = ((struct __pyx_vtabstruct_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *)__pyx_v_self->__pyx_vtab)->_probs(__pyx_v_self, __pyx_v_sample_memview); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 176, __pyx_L1_error)
      __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_t_5, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 176, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __PYX_XDEC_MEMVIEW(&__pyx_t_5, 1);
      __pyx_t_5.memview = NULL;
      __pyx_t_5.data = NULL;
      __pyx_v_probs_sample = __pyx_t_1;
      __pyx_t_1 = 0;

     177:

     178:         # construct numerator and denominator of acquisition

    +179:         cdef double num = 0.

      __pyx_v_num = 0.;

    +180:         cdef double den = 0.

      __pyx_v_den = 0.;

    +181:         cdef double [:] objs = self.np_objs

      __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(((PyObject *)__pyx_v_self->np_objs), PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 181, __pyx_L1_error)
      __pyx_v_objs = __pyx_t_5;
      __pyx_t_5.memview = NULL;
      __pyx_t_5.data = NULL;

     182:

    +183:         for obs_index in range(self.num_obs):

      __pyx_t_6 = __pyx_v_self->num_obs;
      __pyx_t_7 = __pyx_t_6;
      for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
        __pyx_v_obs_index = __pyx_t_8;

    +184:             temp_0 = objs[obs_index]

        __pyx_t_9 = __pyx_v_obs_index;
        __pyx_t_10 = -1;
        if (__pyx_t_9 < 0) {
          __pyx_t_9 += __pyx_v_objs.shape[0];
          if (unlikely(__pyx_t_9 < 0)) __pyx_t_10 = 0;
        } else if (unlikely(__pyx_t_9 >= __pyx_v_objs.shape[0])) __pyx_t_10 = 0;
        if (unlikely(__pyx_t_10 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_10);
          __PYX_ERR(0, 184, __pyx_L1_error)
        }
        __pyx_v_temp_0 = (*((double *) ( /* dim=0 */ (__pyx_v_objs.data + __pyx_t_9 * __pyx_v_objs.strides[0]) )));

    +185:             temp_1 = probs_sample[obs_index]

        __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_probs_sample, __pyx_v_obs_index, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 185, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __pyx_t_11 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_11 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 185, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __pyx_v_temp_1 = __pyx_t_11;

    +186:             num += temp_0 * temp_1

        __pyx_v_num = (__pyx_v_num + (__pyx_v_temp_0 * __pyx_v_temp_1));

    +187:             den += temp_1

        __pyx_v_den = (__pyx_v_den + __pyx_v_temp_1);
      }

     188:

    +189:         inv_den = 1. / (self.inv_vol + den)

      __pyx_t_11 = (__pyx_v_self->inv_vol + __pyx_v_den);
      if (unlikely(__pyx_t_11 == 0)) {
        PyErr_SetString(PyExc_ZeroDivisionError, "float division");
        __PYX_ERR(0, 189, __pyx_L1_error)
      }
      __pyx_v_inv_den = (1. / __pyx_t_11);

     190:

    +191:         return num, inv_den, probs_sample

      __Pyx_XDECREF(__pyx_r);
      __pyx_t_1 = PyFloat_FromDouble(__pyx_v_num); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 191, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_2 = PyFloat_FromDouble(__pyx_v_inv_den); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 191, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 191, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_GIVEREF(__pyx_t_1);
      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
      __Pyx_GIVEREF(__pyx_t_2);
      PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2);
      __Pyx_INCREF(__pyx_v_probs_sample);
      __Pyx_GIVEREF(__pyx_v_probs_sample);
      PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_v_probs_sample);
      __pyx_t_1 = 0;
      __pyx_t_2 = 0;
      __pyx_r = __pyx_t_3;
      __pyx_t_3 = 0;
      goto __pyx_L0;

     192:

    +193:     cpdef get_regression_surrogate(self, np.ndarray sample):

    static PyObject *__pyx_pw_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_5get_regression_surrogate(PyObject *__pyx_v_self, PyObject *__pyx_v_sample); /*proto*/
    static PyObject *__pyx_f_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_get_regression_surrogate(struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *__pyx_v_self, PyArrayObject *__pyx_v_sample, int __pyx_skip_dispatch) {
      int __pyx_v_obs_index;
      double __pyx_v_temp_0;
      double __pyx_v_temp_1;
      double __pyx_v_y_pred;
      __Pyx_memviewslice __pyx_v_sample_memview = { 0, 0, { 0 }, { 0 }, { 0 } };
      PyObject *__pyx_v_probs_sample = NULL;
      double __pyx_v_num;
      double __pyx_v_den;
      __Pyx_memviewslice __pyx_v_objs = { 0, 0, { 0 }, { 0 }, { 0 } };
      PyObject *__pyx_r = NULL;
      __Pyx_TraceDeclarations
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("get_regression_surrogate", 0);
      __Pyx_TraceCall("get_regression_surrogate", __pyx_f[0], 193, 0, __PYX_ERR(0, 193, __pyx_L1_error));
      /* Check if called by wrapper */
      if (unlikely(__pyx_skip_dispatch)) ;
      /* Check if overridden in Python */
      else if (unlikely((Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0) || (Py_TYPE(((PyObject *)__pyx_v_self))->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)))) {
        #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
        static PY_UINT64_T __pyx_tp_dict_version = __PYX_DICT_VERSION_INIT, __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT;
        if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
          PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
          #endif
          __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_regression_surrogate); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 193, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_1);
          if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_5get_regression_surrogate)) {
            __Pyx_XDECREF(__pyx_r);
            __Pyx_INCREF(__pyx_t_1);
            __pyx_t_3 = __pyx_t_1; __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_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, ((PyObject *)__pyx_v_sample)) : __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_sample));
            __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
            if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 193, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_2);
            __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
            __pyx_r = __pyx_t_2;
            __pyx_t_2 = 0;
            __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
            goto __pyx_L0;
          }
          #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
          __pyx_tp_dict_version = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
          __pyx_obj_dict_version = __Pyx_get_object_dict_version(((PyObject *)__pyx_v_self));
          if (unlikely(__pyx_type_dict_guard != __pyx_tp_dict_version)) {
            __pyx_tp_dict_version = __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT;
          }
          #endif
          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
          #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
        }
        #endif
      }
    /* … */
      /* 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_XDEC_MEMVIEW(&__pyx_t_5, 1);
      __Pyx_AddTraceback("gryffin.bayesian_network.kernel_evaluations.KernelEvaluator.get_regression_surrogate", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = 0;
      __pyx_L0:;
      __PYX_XDEC_MEMVIEW(&__pyx_v_sample_memview, 1);
      __Pyx_XDECREF(__pyx_v_probs_sample);
      __PYX_XDEC_MEMVIEW(&__pyx_v_objs, 1);
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_TraceReturn(__pyx_r, 0);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    /* Python wrapper */
    static PyObject *__pyx_pw_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_5get_regression_surrogate(PyObject *__pyx_v_self, PyObject *__pyx_v_sample); /*proto*/
    static PyObject *__pyx_pw_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_5get_regression_surrogate(PyObject *__pyx_v_self, PyObject *__pyx_v_sample) {
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("get_regression_surrogate (wrapper)", 0);
      if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_sample), __pyx_ptype_5numpy_ndarray, 1, "sample", 0))) __PYX_ERR(0, 193, __pyx_L1_error)
      __pyx_r = __pyx_pf_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_4get_regression_surrogate(((struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *)__pyx_v_self), ((PyArrayObject *)__pyx_v_sample));
      int __pyx_lineno = 0;
      const char *__pyx_filename = NULL;
      int __pyx_clineno = 0;

      /* function exit code */
      goto __pyx_L0;
      __pyx_L1_error:;
      __pyx_r = NULL;
      __pyx_L0:;
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_4get_regression_surrogate(struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *__pyx_v_self, PyArrayObject *__pyx_v_sample) {
      PyObject *__pyx_r = NULL;
      __Pyx_TraceDeclarations
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("get_regression_surrogate", 0);
      __Pyx_TraceCall("get_regression_surrogate (wrapper)", __pyx_f[0], 193, 0, __PYX_ERR(0, 193, __pyx_L1_error));
      __Pyx_XDECREF(__pyx_r);
      __pyx_t_1 = __pyx_f_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_get_regression_surrogate(__pyx_v_self, __pyx_v_sample, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 193, __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("gryffin.bayesian_network.kernel_evaluations.KernelEvaluator.get_regression_surrogate", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      __pyx_L0:;
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_TraceReturn(__pyx_r, 0);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

     194:

     195:         cdef int obs_index

     196:         cdef double temp_0, temp_1

     197:         cdef double inv_den

     198:         cdef double y_pred

    +199:         cdef double [:] sample_memview = sample

      __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(((PyObject *)__pyx_v_sample), PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 199, __pyx_L1_error)
      __pyx_v_sample_memview = __pyx_t_5;
      __pyx_t_5.memview = NULL;
      __pyx_t_5.data = NULL;

    +200:         probs_sample = self._probs(sample_memview)

      __pyx_t_5 = ((struct __pyx_vtabstruct_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *)__pyx_v_self->__pyx_vtab)->_probs(__pyx_v_self, __pyx_v_sample_memview); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 200, __pyx_L1_error)
      __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_t_5, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 200, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __PYX_XDEC_MEMVIEW(&__pyx_t_5, 1);
      __pyx_t_5.memview = NULL;
      __pyx_t_5.data = NULL;
      __pyx_v_probs_sample = __pyx_t_1;
      __pyx_t_1 = 0;

     201:

     202:         # construct numerator and denominator of acquisition

    +203:         cdef double num = 0.

      __pyx_v_num = 0.;

    +204:         cdef double den = 0.

      __pyx_v_den = 0.;

    +205:         cdef double [:] objs = self.np_objs

      __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(((PyObject *)__pyx_v_self->np_objs), PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 205, __pyx_L1_error)
      __pyx_v_objs = __pyx_t_5;
      __pyx_t_5.memview = NULL;
      __pyx_t_5.data = NULL;

     206:

    +207:         for obs_index in range(self.num_obs):

      __pyx_t_6 = __pyx_v_self->num_obs;
      __pyx_t_7 = __pyx_t_6;
      for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
        __pyx_v_obs_index = __pyx_t_8;

    +208:             temp_0 = objs[obs_index]

        __pyx_t_9 = __pyx_v_obs_index;
        __pyx_t_10 = -1;
        if (__pyx_t_9 < 0) {
          __pyx_t_9 += __pyx_v_objs.shape[0];
          if (unlikely(__pyx_t_9 < 0)) __pyx_t_10 = 0;
        } else if (unlikely(__pyx_t_9 >= __pyx_v_objs.shape[0])) __pyx_t_10 = 0;
        if (unlikely(__pyx_t_10 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_10);
          __PYX_ERR(0, 208, __pyx_L1_error)
        }
        __pyx_v_temp_0 = (*((double *) ( /* dim=0 */ (__pyx_v_objs.data + __pyx_t_9 * __pyx_v_objs.strides[0]) )));

    +209:             temp_1 = probs_sample[obs_index]

        __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_probs_sample, __pyx_v_obs_index, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 209, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __pyx_t_11 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_11 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 209, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __pyx_v_temp_1 = __pyx_t_11;

    +210:             num += temp_0 * temp_1

        __pyx_v_num = (__pyx_v_num + (__pyx_v_temp_0 * __pyx_v_temp_1));

    +211:             den += temp_1

        __pyx_v_den = (__pyx_v_den + __pyx_v_temp_1);
      }

     212:

    +213:         y_pred = num / (den + 1e-8)  # avoid division by zero

      __pyx_t_11 = (__pyx_v_den + 1e-8);
      if (unlikely(__pyx_t_11 == 0)) {
        PyErr_SetString(PyExc_ZeroDivisionError, "float division");
        __PYX_ERR(0, 213, __pyx_L1_error)
      }
      __pyx_v_y_pred = (__pyx_v_num / __pyx_t_11);

    +214:         return y_pred

      __Pyx_XDECREF(__pyx_r);
      __pyx_t_1 = PyFloat_FromDouble(__pyx_v_y_pred); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 214, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_r = __pyx_t_1;
      __pyx_t_1 = 0;
      goto __pyx_L0;

     215:

    +216:     cpdef get_binary_kernel_densities(self, np.ndarray sample):

    static PyObject *__pyx_pw_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_7get_binary_kernel_densities(PyObject *__pyx_v_self, PyObject *__pyx_v_sample); /*proto*/
    static PyObject *__pyx_f_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_get_binary_kernel_densities(struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *__pyx_v_self, PyArrayObject *__pyx_v_sample, int __pyx_skip_dispatch) {
      int __pyx_v_obs_index;
      double __pyx_v_density_0;
      double __pyx_v_density_1;
      double __pyx_v_num_0;
      double __pyx_v_num_1;
      double __pyx_v_log_density_0;
      double __pyx_v_log_density_1;
      __Pyx_memviewslice __pyx_v_sample_memview = { 0, 0, { 0 }, { 0 }, { 0 } };
      PyObject *__pyx_v_probs_sample = NULL;
      PyObject *__pyx_v_obj = NULL;
      PyObject *__pyx_r = NULL;
      __Pyx_TraceDeclarations
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("get_binary_kernel_densities", 0);
      __Pyx_TraceCall("get_binary_kernel_densities", __pyx_f[0], 216, 0, __PYX_ERR(0, 216, __pyx_L1_error));
      /* Check if called by wrapper */
      if (unlikely(__pyx_skip_dispatch)) ;
      /* Check if overridden in Python */
      else if (unlikely((Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0) || (Py_TYPE(((PyObject *)__pyx_v_self))->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)))) {
        #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
        static PY_UINT64_T __pyx_tp_dict_version = __PYX_DICT_VERSION_INIT, __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT;
        if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
          PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
          #endif
          __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_binary_kernel_densities); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 216, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_1);
          if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_7get_binary_kernel_densities)) {
            __Pyx_XDECREF(__pyx_r);
            __Pyx_INCREF(__pyx_t_1);
            __pyx_t_3 = __pyx_t_1; __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_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, ((PyObject *)__pyx_v_sample)) : __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_sample));
            __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
            if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 216, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_2);
            __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
            __pyx_r = __pyx_t_2;
            __pyx_t_2 = 0;
            __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
            goto __pyx_L0;
          }
          #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
          __pyx_tp_dict_version = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
          __pyx_obj_dict_version = __Pyx_get_object_dict_version(((PyObject *)__pyx_v_self));
          if (unlikely(__pyx_type_dict_guard != __pyx_tp_dict_version)) {
            __pyx_tp_dict_version = __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT;
          }
          #endif
          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
          #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
        }
        #endif
      }
    /* … */
      /* 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_XDEC_MEMVIEW(&__pyx_t_5, 1);
      __Pyx_XDECREF(__pyx_t_11);
      __Pyx_AddTraceback("gryffin.bayesian_network.kernel_evaluations.KernelEvaluator.get_binary_kernel_densities", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = 0;
      __pyx_L0:;
      __PYX_XDEC_MEMVIEW(&__pyx_v_sample_memview, 1);
      __Pyx_XDECREF(__pyx_v_probs_sample);
      __Pyx_XDECREF(__pyx_v_obj);
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_TraceReturn(__pyx_r, 0);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    /* Python wrapper */
    static PyObject *__pyx_pw_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_7get_binary_kernel_densities(PyObject *__pyx_v_self, PyObject *__pyx_v_sample); /*proto*/
    static PyObject *__pyx_pw_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_7get_binary_kernel_densities(PyObject *__pyx_v_self, PyObject *__pyx_v_sample) {
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("get_binary_kernel_densities (wrapper)", 0);
      if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_sample), __pyx_ptype_5numpy_ndarray, 1, "sample", 0))) __PYX_ERR(0, 216, __pyx_L1_error)
      __pyx_r = __pyx_pf_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_6get_binary_kernel_densities(((struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *)__pyx_v_self), ((PyArrayObject *)__pyx_v_sample));
      int __pyx_lineno = 0;
      const char *__pyx_filename = NULL;
      int __pyx_clineno = 0;

      /* function exit code */
      goto __pyx_L0;
      __pyx_L1_error:;
      __pyx_r = NULL;
      __pyx_L0:;
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_6get_binary_kernel_densities(struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *__pyx_v_self, PyArrayObject *__pyx_v_sample) {
      PyObject *__pyx_r = NULL;
      __Pyx_TraceDeclarations
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("get_binary_kernel_densities", 0);
      __Pyx_TraceCall("get_binary_kernel_densities (wrapper)", __pyx_f[0], 216, 0, __PYX_ERR(0, 216, __pyx_L1_error));
      __Pyx_XDECREF(__pyx_r);
      __pyx_t_1 = __pyx_f_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_get_binary_kernel_densities(__pyx_v_self, __pyx_v_sample, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 216, __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("gryffin.bayesian_network.kernel_evaluations.KernelEvaluator.get_binary_kernel_densities", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      __pyx_L0:;
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_TraceReturn(__pyx_r, 0);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

     217:

     218:         cdef int obs_index

    +219:         cdef double density_0 = 0.  # density of feasible

      __pyx_v_density_0 = 0.;

    +220:         cdef double density_1 = 0.  # density of infeasible

      __pyx_v_density_1 = 0.;

    +221:         cdef double num_0 = 0.

      __pyx_v_num_0 = 0.;

    +222:         cdef double num_1 = 0.

      __pyx_v_num_1 = 0.;

     223:         cdef double log_density_0

     224:         cdef double log_density_1

     225:

    +226:         cdef double [:] sample_memview = sample

      __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(((PyObject *)__pyx_v_sample), PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 226, __pyx_L1_error)
      __pyx_v_sample_memview = __pyx_t_5;
      __pyx_t_5.memview = NULL;
      __pyx_t_5.data = NULL;

    +227:         probs_sample = self._probs(sample_memview)

      __pyx_t_5 = ((struct __pyx_vtabstruct_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *)__pyx_v_self->__pyx_vtab)->_probs(__pyx_v_self, __pyx_v_sample_memview); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 227, __pyx_L1_error)
      __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_t_5, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 227, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __PYX_XDEC_MEMVIEW(&__pyx_t_5, 1);
      __pyx_t_5.memview = NULL;
      __pyx_t_5.data = NULL;
      __pyx_v_probs_sample = __pyx_t_1;
      __pyx_t_1 = 0;

     228:

    +229:         for obs_index, obj in enumerate(self.np_objs):

      __pyx_t_6 = 0;
      if (likely(PyList_CheckExact(((PyObject *)__pyx_v_self->np_objs))) || PyTuple_CheckExact(((PyObject *)__pyx_v_self->np_objs))) {
        __pyx_t_1 = ((PyObject *)__pyx_v_self->np_objs); __Pyx_INCREF(__pyx_t_1); __pyx_t_7 = 0;
        __pyx_t_8 = NULL;
      } else {
        __pyx_t_7 = -1; __pyx_t_1 = PyObject_GetIter(((PyObject *)__pyx_v_self->np_objs)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 229, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __pyx_t_8 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 229, __pyx_L1_error)
      }
      for (;;) {
        if (likely(!__pyx_t_8)) {
          if (likely(PyList_CheckExact(__pyx_t_1))) {
            if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_1)) break;
            #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
            __pyx_t_2 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_7); __Pyx_INCREF(__pyx_t_2); __pyx_t_7++; if (unlikely(0 < 0)) __PYX_ERR(0, 229, __pyx_L1_error)
            #else
            __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 229, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_2);
            #endif
          } else {
            if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
            #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
            __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_7); __Pyx_INCREF(__pyx_t_2); __pyx_t_7++; if (unlikely(0 < 0)) __PYX_ERR(0, 229, __pyx_L1_error)
            #else
            __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 229, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_2);
            #endif
          }
        } else {
          __pyx_t_2 = __pyx_t_8(__pyx_t_1);
          if (unlikely(!__pyx_t_2)) {
            PyObject* exc_type = PyErr_Occurred();
            if (exc_type) {
              if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
              else __PYX_ERR(0, 229, __pyx_L1_error)
            }
            break;
          }
          __Pyx_GOTREF(__pyx_t_2);
        }
        __Pyx_XDECREF_SET(__pyx_v_obj, __pyx_t_2);
        __pyx_t_2 = 0;
        __pyx_v_obs_index = __pyx_t_6;
        __pyx_t_6 = (__pyx_t_6 + 1);
    /* … */
      }
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;

    +230:             if obj > 0.5:

        __pyx_t_2 = PyObject_RichCompare(__pyx_v_obj, __pyx_float_0_5, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 230, __pyx_L1_error)
        __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_9 < 0)) __PYX_ERR(0, 230, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
        if (__pyx_t_9) {
    /* … */
          goto __pyx_L5;
        }

    +231:                 density_1 += probs_sample[obs_index]

          __pyx_t_2 = PyFloat_FromDouble(__pyx_v_density_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 231, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_2);
          __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_probs_sample, __pyx_v_obs_index, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 231, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_3);
          __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 231, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_4);
          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
          __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
          __pyx_t_10 = __pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_10 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 231, __pyx_L1_error)
          __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
          __pyx_v_density_1 = __pyx_t_10;

    +232:                 num_1 += 1.

          __pyx_v_num_1 = (__pyx_v_num_1 + 1.);

     233:             else:

    +234:                 density_0 += probs_sample[obs_index]

        /*else*/ {
          __pyx_t_4 = PyFloat_FromDouble(__pyx_v_density_0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 234, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_4);
          __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_probs_sample, __pyx_v_obs_index, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 234, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_3);
          __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 234, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_2);
          __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
          __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
          __pyx_t_10 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_10 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 234, __pyx_L1_error)
          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
          __pyx_v_density_0 = __pyx_t_10;

    +235:                 num_0 += 1.

          __pyx_v_num_0 = (__pyx_v_num_0 + 1.);
        }
        __pyx_L5:;

     236:

     237:         # normalize wrt the number of kernels

    +238:         log_density_0 = np.log(density_0) - np.log(num_0)

      __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 238, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_log); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 238, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_t_2 = PyFloat_FromDouble(__pyx_v_density_0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 238, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __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_2) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __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, 238, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 238, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_log); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 238, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_t_2 = PyFloat_FromDouble(__pyx_v_num_0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 238, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_11 = NULL;
      if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
        __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_4);
        if (likely(__pyx_t_11)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
          __Pyx_INCREF(__pyx_t_11);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_4, function);
        }
      }
      __pyx_t_3 = (__pyx_t_11) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_11, __pyx_t_2) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_2);
      __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 238, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __pyx_t_4 = PyNumber_Subtract(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 238, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __pyx_t_10 = __pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_10 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 238, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __pyx_v_log_density_0 = __pyx_t_10;

    +239:         log_density_1 = np.log(density_1) - np.log(num_1)

      __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 239, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_log); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 239, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __pyx_t_3 = PyFloat_FromDouble(__pyx_v_density_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 239, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_2 = NULL;
      if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_1))) {
        __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_1);
        if (likely(__pyx_t_2)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
          __Pyx_INCREF(__pyx_t_2);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_1, function);
        }
      }
      __pyx_t_4 = (__pyx_t_2) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_3);
      __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 239, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 239, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_log); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 239, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __pyx_t_3 = PyFloat_FromDouble(__pyx_v_num_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 239, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_11 = NULL;
      if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
        __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_2);
        if (likely(__pyx_t_11)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
          __Pyx_INCREF(__pyx_t_11);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_2, function);
        }
      }
      __pyx_t_1 = (__pyx_t_11) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_11, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
      __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 239, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_t_2 = PyNumber_Subtract(__pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 239, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_t_10 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_10 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 239, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_v_log_density_1 = __pyx_t_10;

     240:

    +241:         return log_density_0, log_density_1

      __Pyx_XDECREF(__pyx_r);
      __pyx_t_2 = PyFloat_FromDouble(__pyx_v_log_density_0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 241, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_1 = PyFloat_FromDouble(__pyx_v_log_density_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 241, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 241, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_GIVEREF(__pyx_t_2);
      PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
      __Pyx_GIVEREF(__pyx_t_1);
      PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_1);
      __pyx_t_2 = 0;
      __pyx_t_1 = 0;
      __pyx_r = __pyx_t_4;
      __pyx_t_4 = 0;
      goto __pyx_L0;

     242:

    +243:     cpdef get_probability_of_infeasibility(self, np.ndarray sample, double log_prior_0, double log_prior_1):

    static PyObject *__pyx_pw_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_9get_probability_of_infeasibility(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
    static PyObject *__pyx_f_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_get_probability_of_infeasibility(struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *__pyx_v_self, PyArrayObject *__pyx_v_sample, double __pyx_v_log_prior_0, double __pyx_v_log_prior_1, int __pyx_skip_dispatch) {
      double __pyx_v_prob_infeas;
      double __pyx_v_log_density_0;
      double __pyx_v_log_density_1;
      double __pyx_v_posterior_0;
      double __pyx_v_posterior_1;
      PyObject *__pyx_r = NULL;
      __Pyx_TraceDeclarations
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("get_probability_of_infeasibility", 0);
      __Pyx_TraceCall("get_probability_of_infeasibility", __pyx_f[0], 243, 0, __PYX_ERR(0, 243, __pyx_L1_error));
      /* Check if called by wrapper */
      if (unlikely(__pyx_skip_dispatch)) ;
      /* Check if overridden in Python */
      else if (unlikely((Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0) || (Py_TYPE(((PyObject *)__pyx_v_self))->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)))) {
        #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
        static PY_UINT64_T __pyx_tp_dict_version = __PYX_DICT_VERSION_INIT, __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT;
        if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
          PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
          #endif
          __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_probability_of_infeasibility); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 243, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_1);
          if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_9get_probability_of_infeasibility)) {
            __Pyx_XDECREF(__pyx_r);
            __pyx_t_3 = PyFloat_FromDouble(__pyx_v_log_prior_0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 243, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_3);
            __pyx_t_4 = PyFloat_FromDouble(__pyx_v_log_prior_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 243, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_4);
            __Pyx_INCREF(__pyx_t_1);
            __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
            __pyx_t_7 = 0;
            if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
              __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
              if (likely(__pyx_t_6)) {
                PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
                __Pyx_INCREF(__pyx_t_6);
                __Pyx_INCREF(function);
                __Pyx_DECREF_SET(__pyx_t_5, function);
                __pyx_t_7 = 1;
              }
            }
            #if CYTHON_FAST_PYCALL
            if (PyFunction_Check(__pyx_t_5)) {
              PyObject *__pyx_temp[4] = {__pyx_t_6, ((PyObject *)__pyx_v_sample), __pyx_t_3, __pyx_t_4};
              __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 3+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 243, __pyx_L1_error)
              __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
              __Pyx_GOTREF(__pyx_t_2);
              __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
              __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
            } else
            #endif
            #if CYTHON_FAST_PYCCALL
            if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
              PyObject *__pyx_temp[4] = {__pyx_t_6, ((PyObject *)__pyx_v_sample), __pyx_t_3, __pyx_t_4};
              __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 3+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 243, __pyx_L1_error)
              __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
              __Pyx_GOTREF(__pyx_t_2);
              __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
              __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
            } else
            #endif
            {
              __pyx_t_8 = PyTuple_New(3+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 243, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_8);
              if (__pyx_t_6) {
                __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
              }
              __Pyx_INCREF(((PyObject *)__pyx_v_sample));
              __Pyx_GIVEREF(((PyObject *)__pyx_v_sample));
              PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, ((PyObject *)__pyx_v_sample));
              __Pyx_GIVEREF(__pyx_t_3);
              PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_t_3);
              __Pyx_GIVEREF(__pyx_t_4);
              PyTuple_SET_ITEM(__pyx_t_8, 2+__pyx_t_7, __pyx_t_4);
              __pyx_t_3 = 0;
              __pyx_t_4 = 0;
              __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 243, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_2);
              __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
            }
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
            __pyx_r = __pyx_t_2;
            __pyx_t_2 = 0;
            __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
            goto __pyx_L0;
          }
          #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
          __pyx_tp_dict_version = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
          __pyx_obj_dict_version = __Pyx_get_object_dict_version(((PyObject *)__pyx_v_self));
          if (unlikely(__pyx_type_dict_guard != __pyx_tp_dict_version)) {
            __pyx_tp_dict_version = __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT;
          }
          #endif
          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
          #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
        }
        #endif
      }
    /* … */
      /* 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_XDECREF(__pyx_t_6);
      __Pyx_XDECREF(__pyx_t_8);
      __Pyx_AddTraceback("gryffin.bayesian_network.kernel_evaluations.KernelEvaluator.get_probability_of_infeasibility", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = 0;
      __pyx_L0:;
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_TraceReturn(__pyx_r, 0);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    /* Python wrapper */
    static PyObject *__pyx_pw_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_9get_probability_of_infeasibility(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
    static PyObject *__pyx_pw_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_9get_probability_of_infeasibility(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
      PyArrayObject *__pyx_v_sample = 0;
      double __pyx_v_log_prior_0;
      double __pyx_v_log_prior_1;
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("get_probability_of_infeasibility (wrapper)", 0);
      {
        static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_sample,&__pyx_n_s_log_prior_0,&__pyx_n_s_log_prior_1,0};
        PyObject* values[3] = {0,0,0};
        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_sample)) != 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_log_prior_0)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("get_probability_of_infeasibility", 1, 3, 3, 1); __PYX_ERR(0, 243, __pyx_L3_error)
            }
            CYTHON_FALLTHROUGH;
            case  2:
            if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_log_prior_1)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("get_probability_of_infeasibility", 1, 3, 3, 2); __PYX_ERR(0, 243, __pyx_L3_error)
            }
          }
          if (unlikely(kw_args > 0)) {
            if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get_probability_of_infeasibility") < 0)) __PYX_ERR(0, 243, __pyx_L3_error)
          }
        } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
          goto __pyx_L5_argtuple_error;
        } else {
          values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
          values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
          values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        }
        __pyx_v_sample = ((PyArrayObject *)values[0]);
        __pyx_v_log_prior_0 = __pyx_PyFloat_AsDouble(values[1]); if (unlikely((__pyx_v_log_prior_0 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 243, __pyx_L3_error)
        __pyx_v_log_prior_1 = __pyx_PyFloat_AsDouble(values[2]); if (unlikely((__pyx_v_log_prior_1 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 243, __pyx_L3_error)
      }
      goto __pyx_L4_argument_unpacking_done;
      __pyx_L5_argtuple_error:;
      __Pyx_RaiseArgtupleInvalid("get_probability_of_infeasibility", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 243, __pyx_L3_error)
      __pyx_L3_error:;
      __Pyx_AddTraceback("gryffin.bayesian_network.kernel_evaluations.KernelEvaluator.get_probability_of_infeasibility", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __Pyx_RefNannyFinishContext();
      return NULL;
      __pyx_L4_argument_unpacking_done:;
      if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_sample), __pyx_ptype_5numpy_ndarray, 1, "sample", 0))) __PYX_ERR(0, 243, __pyx_L1_error)
      __pyx_r = __pyx_pf_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_8get_probability_of_infeasibility(((struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *)__pyx_v_self), __pyx_v_sample, __pyx_v_log_prior_0, __pyx_v_log_prior_1);
      int __pyx_lineno = 0;
      const char *__pyx_filename = NULL;
      int __pyx_clineno = 0;

      /* function exit code */
      goto __pyx_L0;
      __pyx_L1_error:;
      __pyx_r = NULL;
      __pyx_L0:;
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_8get_probability_of_infeasibility(struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *__pyx_v_self, PyArrayObject *__pyx_v_sample, double __pyx_v_log_prior_0, double __pyx_v_log_prior_1) {
      PyObject *__pyx_r = NULL;
      __Pyx_TraceDeclarations
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("get_probability_of_infeasibility", 0);
      __Pyx_TraceCall("get_probability_of_infeasibility (wrapper)", __pyx_f[0], 243, 0, __PYX_ERR(0, 243, __pyx_L1_error));
      __Pyx_XDECREF(__pyx_r);
      __pyx_t_1 = __pyx_f_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_get_probability_of_infeasibility(__pyx_v_self, __pyx_v_sample, __pyx_v_log_prior_0, __pyx_v_log_prior_1, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 243, __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("gryffin.bayesian_network.kernel_evaluations.KernelEvaluator.get_probability_of_infeasibility", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      __pyx_L0:;
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_TraceReturn(__pyx_r, 0);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

     244:

     245:         # 0 = feasible, 1 = infeasible

     246:         cdef double prob_infeas

     247:         cdef double log_density_0

     248:         cdef double log_density_1

     249:         cdef double posterior_0

     250:         cdef double posterior_1

     251:

     252:         # get log probabilities

    +253:         log_density_0, log_density_1 = self.get_binary_kernel_densities(sample)

      __pyx_t_1 = ((struct __pyx_vtabstruct_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *)__pyx_v_self->__pyx_vtab)->get_binary_kernel_densities(__pyx_v_self, __pyx_v_sample, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 253, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      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, 253, __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_5 = PyTuple_GET_ITEM(sequence, 1);
        } else {
          __pyx_t_2 = PyList_GET_ITEM(sequence, 0);
          __pyx_t_5 = PyList_GET_ITEM(sequence, 1);
        }
        __Pyx_INCREF(__pyx_t_2);
        __Pyx_INCREF(__pyx_t_5);
        #else
        __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 253, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 253, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_5);
        #endif
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      } else {
        Py_ssize_t index = -1;
        __pyx_t_8 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 253, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_8);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __pyx_t_9 = Py_TYPE(__pyx_t_8)->tp_iternext;
        index = 0; __pyx_t_2 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed;
        __Pyx_GOTREF(__pyx_t_2);
        index = 1; __pyx_t_5 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_5)) goto __pyx_L3_unpacking_failed;
        __Pyx_GOTREF(__pyx_t_5);
        if (__Pyx_IternextUnpackEndCheck(__pyx_t_9(__pyx_t_8), 2) < 0) __PYX_ERR(0, 253, __pyx_L1_error)
        __pyx_t_9 = NULL;
        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
        goto __pyx_L4_unpacking_done;
        __pyx_L3_unpacking_failed:;
        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
        __pyx_t_9 = NULL;
        if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
        __PYX_ERR(0, 253, __pyx_L1_error)
        __pyx_L4_unpacking_done:;
      }
      __pyx_t_10 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_10 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 253, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_t_11 = __pyx_PyFloat_AsDouble(__pyx_t_5); if (unlikely((__pyx_t_11 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 253, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __pyx_v_log_density_0 = __pyx_t_10;
      __pyx_v_log_density_1 = __pyx_t_11;

     254:

     255:         # compute unnormalized posteriors

    +256:         posterior_0 = exp(log_density_0 + log_prior_0)

      __pyx_v_posterior_0 = exp((__pyx_v_log_density_0 + __pyx_v_log_prior_0));

    +257:         posterior_1 = exp(log_density_1 + log_prior_1)

      __pyx_v_posterior_1 = exp((__pyx_v_log_density_1 + __pyx_v_log_prior_1));

     258:

     259:         # guard against zero division. This may happen if both densities are zero

    +260:         if np.log(posterior_0 + posterior_1) < - 230:  # i.e. less then 1e-100

      __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 260, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_log); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 260, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __pyx_t_5 = PyFloat_FromDouble((__pyx_v_posterior_0 + __pyx_v_posterior_1)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 260, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_8 = NULL;
      if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
        __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_2);
        if (likely(__pyx_t_8)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
          __Pyx_INCREF(__pyx_t_8);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_2, function);
        }
      }
      __pyx_t_1 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_8, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_5);
      __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 260, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_t_2 = PyObject_RichCompare(__pyx_t_1, __pyx_int_neg_230, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 260, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_t_12 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_12 < 0)) __PYX_ERR(0, 260, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      if (__pyx_t_12) {
    /* … */
      }

    +261:             return exp(log_prior_1) / (exp(log_prior_0) + exp(log_prior_1))  # return prior prob

        __Pyx_XDECREF(__pyx_r);
        __pyx_t_11 = exp(__pyx_v_log_prior_1);
        __pyx_t_10 = (exp(__pyx_v_log_prior_0) + exp(__pyx_v_log_prior_1));
        if (unlikely(__pyx_t_10 == 0)) {
          PyErr_SetString(PyExc_ZeroDivisionError, "float division");
          __PYX_ERR(0, 261, __pyx_L1_error)
        }
        __pyx_t_2 = PyFloat_FromDouble((__pyx_t_11 / __pyx_t_10)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 261, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __pyx_r = __pyx_t_2;
        __pyx_t_2 = 0;
        goto __pyx_L0;

     262:

     263:         # get normalized posterior for prob of infeasible

    +264:         prob_infeas = posterior_1 / (posterior_0 + posterior_1)

      __pyx_t_10 = (__pyx_v_posterior_0 + __pyx_v_posterior_1);
      if (unlikely(__pyx_t_10 == 0)) {
        PyErr_SetString(PyExc_ZeroDivisionError, "float division");
        __PYX_ERR(0, 264, __pyx_L1_error)
      }
      __pyx_v_prob_infeas = (__pyx_v_posterior_1 / __pyx_t_10);

     265:

    +266:         return prob_infeas

      __Pyx_XDECREF(__pyx_r);
      __pyx_t_2 = PyFloat_FromDouble(__pyx_v_prob_infeas); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 266, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_r = __pyx_t_2;
      __pyx_t_2 = 0;
      goto __pyx_L0;

     267:

    +268:     cpdef get_probability_of_feasibility(self, np.ndarray sample, double log_prior_0, double log_prior_1):

    static PyObject *__pyx_pw_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_11get_probability_of_feasibility(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
    static PyObject *__pyx_f_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_get_probability_of_feasibility(struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *__pyx_v_self, PyArrayObject *__pyx_v_sample, double __pyx_v_log_prior_0, double __pyx_v_log_prior_1, int __pyx_skip_dispatch) {
      double __pyx_v_prob_feas;
      double __pyx_v_log_density_0;
      double __pyx_v_log_density_1;
      double __pyx_v_posterior_0;
      double __pyx_v_posterior_1;
      PyObject *__pyx_r = NULL;
      __Pyx_TraceDeclarations
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("get_probability_of_feasibility", 0);
      __Pyx_TraceCall("get_probability_of_feasibility", __pyx_f[0], 268, 0, __PYX_ERR(0, 268, __pyx_L1_error));
      /* Check if called by wrapper */
      if (unlikely(__pyx_skip_dispatch)) ;
      /* Check if overridden in Python */
      else if (unlikely((Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0) || (Py_TYPE(((PyObject *)__pyx_v_self))->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)))) {
        #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
        static PY_UINT64_T __pyx_tp_dict_version = __PYX_DICT_VERSION_INIT, __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT;
        if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
          PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
          #endif
          __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_probability_of_feasibility); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 268, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_1);
          if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_11get_probability_of_feasibility)) {
            __Pyx_XDECREF(__pyx_r);
            __pyx_t_3 = PyFloat_FromDouble(__pyx_v_log_prior_0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 268, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_3);
            __pyx_t_4 = PyFloat_FromDouble(__pyx_v_log_prior_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 268, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_4);
            __Pyx_INCREF(__pyx_t_1);
            __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
            __pyx_t_7 = 0;
            if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
              __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
              if (likely(__pyx_t_6)) {
                PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
                __Pyx_INCREF(__pyx_t_6);
                __Pyx_INCREF(function);
                __Pyx_DECREF_SET(__pyx_t_5, function);
                __pyx_t_7 = 1;
              }
            }
            #if CYTHON_FAST_PYCALL
            if (PyFunction_Check(__pyx_t_5)) {
              PyObject *__pyx_temp[4] = {__pyx_t_6, ((PyObject *)__pyx_v_sample), __pyx_t_3, __pyx_t_4};
              __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 3+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 268, __pyx_L1_error)
              __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
              __Pyx_GOTREF(__pyx_t_2);
              __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
              __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
            } else
            #endif
            #if CYTHON_FAST_PYCCALL
            if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
              PyObject *__pyx_temp[4] = {__pyx_t_6, ((PyObject *)__pyx_v_sample), __pyx_t_3, __pyx_t_4};
              __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 3+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 268, __pyx_L1_error)
              __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
              __Pyx_GOTREF(__pyx_t_2);
              __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
              __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
            } else
            #endif
            {
              __pyx_t_8 = PyTuple_New(3+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 268, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_8);
              if (__pyx_t_6) {
                __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
              }
              __Pyx_INCREF(((PyObject *)__pyx_v_sample));
              __Pyx_GIVEREF(((PyObject *)__pyx_v_sample));
              PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, ((PyObject *)__pyx_v_sample));
              __Pyx_GIVEREF(__pyx_t_3);
              PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_t_3);
              __Pyx_GIVEREF(__pyx_t_4);
              PyTuple_SET_ITEM(__pyx_t_8, 2+__pyx_t_7, __pyx_t_4);
              __pyx_t_3 = 0;
              __pyx_t_4 = 0;
              __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 268, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_2);
              __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
            }
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
            __pyx_r = __pyx_t_2;
            __pyx_t_2 = 0;
            __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
            goto __pyx_L0;
          }
          #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
          __pyx_tp_dict_version = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
          __pyx_obj_dict_version = __Pyx_get_object_dict_version(((PyObject *)__pyx_v_self));
          if (unlikely(__pyx_type_dict_guard != __pyx_tp_dict_version)) {
            __pyx_tp_dict_version = __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT;
          }
          #endif
          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
          #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
        }
        #endif
      }
    /* … */
      /* 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_XDECREF(__pyx_t_6);
      __Pyx_XDECREF(__pyx_t_8);
      __Pyx_AddTraceback("gryffin.bayesian_network.kernel_evaluations.KernelEvaluator.get_probability_of_feasibility", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = 0;
      __pyx_L0:;
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_TraceReturn(__pyx_r, 0);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    /* Python wrapper */
    static PyObject *__pyx_pw_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_11get_probability_of_feasibility(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
    static PyObject *__pyx_pw_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_11get_probability_of_feasibility(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
      PyArrayObject *__pyx_v_sample = 0;
      double __pyx_v_log_prior_0;
      double __pyx_v_log_prior_1;
      PyObject *__pyx_r = 0;
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("get_probability_of_feasibility (wrapper)", 0);
      {
        static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_sample,&__pyx_n_s_log_prior_0,&__pyx_n_s_log_prior_1,0};
        PyObject* values[3] = {0,0,0};
        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_sample)) != 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_log_prior_0)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("get_probability_of_feasibility", 1, 3, 3, 1); __PYX_ERR(0, 268, __pyx_L3_error)
            }
            CYTHON_FALLTHROUGH;
            case  2:
            if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_log_prior_1)) != 0)) kw_args--;
            else {
              __Pyx_RaiseArgtupleInvalid("get_probability_of_feasibility", 1, 3, 3, 2); __PYX_ERR(0, 268, __pyx_L3_error)
            }
          }
          if (unlikely(kw_args > 0)) {
            if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get_probability_of_feasibility") < 0)) __PYX_ERR(0, 268, __pyx_L3_error)
          }
        } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
          goto __pyx_L5_argtuple_error;
        } else {
          values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
          values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
          values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        }
        __pyx_v_sample = ((PyArrayObject *)values[0]);
        __pyx_v_log_prior_0 = __pyx_PyFloat_AsDouble(values[1]); if (unlikely((__pyx_v_log_prior_0 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 268, __pyx_L3_error)
        __pyx_v_log_prior_1 = __pyx_PyFloat_AsDouble(values[2]); if (unlikely((__pyx_v_log_prior_1 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 268, __pyx_L3_error)
      }
      goto __pyx_L4_argument_unpacking_done;
      __pyx_L5_argtuple_error:;
      __Pyx_RaiseArgtupleInvalid("get_probability_of_feasibility", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 268, __pyx_L3_error)
      __pyx_L3_error:;
      __Pyx_AddTraceback("gryffin.bayesian_network.kernel_evaluations.KernelEvaluator.get_probability_of_feasibility", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __Pyx_RefNannyFinishContext();
      return NULL;
      __pyx_L4_argument_unpacking_done:;
      if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_sample), __pyx_ptype_5numpy_ndarray, 1, "sample", 0))) __PYX_ERR(0, 268, __pyx_L1_error)
      __pyx_r = __pyx_pf_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_10get_probability_of_feasibility(((struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *)__pyx_v_self), __pyx_v_sample, __pyx_v_log_prior_0, __pyx_v_log_prior_1);
      int __pyx_lineno = 0;
      const char *__pyx_filename = NULL;
      int __pyx_clineno = 0;

      /* function exit code */
      goto __pyx_L0;
      __pyx_L1_error:;
      __pyx_r = NULL;
      __pyx_L0:;
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

    static PyObject *__pyx_pf_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_10get_probability_of_feasibility(struct __pyx_obj_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *__pyx_v_self, PyArrayObject *__pyx_v_sample, double __pyx_v_log_prior_0, double __pyx_v_log_prior_1) {
      PyObject *__pyx_r = NULL;
      __Pyx_TraceDeclarations
      __Pyx_RefNannyDeclarations
      __Pyx_RefNannySetupContext("get_probability_of_feasibility", 0);
      __Pyx_TraceCall("get_probability_of_feasibility (wrapper)", __pyx_f[0], 268, 0, __PYX_ERR(0, 268, __pyx_L1_error));
      __Pyx_XDECREF(__pyx_r);
      __pyx_t_1 = __pyx_f_7gryffin_16bayesian_network_18kernel_evaluations_15KernelEvaluator_get_probability_of_feasibility(__pyx_v_self, __pyx_v_sample, __pyx_v_log_prior_0, __pyx_v_log_prior_1, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 268, __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("gryffin.bayesian_network.kernel_evaluations.KernelEvaluator.get_probability_of_feasibility", __pyx_clineno, __pyx_lineno, __pyx_filename);
      __pyx_r = NULL;
      __pyx_L0:;
      __Pyx_XGIVEREF(__pyx_r);
      __Pyx_TraceReturn(__pyx_r, 0);
      __Pyx_RefNannyFinishContext();
      return __pyx_r;
    }

     269:

     270:         # 0 = feasible, 1 = infeasible

     271:         cdef double prob_feas

     272:         cdef double log_density_0

     273:         cdef double log_density_1

     274:         cdef double posterior_0

     275:         cdef double posterior_1

     276:

     277:         # get log probabilities

    +278:         log_density_0, log_density_1 = self.get_binary_kernel_densities(sample)

      __pyx_t_1 = ((struct __pyx_vtabstruct_7gryffin_16bayesian_network_18kernel_evaluations_KernelEvaluator *)__pyx_v_self->__pyx_vtab)->get_binary_kernel_densities(__pyx_v_self, __pyx_v_sample, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 278, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      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, 278, __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_5 = PyTuple_GET_ITEM(sequence, 1);
        } else {
          __pyx_t_2 = PyList_GET_ITEM(sequence, 0);
          __pyx_t_5 = PyList_GET_ITEM(sequence, 1);
        }
        __Pyx_INCREF(__pyx_t_2);
        __Pyx_INCREF(__pyx_t_5);
        #else
        __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 278, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 278, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_5);
        #endif
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      } else {
        Py_ssize_t index = -1;
        __pyx_t_8 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 278, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_8);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __pyx_t_9 = Py_TYPE(__pyx_t_8)->tp_iternext;
        index = 0; __pyx_t_2 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed;
        __Pyx_GOTREF(__pyx_t_2);
        index = 1; __pyx_t_5 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_5)) goto __pyx_L3_unpacking_failed;
        __Pyx_GOTREF(__pyx_t_5);
        if (__Pyx_IternextUnpackEndCheck(__pyx_t_9(__pyx_t_8), 2) < 0) __PYX_ERR(0, 278, __pyx_L1_error)
        __pyx_t_9 = NULL;
        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
        goto __pyx_L4_unpacking_done;
        __pyx_L3_unpacking_failed:;
        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
        __pyx_t_9 = NULL;
        if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
        __PYX_ERR(0, 278, __pyx_L1_error)
        __pyx_L4_unpacking_done:;
      }
      __pyx_t_10 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_10 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 278, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_t_11 = __pyx_PyFloat_AsDouble(__pyx_t_5); if (unlikely((__pyx_t_11 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 278, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __pyx_v_log_density_0 = __pyx_t_10;
      __pyx_v_log_density_1 = __pyx_t_11;

     279:

     280:         # compute unnormalized posteriors

    +281:         posterior_0 = exp(log_density_0 + log_prior_0)

      __pyx_v_posterior_0 = exp((__pyx_v_log_density_0 + __pyx_v_log_prior_0));

    +282:         posterior_1 = exp(log_density_1 + log_prior_1)

      __pyx_v_posterior_1 = exp((__pyx_v_log_density_1 + __pyx_v_log_prior_1));

     283:

     284:         # guard against zero division. This may happen if both densities are zero

    +285:         if np.log(posterior_0 + posterior_1) < - 230:  # i.e. less then 1e-100

      __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 285, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_log); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 285, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __pyx_t_5 = PyFloat_FromDouble((__pyx_v_posterior_0 + __pyx_v_posterior_1)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 285, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_8 = NULL;
      if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
        __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_2);
        if (likely(__pyx_t_8)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
          __Pyx_INCREF(__pyx_t_8);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_2, function);
        }
      }
      __pyx_t_1 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_8, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_5);
      __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 285, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_t_2 = PyObject_RichCompare(__pyx_t_1, __pyx_int_neg_230, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 285, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_t_12 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_12 < 0)) __PYX_ERR(0, 285, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      if (__pyx_t_12) {
    /* … */
      }

    +286:             return exp(log_prior_1) / (exp(log_prior_0) + exp(log_prior_1))  # return prior prob

        __Pyx_XDECREF(__pyx_r);
        __pyx_t_11 = exp(__pyx_v_log_prior_1);
        __pyx_t_10 = (exp(__pyx_v_log_prior_0) + exp(__pyx_v_log_prior_1));
        if (unlikely(__pyx_t_10 == 0)) {
          PyErr_SetString(PyExc_ZeroDivisionError, "float division");
          __PYX_ERR(0, 286, __pyx_L1_error)
        }
        __pyx_t_2 = PyFloat_FromDouble((__pyx_t_11 / __pyx_t_10)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 286, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __pyx_r = __pyx_t_2;
        __pyx_t_2 = 0;
        goto __pyx_L0;

     287:

     288:         # get normalized posterior for prob of infeasible

    +289:         prob_feas = posterior_0 / (posterior_0 + posterior_1)

      __pyx_t_10 = (__pyx_v_posterior_0 + __pyx_v_posterior_1);
      if (unlikely(__pyx_t_10 == 0)) {
        PyErr_SetString(PyExc_ZeroDivisionError, "float division");
        __PYX_ERR(0, 289, __pyx_L1_error)
      }
      __pyx_v_prob_feas = (__pyx_v_posterior_0 / __pyx_t_10);

     290:

    +291:         return prob_feas

      __Pyx_XDECREF(__pyx_r);
      __pyx_t_2 = PyFloat_FromDouble(__pyx_v_prob_feas); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 291, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_r = __pyx_t_2;
      __pyx_t_2 = 0;
      goto __pyx_L0;