Generated by Cython 0.29.28

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

+001: # cython: language_level=3, boundscheck=True, wraparound=False
  __pyx_t_2 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+002: import numpy as np
  __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 2, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+003: import psutil      # For Memory Profiling
  __pyx_t_1 = __Pyx_Import(__pyx_n_s_psutil, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_psutil, __pyx_t_1) < 0) __PYX_ERR(0, 3, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+004: import os
  __pyx_t_1 = __Pyx_Import(__pyx_n_s_os, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_os, __pyx_t_1) < 0) __PYX_ERR(0, 4, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 005: cimport cython
 006: 
 007: #from scipy.special import logsumexp
 008: from libc.math cimport exp, log   # For doing Exponentials and Logs
 009: 
+010: DTYPE = np.float # The float data type
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 10, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_float); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 10, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_DTYPE, __pyx_t_2) < 0) __PYX_ERR(0, 10, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 011: 
 012: ##############################################################################
 013: #### Helper Functions
 014: 
+015: cdef inline double logsumexp(double[:] vec):
static CYTHON_INLINE double __pyx_f_8hapsburg_5cfunc_logsumexp(__Pyx_memviewslice __pyx_v_vec) {
  Py_ssize_t __pyx_v_i;
  double __pyx_v_result;
  double __pyx_v_largest;
  double __pyx_r;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("logsumexp", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_WriteUnraisable("hapsburg.cfunc.logsumexp", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
  __pyx_r = 0;
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 016:   """Do the Log of the Sum of Exponentials."""
 017:   cdef Py_ssize_t i  # The iterator Variable
+018:   cdef double result = 0.0
  __pyx_v_result = 0.0;
+019:   cdef double largest = vec[0]
  __pyx_t_1 = 0;
  __pyx_t_2 = -1;
  if (__pyx_t_1 < 0) {
    __pyx_t_2 = 0;
  } else if (unlikely(__pyx_t_1 >= __pyx_v_vec.shape[0])) __pyx_t_2 = 0;
  if (unlikely(__pyx_t_2 != -1)) {
    __Pyx_RaiseBufferIndexError(__pyx_t_2);
    __PYX_ERR(0, 19, __pyx_L1_error)
  }
  __pyx_v_largest = (*((double *) ( /* dim=0 */ (__pyx_v_vec.data + __pyx_t_1 * __pyx_v_vec.strides[0]) )));
 020: 
+021:   for i in range(1, vec.shape[0]):   # Find Maximum in vec
  __pyx_t_3 = (__pyx_v_vec.shape[0]);
  __pyx_t_4 = __pyx_t_3;
  for (__pyx_t_5 = 1; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
    __pyx_v_i = __pyx_t_5;
+022:       if (vec[i] > largest):
    __pyx_t_1 = __pyx_v_i;
    __pyx_t_2 = -1;
    if (__pyx_t_1 < 0) {
      __pyx_t_2 = 0;
    } else if (unlikely(__pyx_t_1 >= __pyx_v_vec.shape[0])) __pyx_t_2 = 0;
    if (unlikely(__pyx_t_2 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_2);
      __PYX_ERR(0, 22, __pyx_L1_error)
    }
    __pyx_t_6 = (((*((double *) ( /* dim=0 */ (__pyx_v_vec.data + __pyx_t_1 * __pyx_v_vec.strides[0]) ))) > __pyx_v_largest) != 0);
    if (__pyx_t_6) {
/* … */
    }
  }
+023:           largest = vec[i]
      __pyx_t_1 = __pyx_v_i;
      __pyx_t_2 = -1;
      if (__pyx_t_1 < 0) {
        __pyx_t_2 = 0;
      } else if (unlikely(__pyx_t_1 >= __pyx_v_vec.shape[0])) __pyx_t_2 = 0;
      if (unlikely(__pyx_t_2 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_2);
        __PYX_ERR(0, 23, __pyx_L1_error)
      }
      __pyx_v_largest = (*((double *) ( /* dim=0 */ (__pyx_v_vec.data + __pyx_t_1 * __pyx_v_vec.strides[0]) )));
+024:   for i in range(vec.shape[0]):
  __pyx_t_3 = (__pyx_v_vec.shape[0]);
  __pyx_t_4 = __pyx_t_3;
  for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
    __pyx_v_i = __pyx_t_5;
+025:       result += exp(vec[i] - largest)
    __pyx_t_1 = __pyx_v_i;
    __pyx_t_2 = -1;
    if (__pyx_t_1 < 0) {
      __pyx_t_2 = 0;
    } else if (unlikely(__pyx_t_1 >= __pyx_v_vec.shape[0])) __pyx_t_2 = 0;
    if (unlikely(__pyx_t_2 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_2);
      __PYX_ERR(0, 25, __pyx_L1_error)
    }
    __pyx_v_result = (__pyx_v_result + exp(((*((double *) ( /* dim=0 */ (__pyx_v_vec.data + __pyx_t_1 * __pyx_v_vec.strides[0]) ))) - __pyx_v_largest)));
  }
+026:   return largest + log(result)
  __pyx_r = (__pyx_v_largest + log(__pyx_v_result));
  goto __pyx_L0;
 027: 
+028: cdef inline long argmax(double[:] vec):
static CYTHON_INLINE long __pyx_f_8hapsburg_5cfunc_argmax(__Pyx_memviewslice __pyx_v_vec) {
  int __pyx_v_m;
  double __pyx_v_v;
  Py_ssize_t __pyx_v_k;
  long __pyx_r;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("argmax", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_WriteUnraisable("hapsburg.cfunc.argmax", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
  __pyx_r = 0;
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 029:   """Return Max and ArgMax"""
 030:   cdef Py_ssize_t i  # The iterator Variable.
+031:   cdef int m = 0     # Position of the Maximum.
  __pyx_v_m = 0;
+032:   cdef double v = vec[0]
  __pyx_t_1 = 0;
  __pyx_t_2 = -1;
  if (__pyx_t_1 < 0) {
    __pyx_t_2 = 0;
  } else if (unlikely(__pyx_t_1 >= __pyx_v_vec.shape[0])) __pyx_t_2 = 0;
  if (unlikely(__pyx_t_2 != -1)) {
    __Pyx_RaiseBufferIndexError(__pyx_t_2);
    __PYX_ERR(0, 32, __pyx_L1_error)
  }
  __pyx_v_v = (*((double *) ( /* dim=0 */ (__pyx_v_vec.data + __pyx_t_1 * __pyx_v_vec.strides[0]) )));
 033: 
+034:   for k in range(1, vec.shape[0]):   # Find Maximum
  __pyx_t_3 = (__pyx_v_vec.shape[0]);
  __pyx_t_4 = __pyx_t_3;
  for (__pyx_t_5 = 1; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
    __pyx_v_k = __pyx_t_5;
+035:     if (vec[k] > v):
    __pyx_t_1 = __pyx_v_k;
    __pyx_t_2 = -1;
    if (__pyx_t_1 < 0) {
      __pyx_t_2 = 0;
    } else if (unlikely(__pyx_t_1 >= __pyx_v_vec.shape[0])) __pyx_t_2 = 0;
    if (unlikely(__pyx_t_2 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_2);
      __PYX_ERR(0, 35, __pyx_L1_error)
    }
    __pyx_t_6 = (((*((double *) ( /* dim=0 */ (__pyx_v_vec.data + __pyx_t_1 * __pyx_v_vec.strides[0]) ))) > __pyx_v_v) != 0);
    if (__pyx_t_6) {
/* … */
    }
  }
+036:       m, v = k, vec[k]
      __pyx_t_7 = __pyx_v_k;
      __pyx_t_1 = __pyx_v_k;
      __pyx_t_2 = -1;
      if (__pyx_t_1 < 0) {
        __pyx_t_2 = 0;
      } else if (unlikely(__pyx_t_1 >= __pyx_v_vec.shape[0])) __pyx_t_2 = 0;
      if (unlikely(__pyx_t_2 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_2);
        __PYX_ERR(0, 36, __pyx_L1_error)
      }
      __pyx_t_8 = (*((double *) ( /* dim=0 */ (__pyx_v_vec.data + __pyx_t_1 * __pyx_v_vec.strides[0]) )));
      __pyx_v_m = __pyx_t_7;
      __pyx_v_v = __pyx_t_8;
+037:   return m  # Return Argmax
  __pyx_r = __pyx_v_m;
  goto __pyx_L0;
 038: 
+039: cdef inline double sum_array(double[:] vec, int n):
static CYTHON_INLINE double __pyx_f_8hapsburg_5cfunc_sum_array(__Pyx_memviewslice __pyx_v_vec, int __pyx_v_n) {
  double __pyx_v_s;
  long __pyx_v_i;
  double __pyx_r;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("sum_array", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_WriteUnraisable("hapsburg.cfunc.sum_array", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
  __pyx_r = 0;
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 040:     """Sum over array.
 041:     vec: Array to sum
 042:     n: Number of elements"""
+043:     cdef double s = vec[0]
  __pyx_t_1 = 0;
  __pyx_t_2 = -1;
  if (__pyx_t_1 < 0) {
    __pyx_t_2 = 0;
  } else if (unlikely(__pyx_t_1 >= __pyx_v_vec.shape[0])) __pyx_t_2 = 0;
  if (unlikely(__pyx_t_2 != -1)) {
    __Pyx_RaiseBufferIndexError(__pyx_t_2);
    __PYX_ERR(0, 43, __pyx_L1_error)
  }
  __pyx_v_s = (*((double *) ( /* dim=0 */ (__pyx_v_vec.data + __pyx_t_1 * __pyx_v_vec.strides[0]) )));
+044:     for i in range(1,n):
  __pyx_t_2 = __pyx_v_n;
  __pyx_t_3 = __pyx_t_2;
  for (__pyx_t_4 = 1; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
    __pyx_v_i = __pyx_t_4;
+045:         s = s + vec[i]
    __pyx_t_1 = __pyx_v_i;
    __pyx_t_5 = -1;
    if (__pyx_t_1 < 0) {
      __pyx_t_5 = 0;
    } else if (unlikely(__pyx_t_1 >= __pyx_v_vec.shape[0])) __pyx_t_5 = 0;
    if (unlikely(__pyx_t_5 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_5);
      __PYX_ERR(0, 45, __pyx_L1_error)
    }
    __pyx_v_s = (__pyx_v_s + (*((double *) ( /* dim=0 */ (__pyx_v_vec.data + __pyx_t_1 * __pyx_v_vec.strides[0]) ))));
  }
+046:     return s
  __pyx_r = __pyx_v_s;
  goto __pyx_L0;
 047: 
+048: def print_memory_usage():
/* Python wrapper */
static PyObject *__pyx_pw_8hapsburg_5cfunc_1print_memory_usage(PyObject *__pyx_self, CYTHON_UNUSED PyObject *unused); /*proto*/
static char __pyx_doc_8hapsburg_5cfunc_print_memory_usage[] = "Print the current Memory Usage in mB";
static PyMethodDef __pyx_mdef_8hapsburg_5cfunc_1print_memory_usage = {"print_memory_usage", (PyCFunction)__pyx_pw_8hapsburg_5cfunc_1print_memory_usage, METH_NOARGS, __pyx_doc_8hapsburg_5cfunc_print_memory_usage};
static PyObject *__pyx_pw_8hapsburg_5cfunc_1print_memory_usage(PyObject *__pyx_self, CYTHON_UNUSED PyObject *unused) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("print_memory_usage (wrapper)", 0);
  __pyx_r = __pyx_pf_8hapsburg_5cfunc_print_memory_usage(__pyx_self);

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

static PyObject *__pyx_pf_8hapsburg_5cfunc_print_memory_usage(CYTHON_UNUSED PyObject *__pyx_self) {
  PyObject *__pyx_v_process = NULL;
  PyObject *__pyx_v_mb_usage = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("print_memory_usage", 0);
/* … */
  /* function exit code */
  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  goto __pyx_L0;
  __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_AddTraceback("hapsburg.cfunc.print_memory_usage", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_process);
  __Pyx_XDECREF(__pyx_v_mb_usage);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__28 = PyTuple_Pack(2, __pyx_n_s_process, __pyx_n_s_mb_usage); if (unlikely(!__pyx_tuple__28)) __PYX_ERR(0, 48, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__28);
  __Pyx_GIVEREF(__pyx_tuple__28);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_8hapsburg_5cfunc_1print_memory_usage, NULL, __pyx_n_s_hapsburg_cfunc); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 48, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_print_memory_usage, __pyx_t_2) < 0) __PYX_ERR(0, 48, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__29 = (PyObject*)__Pyx_PyCode_New(0, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__28, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_hapsburg_cfunc_pyx, __pyx_n_s_print_memory_usage, 48, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__29)) __PYX_ERR(0, 48, __pyx_L1_error)
 049:     """Print the current Memory Usage in mB"""
+050:     process = psutil.Process(os.getpid())
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_psutil); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 50, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_Process); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 50, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_os); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 50, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_getpid); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 50, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
    if (likely(__pyx_t_4)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_4);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_5, function);
    }
  }
  __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 50, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3);
    if (likely(__pyx_t_5)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
      __Pyx_INCREF(__pyx_t_5);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_3, function);
    }
  }
  __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_5, __pyx_t_2) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2);
  __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 50, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_v_process = __pyx_t_1;
  __pyx_t_1 = 0;
+051:     mb_usage = process.memory_info().rss / 1e6
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_process, __pyx_n_s_memory_info); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 51, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_2 = NULL;
  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_3))) {
    __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
    if (likely(__pyx_t_2)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
      __Pyx_INCREF(__pyx_t_2);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_3, function);
    }
  }
  __pyx_t_1 = (__pyx_t_2) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 51, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_rss); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 51, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_3, __pyx_float_1e6, 1e6, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 51, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_v_mb_usage = __pyx_t_1;
  __pyx_t_1 = 0;
+052:     print(f"Memory Usage: {mb_usage} mB")
  __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 52, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_6 = 0;
  __pyx_t_7 = 127;
  __Pyx_INCREF(__pyx_kp_u_Memory_Usage);
  __pyx_t_6 += 14;
  __Pyx_GIVEREF(__pyx_kp_u_Memory_Usage);
  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_Memory_Usage);
  __pyx_t_3 = __Pyx_PyObject_FormatSimple(__pyx_v_mb_usage, __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 52, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_3) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_3) : __pyx_t_7;
  __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_3);
  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3);
  __pyx_t_3 = 0;
  __Pyx_INCREF(__pyx_kp_u_mB);
  __pyx_t_6 += 3;
  __Pyx_GIVEREF(__pyx_kp_u_mB);
  PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u_mB);
  __pyx_t_3 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 52, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 52, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 053: 
 054: ##############################################################################
 055: #### The main functions
 056: 
+057: def fwd_bkwd_fast(double[:, :] e_mat, double[:, :, :] t_mat,
/* Python wrapper */
static PyObject *__pyx_pw_8hapsburg_5cfunc_3fwd_bkwd_fast(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_8hapsburg_5cfunc_2fwd_bkwd_fast[] = "Takes emission and transition probabilities, and calculates posteriors.\n    Uses speed-up specific for Genotype data (pooling same transition rates)\n    Input:\n    e_mat: Emission probabilities: [k x l]  (normal space)\n    t_mat: Transition Matrix:  [l x 3 x 3]  (normal space)\n    in_val: Intitial probability of single symmetric state (normal space)\n    full: Boolean whether to return (post, fwd1, bwd1, tot_ll)\n    else only return post\n    output: Whether to print output useful for monitoring.\n    Otherwise only posterior mat [kxl] of post is returned";
static PyMethodDef __pyx_mdef_8hapsburg_5cfunc_3fwd_bkwd_fast = {"fwd_bkwd_fast", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_8hapsburg_5cfunc_3fwd_bkwd_fast, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8hapsburg_5cfunc_2fwd_bkwd_fast};
static PyObject *__pyx_pw_8hapsburg_5cfunc_3fwd_bkwd_fast(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  __Pyx_memviewslice __pyx_v_e_mat = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_t_mat = { 0, 0, { 0 }, { 0 }, { 0 } };
  double __pyx_v_in_val;
  PyObject *__pyx_v_full = 0;
  PyObject *__pyx_v_output = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("fwd_bkwd_fast (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_e_mat,&__pyx_n_s_t_mat,&__pyx_n_s_in_val,&__pyx_n_s_full,&__pyx_n_s_output,0};
    PyObject* values[5] = {0,0,0,0,0};
/* … */
  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_8hapsburg_5cfunc_2fwd_bkwd_fast(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_e_mat, __Pyx_memviewslice __pyx_v_t_mat, double __pyx_v_in_val, PyObject *__pyx_v_full, PyObject *__pyx_v_output) {
  int __pyx_v_n_states;
  int __pyx_v_n_loci;
  Py_ssize_t __pyx_v_i;
  Py_ssize_t __pyx_v_j;
  Py_ssize_t __pyx_v_k;
  double __pyx_v_stay;
  PyObject *__pyx_v_post = NULL;
  PyObject *__pyx_v_trans_ll = NULL;
  __Pyx_memviewslice __pyx_v_trans_ll_view = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_trans_ll1 = NULL;
  __Pyx_memviewslice __pyx_v_trans_ll_view1 = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_three_v = NULL;
  __Pyx_memviewslice __pyx_v_three_v_view = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_two_v = NULL;
  __Pyx_memviewslice __pyx_v_two_v_view = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_t0 = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_e_mat0 = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_fwd0 = NULL;
  __Pyx_memviewslice __pyx_v_fwd = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_bwd0 = NULL;
  __Pyx_memviewslice __pyx_v_bwd = { 0, 0, { 0 }, { 0 }, { 0 } };
  double __pyx_v_f_l;
  double __pyx_v_tot_ll;
  PyObject *__pyx_v_fwd1 = NULL;
  PyObject *__pyx_v_bwd1 = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("fwd_bkwd_fast", 0);
/* … */
  /* function exit code */
  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  goto __pyx_L0;
  __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_XDEC_MEMVIEW(&__pyx_t_6, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_t_7, 1);
  __Pyx_XDECREF(__pyx_t_23);
  __Pyx_AddTraceback("hapsburg.cfunc.fwd_bkwd_fast", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_post);
  __Pyx_XDECREF(__pyx_v_trans_ll);
  __PYX_XDEC_MEMVIEW(&__pyx_v_trans_ll_view, 1);
  __Pyx_XDECREF(__pyx_v_trans_ll1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_trans_ll_view1, 1);
  __Pyx_XDECREF(__pyx_v_three_v);
  __PYX_XDEC_MEMVIEW(&__pyx_v_three_v_view, 1);
  __Pyx_XDECREF(__pyx_v_two_v);
  __PYX_XDEC_MEMVIEW(&__pyx_v_two_v_view, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_t0, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_e_mat0, 1);
  __Pyx_XDECREF(__pyx_v_fwd0);
  __PYX_XDEC_MEMVIEW(&__pyx_v_fwd, 1);
  __Pyx_XDECREF(__pyx_v_bwd0);
  __PYX_XDEC_MEMVIEW(&__pyx_v_bwd, 1);
  __Pyx_XDECREF(__pyx_v_fwd1);
  __Pyx_XDECREF(__pyx_v_bwd1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_e_mat, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_t_mat, 1);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__30 = PyTuple_Pack(30, __pyx_n_s_e_mat, __pyx_n_s_t_mat, __pyx_n_s_in_val, __pyx_n_s_full, __pyx_n_s_output, __pyx_n_s_n_states, __pyx_n_s_n_loci, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_k, __pyx_n_s_stay, __pyx_n_s_post, __pyx_n_s_trans_ll, __pyx_n_s_trans_ll_view, __pyx_n_s_trans_ll1, __pyx_n_s_trans_ll_view1, __pyx_n_s_three_v, __pyx_n_s_three_v_view, __pyx_n_s_two_v, __pyx_n_s_two_v_view, __pyx_n_s_t0, __pyx_n_s_e_mat0, __pyx_n_s_fwd0, __pyx_n_s_fwd, __pyx_n_s_bwd0, __pyx_n_s_bwd, __pyx_n_s_f_l, __pyx_n_s_tot_ll, __pyx_n_s_fwd1, __pyx_n_s_bwd1); if (unlikely(!__pyx_tuple__30)) __PYX_ERR(0, 57, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__30);
  __Pyx_GIVEREF(__pyx_tuple__30);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_8hapsburg_5cfunc_3fwd_bkwd_fast, NULL, __pyx_n_s_hapsburg_cfunc); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_fwd_bkwd_fast, __pyx_t_2) < 0) __PYX_ERR(0, 57, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__31 = (PyObject*)__Pyx_PyCode_New(5, 0, 30, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__30, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_hapsburg_cfunc_pyx, __pyx_n_s_fwd_bkwd_fast, 57, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__31)) __PYX_ERR(0, 57, __pyx_L1_error)
+058:                   double in_val = 1e-4, full=False, output=True):
    values[3] = ((PyObject *)Py_False);
    values[4] = ((PyObject *)Py_True);
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        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_e_mat)) != 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_t_mat)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("fwd_bkwd_fast", 0, 2, 5, 1); __PYX_ERR(0, 57, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_in_val);
          if (value) { values[2] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_full);
          if (value) { values[3] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  4:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_output);
          if (value) { values[4] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "fwd_bkwd_fast") < 0)) __PYX_ERR(0, 57, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        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);
        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_e_mat = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(values[0], PyBUF_WRITABLE); if (unlikely(!__pyx_v_e_mat.memview)) __PYX_ERR(0, 57, __pyx_L3_error)
    __pyx_v_t_mat = __Pyx_PyObject_to_MemoryviewSlice_dsdsds_double(values[1], PyBUF_WRITABLE); if (unlikely(!__pyx_v_t_mat.memview)) __PYX_ERR(0, 57, __pyx_L3_error)
    if (values[2]) {
      __pyx_v_in_val = __pyx_PyFloat_AsDouble(values[2]); if (unlikely((__pyx_v_in_val == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 58, __pyx_L3_error)
    } else {
      __pyx_v_in_val = ((double)1e-4);
    }
    __pyx_v_full = values[3];
    __pyx_v_output = values[4];
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("fwd_bkwd_fast", 0, 2, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 57, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("hapsburg.cfunc.fwd_bkwd_fast", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_8hapsburg_5cfunc_2fwd_bkwd_fast(__pyx_self, __pyx_v_e_mat, __pyx_v_t_mat, __pyx_v_in_val, __pyx_v_full, __pyx_v_output);
 059:     """Takes emission and transition probabilities, and calculates posteriors.
 060:     Uses speed-up specific for Genotype data (pooling same transition rates)
 061:     Input:
 062:     e_mat: Emission probabilities: [k x l]  (normal space)
 063:     t_mat: Transition Matrix:  [l x 3 x 3]  (normal space)
 064:     in_val: Intitial probability of single symmetric state (normal space)
 065:     full: Boolean whether to return (post, fwd1, bwd1, tot_ll)
 066:     else only return post
 067:     output: Whether to print output useful for monitoring.
 068:     Otherwise only posterior mat [kxl] of post is returned"""
+069:     cdef int n_states = e_mat.shape[0]
  __pyx_v_n_states = (__pyx_v_e_mat.shape[0]);
+070:     cdef int n_loci = e_mat.shape[1]
  __pyx_v_n_loci = (__pyx_v_e_mat.shape[1]);
 071:     cdef Py_ssize_t i, j, k    # The Array Indices
 072:     cdef double stay           # The Probablility of Staying
 073: 
 074:     # Initialize Posterior and Transition Probabilities
+075:     post = np.empty([n_states, n_loci], dtype=DTYPE)
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 75, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 75, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_n_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 75, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_n_loci); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 75, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = PyList_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 75, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_1);
  PyList_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
  __Pyx_GIVEREF(__pyx_t_3);
  PyList_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
  __pyx_t_1 = 0;
  __pyx_t_3 = 0;
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 75, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
  __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 75, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 75, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_1) < 0) __PYX_ERR(0, 75, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 75, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_v_post = __pyx_t_1;
  __pyx_t_1 = 0;
 076: 
+077:     trans_ll = np.empty(n_states-1, dtype=DTYPE) # Array for pre-calculations
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 77, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 77, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_long((__pyx_v_n_states - 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 77, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 77, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
  __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 77, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 77, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_2) < 0) __PYX_ERR(0, 77, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 77, __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_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_trans_ll = __pyx_t_2;
  __pyx_t_2 = 0;
+078:     cdef double[:] trans_ll_view = trans_ll
  __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_trans_ll, PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 78, __pyx_L1_error)
  __pyx_v_trans_ll_view = __pyx_t_5;
  __pyx_t_5.memview = NULL;
  __pyx_t_5.data = NULL;
 079: 
+080:     trans_ll1 = np.empty(n_states, dtype=DTYPE) # Array for calculations
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 80, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 80, __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_n_states); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 80, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 80, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_2);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
  __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 80, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 80, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_4) < 0) __PYX_ERR(0, 80, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 80, __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_trans_ll1 = __pyx_t_4;
  __pyx_t_4 = 0;
+081:     cdef double[:] trans_ll_view1 = trans_ll1
  __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_trans_ll1, PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 81, __pyx_L1_error)
  __pyx_v_trans_ll_view1 = __pyx_t_5;
  __pyx_t_5.memview = NULL;
  __pyx_t_5.data = NULL;
 082: 
+083:     three_v = np.empty(3, dtype=DTYPE)     # Array of size three
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 83, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 83, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 83, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 83, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_3) < 0) __PYX_ERR(0, 83, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple_, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 83, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_v_three_v = __pyx_t_3;
  __pyx_t_3 = 0;
/* … */
  __pyx_tuple_ = PyTuple_Pack(1, __pyx_int_3); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 83, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple_);
  __Pyx_GIVEREF(__pyx_tuple_);
+084:     cdef double[:] three_v_view = three_v
  __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_three_v, PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 84, __pyx_L1_error)
  __pyx_v_three_v_view = __pyx_t_5;
  __pyx_t_5.memview = NULL;
  __pyx_t_5.data = NULL;
 085: 
+086:     two_v = np.empty(2, dtype=DTYPE)       # Array of size two
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 86, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_empty); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 86, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 86, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 86, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_2) < 0) __PYX_ERR(0, 86, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_tuple__2, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 86, __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_v_two_v = __pyx_t_2;
  __pyx_t_2 = 0;
/* … */
  __pyx_tuple__2 = PyTuple_Pack(1, __pyx_int_2); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(0, 86, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__2);
  __Pyx_GIVEREF(__pyx_tuple__2);
+087:     cdef double[:] two_v_view = two_v
  __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_two_v, PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 87, __pyx_L1_error)
  __pyx_v_two_v_view = __pyx_t_5;
  __pyx_t_5.memview = NULL;
  __pyx_t_5.data = NULL;
 088: 
 089:     # Do transform to Log Space:
+090:     cdef double[:,:,:] t0 = np.log(t_mat)         # Do logs
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 90, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_log); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 90, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_t_mat, 3, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 90, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_1 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
    __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_4);
    if (likely(__pyx_t_1)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_4, function);
    }
  }
  __pyx_t_2 = (__pyx_t_1) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_1, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
  __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 90, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_dsdsds_double(__pyx_t_2, PyBUF_WRITABLE); if (unlikely(!__pyx_t_6.memview)) __PYX_ERR(0, 90, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_t0 = __pyx_t_6;
  __pyx_t_6.memview = NULL;
  __pyx_t_6.data = NULL;
+091:     cdef double[:, :] e_mat0 = np.log(e_mat)
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 91, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_log); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 91, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __pyx_memoryview_fromslice(__pyx_v_e_mat, 2, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 91, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_1 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
    __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_3);
    if (likely(__pyx_t_1)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_3, function);
    }
  }
  __pyx_t_2 = (__pyx_t_1) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_1, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4);
  __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 91, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(__pyx_t_2, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 91, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_e_mat0 = __pyx_t_7;
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
 092: 
 093:     ### Initialize FWD BWD matrices
+094:     fwd0 = np.zeros((n_states, n_loci), dtype="float")
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 94, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_zeros); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 94, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_n_states); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 94, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_n_loci); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 94, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 94, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_GIVEREF(__pyx_t_2);
  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_4);
  __pyx_t_2 = 0;
  __pyx_t_4 = 0;
  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 94, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
  __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 94, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_n_u_float) < 0) __PYX_ERR(0, 94, __pyx_L1_error)
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 94, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_fwd0 = __pyx_t_2;
  __pyx_t_2 = 0;
+095:     fwd0[:, 0] = np.log(in_val)  # Initial Probabilities
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 95, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_log); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 95, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = PyFloat_FromDouble(__pyx_v_in_val); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 95, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_4);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_4, function);
    }
  }
  __pyx_t_2 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_3, __pyx_t_1) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_1);
  __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 95, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
/* … */
  __pyx_slice__3 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__3)) __PYX_ERR(0, 95, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_slice__3);
  __Pyx_GIVEREF(__pyx_slice__3);
  if (unlikely(PyObject_SetItem(__pyx_v_fwd0, __pyx_tuple__4, __pyx_t_2) < 0)) __PYX_ERR(0, 95, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_tuple__4 = PyTuple_Pack(2, __pyx_slice__3, __pyx_int_0); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(0, 95, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__4);
  __Pyx_GIVEREF(__pyx_tuple__4);
+096:     fwd0[0, 0] = np.log(1 - (n_states - 1) * in_val)
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 96, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_log); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 96, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = PyFloat_FromDouble((1.0 - ((__pyx_v_n_states - 1) * __pyx_v_in_val))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 96, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_3 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_1))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_1, function);
    }
  }
  __pyx_t_2 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_4);
  __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 96, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (unlikely(PyObject_SetItem(__pyx_v_fwd0, __pyx_tuple__5, __pyx_t_2) < 0)) __PYX_ERR(0, 96, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
/* … */
  __pyx_tuple__5 = PyTuple_Pack(2, __pyx_int_0, __pyx_int_0); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(0, 96, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__5);
  __Pyx_GIVEREF(__pyx_tuple__5);
+097:     cdef double[:,:] fwd = fwd0
  __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(__pyx_v_fwd0, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 97, __pyx_L1_error)
  __pyx_v_fwd = __pyx_t_7;
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
 098: 
+099:     bwd0 = np.zeros((n_states, n_loci), dtype="float")
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 99, __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, 99, __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_n_states); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 99, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_n_loci); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 99, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 99, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_2);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_4);
  __pyx_t_2 = 0;
  __pyx_t_4 = 0;
  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 99, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_3);
  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
  __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 99, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_n_u_float) < 0) __PYX_ERR(0, 99, __pyx_L1_error)
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 99, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_v_bwd0 = __pyx_t_2;
  __pyx_t_2 = 0;
+100:     bwd0[:, -1] = np.log(in_val)
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 100, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_log); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 100, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = PyFloat_FromDouble(__pyx_v_in_val); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 100, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_1 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
    __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_4);
    if (likely(__pyx_t_1)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_4, function);
    }
  }
  __pyx_t_2 = (__pyx_t_1) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_1, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
  __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 100, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (unlikely(PyObject_SetItem(__pyx_v_bwd0, __pyx_tuple__6, __pyx_t_2) < 0)) __PYX_ERR(0, 100, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
/* … */
  __pyx_tuple__6 = PyTuple_Pack(2, __pyx_slice__3, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(0, 100, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__6);
  __Pyx_GIVEREF(__pyx_tuple__6);
+101:     bwd0[0, -1] = np.log(1 - (n_states - 1) * in_val)
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 101, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_log); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 101, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = PyFloat_FromDouble((1.0 - ((__pyx_v_n_states - 1) * __pyx_v_in_val))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 101, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_1 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
    __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_3);
    if (likely(__pyx_t_1)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_3, function);
    }
  }
  __pyx_t_2 = (__pyx_t_1) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_1, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4);
  __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 101, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  if (unlikely(PyObject_SetItem(__pyx_v_bwd0, __pyx_tuple__7, __pyx_t_2) < 0)) __PYX_ERR(0, 101, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
/* … */
  __pyx_tuple__7 = PyTuple_Pack(2, __pyx_int_0, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(0, 101, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__7);
  __Pyx_GIVEREF(__pyx_tuple__7);
+102:     cdef double[:,:] bwd = bwd0
  __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(__pyx_v_bwd0, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 102, __pyx_L1_error)
  __pyx_v_bwd = __pyx_t_7;
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
 103: 
 104:     #############################
 105:     ### Do the Forward Algorithm
+106:     for i in range(1, n_loci):  # Run forward recursion
  __pyx_t_8 = __pyx_v_n_loci;
  __pyx_t_9 = __pyx_t_8;
  for (__pyx_t_10 = 1; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
    __pyx_v_i = __pyx_t_10;
+107:         stay = log(t_mat[i, 1, 1] - t_mat[i, 1, 2])  # Do the log of the Stay term
    __pyx_t_11 = __pyx_v_i;
    __pyx_t_12 = 1;
    __pyx_t_13 = 1;
    __pyx_t_14 = -1;
    if (__pyx_t_11 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_t_mat.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_12 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_t_mat.shape[1])) __pyx_t_14 = 1;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 2;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_t_mat.shape[2])) __pyx_t_14 = 2;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 107, __pyx_L1_error)
    }
    __pyx_t_15 = __pyx_v_i;
    __pyx_t_16 = 1;
    __pyx_t_17 = 2;
    __pyx_t_14 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t_mat.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_16 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t_mat.shape[1])) __pyx_t_14 = 1;
    if (__pyx_t_17 < 0) {
      __pyx_t_14 = 2;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_t_mat.shape[2])) __pyx_t_14 = 2;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 107, __pyx_L1_error)
    }
    __pyx_v_stay = log(((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t_mat.data + __pyx_t_11 * __pyx_v_t_mat.strides[0]) ) + __pyx_t_12 * __pyx_v_t_mat.strides[1]) ) + __pyx_t_13 * __pyx_v_t_mat.strides[2]) ))) - (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t_mat.data + __pyx_t_15 * __pyx_v_t_mat.strides[0]) ) + __pyx_t_16 * __pyx_v_t_mat.strides[1]) ) + __pyx_t_17 * __pyx_v_t_mat.strides[2]) )))));
 108: 
+109:         for k in range(1, n_states): # Calculate logsum of ROH states:
    __pyx_t_14 = __pyx_v_n_states;
    __pyx_t_18 = __pyx_t_14;
    for (__pyx_t_19 = 1; __pyx_t_19 < __pyx_t_18; __pyx_t_19+=1) {
      __pyx_v_k = __pyx_t_19;
+110:             trans_ll_view[k-1] = fwd[k, i - 1]
      __pyx_t_17 = __pyx_v_k;
      __pyx_t_16 = (__pyx_v_i - 1);
      __pyx_t_20 = -1;
      if (__pyx_t_17 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_17 >= __pyx_v_fwd.shape[0])) __pyx_t_20 = 0;
      if (__pyx_t_16 < 0) {
        __pyx_t_20 = 1;
      } else if (unlikely(__pyx_t_16 >= __pyx_v_fwd.shape[1])) __pyx_t_20 = 1;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 110, __pyx_L1_error)
      }
      __pyx_t_15 = (__pyx_v_k - 1);
      __pyx_t_20 = -1;
      if (__pyx_t_15 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_15 >= __pyx_v_trans_ll_view.shape[0])) __pyx_t_20 = 0;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 110, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_trans_ll_view.data + __pyx_t_15 * __pyx_v_trans_ll_view.strides[0]) )) = (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_17 * __pyx_v_fwd.strides[0]) ) + __pyx_t_16 * __pyx_v_fwd.strides[1]) )));
    }
+111:         f_l = logsumexp(trans_ll_view) # Logsum of ROH States
    __pyx_v_f_l = __pyx_f_8hapsburg_5cfunc_logsumexp(__pyx_v_trans_ll_view);
 112: 
 113:         # Do the 0 State:
+114:         two_v_view[0] = fwd[0, i - 1] + t0[i, 0, 0]   # Staying in 0 State
    __pyx_t_16 = 0;
    __pyx_t_17 = (__pyx_v_i - 1);
    __pyx_t_14 = -1;
    if (__pyx_t_16 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_fwd.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_17 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_fwd.shape[1])) __pyx_t_14 = 1;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 114, __pyx_L1_error)
    }
    __pyx_t_15 = __pyx_v_i;
    __pyx_t_13 = 0;
    __pyx_t_12 = 0;
    __pyx_t_14 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t0.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_t0.shape[1])) __pyx_t_14 = 1;
    if (__pyx_t_12 < 0) {
      __pyx_t_14 = 2;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_t0.shape[2])) __pyx_t_14 = 2;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 114, __pyx_L1_error)
    }
    __pyx_t_11 = 0;
    __pyx_t_14 = -1;
    if (__pyx_t_11 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_two_v_view.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 114, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_two_v_view.data + __pyx_t_11 * __pyx_v_two_v_view.strides[0]) )) = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_16 * __pyx_v_fwd.strides[0]) ) + __pyx_t_17 * __pyx_v_fwd.strides[1]) ))) + (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t0.data + __pyx_t_15 * __pyx_v_t0.strides[0]) ) + __pyx_t_13 * __pyx_v_t0.strides[1]) ) + __pyx_t_12 * __pyx_v_t0.strides[2]) ))));
+115:         two_v_view[1] = f_l + t0[i, 1, 0]             # Going into 0 State
    __pyx_t_12 = __pyx_v_i;
    __pyx_t_13 = 1;
    __pyx_t_15 = 0;
    __pyx_t_14 = -1;
    if (__pyx_t_12 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_t0.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_t0.shape[1])) __pyx_t_14 = 1;
    if (__pyx_t_15 < 0) {
      __pyx_t_14 = 2;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t0.shape[2])) __pyx_t_14 = 2;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 115, __pyx_L1_error)
    }
    __pyx_t_17 = 1;
    __pyx_t_14 = -1;
    if (__pyx_t_17 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_two_v_view.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 115, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_two_v_view.data + __pyx_t_17 * __pyx_v_two_v_view.strides[0]) )) = (__pyx_v_f_l + (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t0.data + __pyx_t_12 * __pyx_v_t0.strides[0]) ) + __pyx_t_13 * __pyx_v_t0.strides[1]) ) + __pyx_t_15 * __pyx_v_t0.strides[2]) ))));
+116:         fwd[0, i] = e_mat0[0, i] + logsumexp(two_v_view)
    __pyx_t_15 = 0;
    __pyx_t_13 = __pyx_v_i;
    __pyx_t_14 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_e_mat0.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_e_mat0.shape[1])) __pyx_t_14 = 1;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 116, __pyx_L1_error)
    }
    __pyx_t_12 = 0;
    __pyx_t_17 = __pyx_v_i;
    __pyx_t_14 = -1;
    if (__pyx_t_12 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_fwd.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_17 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_fwd.shape[1])) __pyx_t_14 = 1;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 116, __pyx_L1_error)
    }
    *((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_12 * __pyx_v_fwd.strides[0]) ) + __pyx_t_17 * __pyx_v_fwd.strides[1]) )) = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat0.data + __pyx_t_15 * __pyx_v_e_mat0.strides[0]) ) + __pyx_t_13 * __pyx_v_e_mat0.strides[1]) ))) + __pyx_f_8hapsburg_5cfunc_logsumexp(__pyx_v_two_v_view));
 117: 
 118:         ### Do the other states
 119:         # Preprocessing:
+120:         three_v_view[0] = fwd[0, i - 1] + t0[i, 0, 1]   # Coming from 0 State
    __pyx_t_13 = 0;
    __pyx_t_15 = (__pyx_v_i - 1);
    __pyx_t_14 = -1;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_fwd.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_15 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_fwd.shape[1])) __pyx_t_14 = 1;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 120, __pyx_L1_error)
    }
    __pyx_t_17 = __pyx_v_i;
    __pyx_t_12 = 0;
    __pyx_t_16 = 1;
    __pyx_t_14 = -1;
    if (__pyx_t_17 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_t0.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_12 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_t0.shape[1])) __pyx_t_14 = 1;
    if (__pyx_t_16 < 0) {
      __pyx_t_14 = 2;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t0.shape[2])) __pyx_t_14 = 2;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 120, __pyx_L1_error)
    }
    __pyx_t_11 = 0;
    __pyx_t_14 = -1;
    if (__pyx_t_11 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_three_v_view.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 120, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_three_v_view.data + __pyx_t_11 * __pyx_v_three_v_view.strides[0]) )) = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_13 * __pyx_v_fwd.strides[0]) ) + __pyx_t_15 * __pyx_v_fwd.strides[1]) ))) + (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t0.data + __pyx_t_17 * __pyx_v_t0.strides[0]) ) + __pyx_t_12 * __pyx_v_t0.strides[1]) ) + __pyx_t_16 * __pyx_v_t0.strides[2]) ))));
+121:         three_v_view[1] = f_l + t0[i, 1, 2]             # Coming from other ROH State
    __pyx_t_16 = __pyx_v_i;
    __pyx_t_12 = 1;
    __pyx_t_17 = 2;
    __pyx_t_14 = -1;
    if (__pyx_t_16 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t0.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_12 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_t0.shape[1])) __pyx_t_14 = 1;
    if (__pyx_t_17 < 0) {
      __pyx_t_14 = 2;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_t0.shape[2])) __pyx_t_14 = 2;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 121, __pyx_L1_error)
    }
    __pyx_t_15 = 1;
    __pyx_t_14 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_three_v_view.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 121, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_three_v_view.data + __pyx_t_15 * __pyx_v_three_v_view.strides[0]) )) = (__pyx_v_f_l + (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t0.data + __pyx_t_16 * __pyx_v_t0.strides[0]) ) + __pyx_t_12 * __pyx_v_t0.strides[1]) ) + __pyx_t_17 * __pyx_v_t0.strides[2]) ))));
 122: 
+123:         for j in range(1, n_states):  # Do the final run over all states
    __pyx_t_14 = __pyx_v_n_states;
    __pyx_t_18 = __pyx_t_14;
    for (__pyx_t_19 = 1; __pyx_t_19 < __pyx_t_18; __pyx_t_19+=1) {
      __pyx_v_j = __pyx_t_19;
+124:           three_v_view[2] = fwd[j, i-1] +  stay
      __pyx_t_17 = __pyx_v_j;
      __pyx_t_12 = (__pyx_v_i - 1);
      __pyx_t_20 = -1;
      if (__pyx_t_17 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_17 >= __pyx_v_fwd.shape[0])) __pyx_t_20 = 0;
      if (__pyx_t_12 < 0) {
        __pyx_t_20 = 1;
      } else if (unlikely(__pyx_t_12 >= __pyx_v_fwd.shape[1])) __pyx_t_20 = 1;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 124, __pyx_L1_error)
      }
      __pyx_t_16 = 2;
      __pyx_t_20 = -1;
      if (__pyx_t_16 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_16 >= __pyx_v_three_v_view.shape[0])) __pyx_t_20 = 0;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 124, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_three_v_view.data + __pyx_t_16 * __pyx_v_three_v_view.strides[0]) )) = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_17 * __pyx_v_fwd.strides[0]) ) + __pyx_t_12 * __pyx_v_fwd.strides[1]) ))) + __pyx_v_stay);
+125:           fwd[j, i] = e_mat0[j, i] + logsumexp(three_v_view)
      __pyx_t_12 = __pyx_v_j;
      __pyx_t_17 = __pyx_v_i;
      __pyx_t_20 = -1;
      if (__pyx_t_12 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_12 >= __pyx_v_e_mat0.shape[0])) __pyx_t_20 = 0;
      if (__pyx_t_17 < 0) {
        __pyx_t_20 = 1;
      } else if (unlikely(__pyx_t_17 >= __pyx_v_e_mat0.shape[1])) __pyx_t_20 = 1;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 125, __pyx_L1_error)
      }
      __pyx_t_16 = __pyx_v_j;
      __pyx_t_15 = __pyx_v_i;
      __pyx_t_20 = -1;
      if (__pyx_t_16 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_16 >= __pyx_v_fwd.shape[0])) __pyx_t_20 = 0;
      if (__pyx_t_15 < 0) {
        __pyx_t_20 = 1;
      } else if (unlikely(__pyx_t_15 >= __pyx_v_fwd.shape[1])) __pyx_t_20 = 1;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 125, __pyx_L1_error)
      }
      *((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_16 * __pyx_v_fwd.strides[0]) ) + __pyx_t_15 * __pyx_v_fwd.strides[1]) )) = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat0.data + __pyx_t_12 * __pyx_v_e_mat0.strides[0]) ) + __pyx_t_17 * __pyx_v_e_mat0.strides[1]) ))) + __pyx_f_8hapsburg_5cfunc_logsumexp(__pyx_v_three_v_view));
    }
  }
 126: 
 127:     #############################
 128:     ### Do the Backward Algorithm
+129:     for i in range(n_loci-1, 0, -1):  # Run backward recursion
  for (__pyx_t_10 = (__pyx_v_n_loci - 1); __pyx_t_10 > 0; __pyx_t_10-=1) {
    __pyx_v_i = __pyx_t_10;
+130:       stay = log(t_mat[i, 1, 1] - t_mat[i, 1, 2])
    __pyx_t_17 = __pyx_v_i;
    __pyx_t_12 = 1;
    __pyx_t_15 = 1;
    __pyx_t_8 = -1;
    if (__pyx_t_17 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_t_mat.shape[0])) __pyx_t_8 = 0;
    if (__pyx_t_12 < 0) {
      __pyx_t_8 = 1;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_t_mat.shape[1])) __pyx_t_8 = 1;
    if (__pyx_t_15 < 0) {
      __pyx_t_8 = 2;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t_mat.shape[2])) __pyx_t_8 = 2;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 130, __pyx_L1_error)
    }
    __pyx_t_16 = __pyx_v_i;
    __pyx_t_13 = 1;
    __pyx_t_11 = 2;
    __pyx_t_8 = -1;
    if (__pyx_t_16 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t_mat.shape[0])) __pyx_t_8 = 0;
    if (__pyx_t_13 < 0) {
      __pyx_t_8 = 1;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_t_mat.shape[1])) __pyx_t_8 = 1;
    if (__pyx_t_11 < 0) {
      __pyx_t_8 = 2;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_t_mat.shape[2])) __pyx_t_8 = 2;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 130, __pyx_L1_error)
    }
    __pyx_v_stay = log(((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t_mat.data + __pyx_t_17 * __pyx_v_t_mat.strides[0]) ) + __pyx_t_12 * __pyx_v_t_mat.strides[1]) ) + __pyx_t_15 * __pyx_v_t_mat.strides[2]) ))) - (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t_mat.data + __pyx_t_16 * __pyx_v_t_mat.strides[0]) ) + __pyx_t_13 * __pyx_v_t_mat.strides[1]) ) + __pyx_t_11 * __pyx_v_t_mat.strides[2]) )))));
 131: 
+132:       for k in range(1, n_states): # Calculate logsum of ROH states:
    __pyx_t_8 = __pyx_v_n_states;
    __pyx_t_9 = __pyx_t_8;
    for (__pyx_t_19 = 1; __pyx_t_19 < __pyx_t_9; __pyx_t_19+=1) {
      __pyx_v_k = __pyx_t_19;
+133:           trans_ll_view[k-1] = bwd[k, i] + e_mat0[k, i]
      __pyx_t_11 = __pyx_v_k;
      __pyx_t_13 = __pyx_v_i;
      __pyx_t_14 = -1;
      if (__pyx_t_11 < 0) {
        __pyx_t_14 = 0;
      } else if (unlikely(__pyx_t_11 >= __pyx_v_bwd.shape[0])) __pyx_t_14 = 0;
      if (__pyx_t_13 < 0) {
        __pyx_t_14 = 1;
      } else if (unlikely(__pyx_t_13 >= __pyx_v_bwd.shape[1])) __pyx_t_14 = 1;
      if (unlikely(__pyx_t_14 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_14);
        __PYX_ERR(0, 133, __pyx_L1_error)
      }
      __pyx_t_16 = __pyx_v_k;
      __pyx_t_15 = __pyx_v_i;
      __pyx_t_14 = -1;
      if (__pyx_t_16 < 0) {
        __pyx_t_14 = 0;
      } else if (unlikely(__pyx_t_16 >= __pyx_v_e_mat0.shape[0])) __pyx_t_14 = 0;
      if (__pyx_t_15 < 0) {
        __pyx_t_14 = 1;
      } else if (unlikely(__pyx_t_15 >= __pyx_v_e_mat0.shape[1])) __pyx_t_14 = 1;
      if (unlikely(__pyx_t_14 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_14);
        __PYX_ERR(0, 133, __pyx_L1_error)
      }
      __pyx_t_12 = (__pyx_v_k - 1);
      __pyx_t_14 = -1;
      if (__pyx_t_12 < 0) {
        __pyx_t_14 = 0;
      } else if (unlikely(__pyx_t_12 >= __pyx_v_trans_ll_view.shape[0])) __pyx_t_14 = 0;
      if (unlikely(__pyx_t_14 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_14);
        __PYX_ERR(0, 133, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_trans_ll_view.data + __pyx_t_12 * __pyx_v_trans_ll_view.strides[0]) )) = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_11 * __pyx_v_bwd.strides[0]) ) + __pyx_t_13 * __pyx_v_bwd.strides[1]) ))) + (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat0.data + __pyx_t_16 * __pyx_v_e_mat0.strides[0]) ) + __pyx_t_15 * __pyx_v_e_mat0.strides[1]) ))));
    }
+134:       f_l = logsumexp(trans_ll_view) # Logsum of ROH States
    __pyx_v_f_l = __pyx_f_8hapsburg_5cfunc_logsumexp(__pyx_v_trans_ll_view);
 135: 
 136:       # Do the 0 State:
+137:       two_v_view[0] = bwd[0, i] + t0[i, 0, 0] + e_mat0[0, i]   # Staying in 0 State
    __pyx_t_15 = 0;
    __pyx_t_16 = __pyx_v_i;
    __pyx_t_8 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_bwd.shape[0])) __pyx_t_8 = 0;
    if (__pyx_t_16 < 0) {
      __pyx_t_8 = 1;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_bwd.shape[1])) __pyx_t_8 = 1;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 137, __pyx_L1_error)
    }
    __pyx_t_13 = __pyx_v_i;
    __pyx_t_11 = 0;
    __pyx_t_12 = 0;
    __pyx_t_8 = -1;
    if (__pyx_t_13 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_t0.shape[0])) __pyx_t_8 = 0;
    if (__pyx_t_11 < 0) {
      __pyx_t_8 = 1;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_t0.shape[1])) __pyx_t_8 = 1;
    if (__pyx_t_12 < 0) {
      __pyx_t_8 = 2;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_t0.shape[2])) __pyx_t_8 = 2;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 137, __pyx_L1_error)
    }
    __pyx_t_17 = 0;
    __pyx_t_21 = __pyx_v_i;
    __pyx_t_8 = -1;
    if (__pyx_t_17 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_e_mat0.shape[0])) __pyx_t_8 = 0;
    if (__pyx_t_21 < 0) {
      __pyx_t_8 = 1;
    } else if (unlikely(__pyx_t_21 >= __pyx_v_e_mat0.shape[1])) __pyx_t_8 = 1;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 137, __pyx_L1_error)
    }
    __pyx_t_22 = 0;
    __pyx_t_8 = -1;
    if (__pyx_t_22 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_22 >= __pyx_v_two_v_view.shape[0])) __pyx_t_8 = 0;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 137, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_two_v_view.data + __pyx_t_22 * __pyx_v_two_v_view.strides[0]) )) = (((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_15 * __pyx_v_bwd.strides[0]) ) + __pyx_t_16 * __pyx_v_bwd.strides[1]) ))) + (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t0.data + __pyx_t_13 * __pyx_v_t0.strides[0]) ) + __pyx_t_11 * __pyx_v_t0.strides[1]) ) + __pyx_t_12 * __pyx_v_t0.strides[2]) )))) + (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat0.data + __pyx_t_17 * __pyx_v_e_mat0.strides[0]) ) + __pyx_t_21 * __pyx_v_e_mat0.strides[1]) ))));
+138:       two_v_view[1] = f_l + t0[i, 0, 1]                         # Going into 0 State
    __pyx_t_21 = __pyx_v_i;
    __pyx_t_17 = 0;
    __pyx_t_12 = 1;
    __pyx_t_8 = -1;
    if (__pyx_t_21 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_21 >= __pyx_v_t0.shape[0])) __pyx_t_8 = 0;
    if (__pyx_t_17 < 0) {
      __pyx_t_8 = 1;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_t0.shape[1])) __pyx_t_8 = 1;
    if (__pyx_t_12 < 0) {
      __pyx_t_8 = 2;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_t0.shape[2])) __pyx_t_8 = 2;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 138, __pyx_L1_error)
    }
    __pyx_t_11 = 1;
    __pyx_t_8 = -1;
    if (__pyx_t_11 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_two_v_view.shape[0])) __pyx_t_8 = 0;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 138, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_two_v_view.data + __pyx_t_11 * __pyx_v_two_v_view.strides[0]) )) = (__pyx_v_f_l + (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t0.data + __pyx_t_21 * __pyx_v_t0.strides[0]) ) + __pyx_t_17 * __pyx_v_t0.strides[1]) ) + __pyx_t_12 * __pyx_v_t0.strides[2]) ))));
+139:       bwd[0, i - 1] = logsumexp(two_v_view)
    __pyx_t_12 = 0;
    __pyx_t_17 = (__pyx_v_i - 1);
    __pyx_t_8 = -1;
    if (__pyx_t_12 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_bwd.shape[0])) __pyx_t_8 = 0;
    if (__pyx_t_17 < 0) {
      __pyx_t_8 = 1;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_bwd.shape[1])) __pyx_t_8 = 1;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 139, __pyx_L1_error)
    }
    *((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_12 * __pyx_v_bwd.strides[0]) ) + __pyx_t_17 * __pyx_v_bwd.strides[1]) )) = __pyx_f_8hapsburg_5cfunc_logsumexp(__pyx_v_two_v_view);
 140: 
 141:       ### Do the other states
 142:       # Preprocessing:
+143:       three_v_view[0] = e_mat0[0, i] + bwd[0, i] + t0[i, 1, 0]
    __pyx_t_17 = 0;
    __pyx_t_12 = __pyx_v_i;
    __pyx_t_8 = -1;
    if (__pyx_t_17 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_e_mat0.shape[0])) __pyx_t_8 = 0;
    if (__pyx_t_12 < 0) {
      __pyx_t_8 = 1;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_e_mat0.shape[1])) __pyx_t_8 = 1;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 143, __pyx_L1_error)
    }
    __pyx_t_21 = 0;
    __pyx_t_11 = __pyx_v_i;
    __pyx_t_8 = -1;
    if (__pyx_t_21 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_21 >= __pyx_v_bwd.shape[0])) __pyx_t_8 = 0;
    if (__pyx_t_11 < 0) {
      __pyx_t_8 = 1;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_bwd.shape[1])) __pyx_t_8 = 1;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 143, __pyx_L1_error)
    }
    __pyx_t_13 = __pyx_v_i;
    __pyx_t_16 = 1;
    __pyx_t_15 = 0;
    __pyx_t_8 = -1;
    if (__pyx_t_13 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_t0.shape[0])) __pyx_t_8 = 0;
    if (__pyx_t_16 < 0) {
      __pyx_t_8 = 1;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t0.shape[1])) __pyx_t_8 = 1;
    if (__pyx_t_15 < 0) {
      __pyx_t_8 = 2;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t0.shape[2])) __pyx_t_8 = 2;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 143, __pyx_L1_error)
    }
    __pyx_t_22 = 0;
    __pyx_t_8 = -1;
    if (__pyx_t_22 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_22 >= __pyx_v_three_v_view.shape[0])) __pyx_t_8 = 0;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 143, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_three_v_view.data + __pyx_t_22 * __pyx_v_three_v_view.strides[0]) )) = (((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat0.data + __pyx_t_17 * __pyx_v_e_mat0.strides[0]) ) + __pyx_t_12 * __pyx_v_e_mat0.strides[1]) ))) + (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_21 * __pyx_v_bwd.strides[0]) ) + __pyx_t_11 * __pyx_v_bwd.strides[1]) )))) + (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t0.data + __pyx_t_13 * __pyx_v_t0.strides[0]) ) + __pyx_t_16 * __pyx_v_t0.strides[1]) ) + __pyx_t_15 * __pyx_v_t0.strides[2]) ))));
+144:       three_v_view[1] = f_l + t0[i, 1, 2]    # Coming from other ROH State
    __pyx_t_15 = __pyx_v_i;
    __pyx_t_16 = 1;
    __pyx_t_13 = 2;
    __pyx_t_8 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t0.shape[0])) __pyx_t_8 = 0;
    if (__pyx_t_16 < 0) {
      __pyx_t_8 = 1;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t0.shape[1])) __pyx_t_8 = 1;
    if (__pyx_t_13 < 0) {
      __pyx_t_8 = 2;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_t0.shape[2])) __pyx_t_8 = 2;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 144, __pyx_L1_error)
    }
    __pyx_t_11 = 1;
    __pyx_t_8 = -1;
    if (__pyx_t_11 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_three_v_view.shape[0])) __pyx_t_8 = 0;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 144, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_three_v_view.data + __pyx_t_11 * __pyx_v_three_v_view.strides[0]) )) = (__pyx_v_f_l + (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t0.data + __pyx_t_15 * __pyx_v_t0.strides[0]) ) + __pyx_t_16 * __pyx_v_t0.strides[1]) ) + __pyx_t_13 * __pyx_v_t0.strides[2]) ))));
 145: 
+146:       for j in range(1, n_states):  # Do the final run over all states
    __pyx_t_8 = __pyx_v_n_states;
    __pyx_t_9 = __pyx_t_8;
    for (__pyx_t_19 = 1; __pyx_t_19 < __pyx_t_9; __pyx_t_19+=1) {
      __pyx_v_j = __pyx_t_19;
+147:         three_v_view[2] = e_mat0[j, i] + bwd[j, i] +  stay
      __pyx_t_13 = __pyx_v_j;
      __pyx_t_16 = __pyx_v_i;
      __pyx_t_14 = -1;
      if (__pyx_t_13 < 0) {
        __pyx_t_14 = 0;
      } else if (unlikely(__pyx_t_13 >= __pyx_v_e_mat0.shape[0])) __pyx_t_14 = 0;
      if (__pyx_t_16 < 0) {
        __pyx_t_14 = 1;
      } else if (unlikely(__pyx_t_16 >= __pyx_v_e_mat0.shape[1])) __pyx_t_14 = 1;
      if (unlikely(__pyx_t_14 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_14);
        __PYX_ERR(0, 147, __pyx_L1_error)
      }
      __pyx_t_15 = __pyx_v_j;
      __pyx_t_11 = __pyx_v_i;
      __pyx_t_14 = -1;
      if (__pyx_t_15 < 0) {
        __pyx_t_14 = 0;
      } else if (unlikely(__pyx_t_15 >= __pyx_v_bwd.shape[0])) __pyx_t_14 = 0;
      if (__pyx_t_11 < 0) {
        __pyx_t_14 = 1;
      } else if (unlikely(__pyx_t_11 >= __pyx_v_bwd.shape[1])) __pyx_t_14 = 1;
      if (unlikely(__pyx_t_14 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_14);
        __PYX_ERR(0, 147, __pyx_L1_error)
      }
      __pyx_t_21 = 2;
      __pyx_t_14 = -1;
      if (__pyx_t_21 < 0) {
        __pyx_t_14 = 0;
      } else if (unlikely(__pyx_t_21 >= __pyx_v_three_v_view.shape[0])) __pyx_t_14 = 0;
      if (unlikely(__pyx_t_14 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_14);
        __PYX_ERR(0, 147, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_three_v_view.data + __pyx_t_21 * __pyx_v_three_v_view.strides[0]) )) = (((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat0.data + __pyx_t_13 * __pyx_v_e_mat0.strides[0]) ) + __pyx_t_16 * __pyx_v_e_mat0.strides[1]) ))) + (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_15 * __pyx_v_bwd.strides[0]) ) + __pyx_t_11 * __pyx_v_bwd.strides[1]) )))) + __pyx_v_stay);
+148:         bwd[j, i - 1] = logsumexp(three_v_view)  # Fill in the backward Probability
      __pyx_t_11 = __pyx_v_j;
      __pyx_t_15 = (__pyx_v_i - 1);
      __pyx_t_14 = -1;
      if (__pyx_t_11 < 0) {
        __pyx_t_14 = 0;
      } else if (unlikely(__pyx_t_11 >= __pyx_v_bwd.shape[0])) __pyx_t_14 = 0;
      if (__pyx_t_15 < 0) {
        __pyx_t_14 = 1;
      } else if (unlikely(__pyx_t_15 >= __pyx_v_bwd.shape[1])) __pyx_t_14 = 1;
      if (unlikely(__pyx_t_14 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_14);
        __PYX_ERR(0, 148, __pyx_L1_error)
      }
      *((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_11 * __pyx_v_bwd.strides[0]) ) + __pyx_t_15 * __pyx_v_bwd.strides[1]) )) = __pyx_f_8hapsburg_5cfunc_logsumexp(__pyx_v_three_v_view);
    }
  }
 149: 
 150:     # Get total log likelihood
+151:     for k in range(n_states):  # Simply sum the two 1D arrays
  __pyx_t_8 = __pyx_v_n_states;
  __pyx_t_9 = __pyx_t_8;
  for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
    __pyx_v_k = __pyx_t_10;
+152:       trans_ll_view1[k] = fwd[k, n_loci - 1] + bwd[k, n_loci - 1]
    __pyx_t_15 = __pyx_v_k;
    __pyx_t_11 = (__pyx_v_n_loci - 1);
    __pyx_t_14 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_fwd.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_11 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_fwd.shape[1])) __pyx_t_14 = 1;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 152, __pyx_L1_error)
    }
    __pyx_t_16 = __pyx_v_k;
    __pyx_t_13 = (__pyx_v_n_loci - 1);
    __pyx_t_14 = -1;
    if (__pyx_t_16 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_bwd.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_bwd.shape[1])) __pyx_t_14 = 1;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 152, __pyx_L1_error)
    }
    __pyx_t_21 = __pyx_v_k;
    __pyx_t_14 = -1;
    if (__pyx_t_21 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_21 >= __pyx_v_trans_ll_view1.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 152, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_trans_ll_view1.data + __pyx_t_21 * __pyx_v_trans_ll_view1.strides[0]) )) = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_15 * __pyx_v_fwd.strides[0]) ) + __pyx_t_11 * __pyx_v_fwd.strides[1]) ))) + (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_16 * __pyx_v_bwd.strides[0]) ) + __pyx_t_13 * __pyx_v_bwd.strides[1]) ))));
  }
+153:     tot_ll = logsumexp(trans_ll_view1)
  __pyx_v_tot_ll = __pyx_f_8hapsburg_5cfunc_logsumexp(__pyx_v_trans_ll_view1);
 154: 
 155:     # Combine the forward and backward calculations
+156:     fwd1 = np.asarray(fwd, dtype=np.float)  # Transform
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 156, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_asarray); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 156, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __pyx_memoryview_fromslice(__pyx_v_fwd, 2, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 156, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 156, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_2);
  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
  __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 156, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 156, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_23 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_float); if (unlikely(!__pyx_t_23)) __PYX_ERR(0, 156, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_23);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_23) < 0) __PYX_ERR(0, 156, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_23); __pyx_t_23 = 0;
  __pyx_t_23 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_23)) __PYX_ERR(0, 156, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_23);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_fwd1 = __pyx_t_23;
  __pyx_t_23 = 0;
+157:     bwd1 = np.asarray(bwd, dtype=np.float)
  __Pyx_GetModuleGlobalName(__pyx_t_23, __pyx_n_s_np); if (unlikely(!__pyx_t_23)) __PYX_ERR(0, 157, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_23);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_23, __pyx_n_s_asarray); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 157, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_23); __pyx_t_23 = 0;
  __pyx_t_23 = __pyx_memoryview_fromslice(__pyx_v_bwd, 2, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_23)) __PYX_ERR(0, 157, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_23);
  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 157, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_23);
  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_23);
  __pyx_t_23 = 0;
  __pyx_t_23 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_23)) __PYX_ERR(0, 157, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_23);
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 157, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_float); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 157, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  if (PyDict_SetItem(__pyx_t_23, __pyx_n_s_dtype, __pyx_t_1) < 0) __PYX_ERR(0, 157, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, __pyx_t_23); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 157, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_23); __pyx_t_23 = 0;
  __pyx_v_bwd1 = __pyx_t_1;
  __pyx_t_1 = 0;
+158:     post = fwd1 + bwd1 - np.float(tot_ll)
  __pyx_t_1 = PyNumber_Add(__pyx_v_fwd1, __pyx_v_bwd1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 158, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 158, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 158, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = PyFloat_FromDouble(__pyx_v_tot_ll); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 158, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_3 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_2, function);
    }
  }
  __pyx_t_23 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4);
  __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (unlikely(!__pyx_t_23)) __PYX_ERR(0, 158, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_23);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_t_23); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 158, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_23); __pyx_t_23 = 0;
  __Pyx_DECREF_SET(__pyx_v_post, __pyx_t_2);
  __pyx_t_2 = 0;
 159: 
+160:     if output:
  __pyx_t_24 = __Pyx_PyObject_IsTrue(__pyx_v_output); if (unlikely(__pyx_t_24 < 0)) __PYX_ERR(0, 160, __pyx_L1_error)
  if (__pyx_t_24) {
/* … */
  }
+161:         print("Memory Usage Full:")
    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_print, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 161, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
/* … */
  __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_u_Memory_Usage_Full); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(0, 161, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__8);
  __Pyx_GIVEREF(__pyx_tuple__8);
+162:         print_memory_usage()   ## For MEMORY_BENCH
    __Pyx_GetModuleGlobalName(__pyx_t_23, __pyx_n_s_print_memory_usage); if (unlikely(!__pyx_t_23)) __PYX_ERR(0, 162, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_23);
    __pyx_t_1 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_23))) {
      __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_23);
      if (likely(__pyx_t_1)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_23);
        __Pyx_INCREF(__pyx_t_1);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_23, function);
      }
    }
    __pyx_t_2 = (__pyx_t_1) ? __Pyx_PyObject_CallOneArg(__pyx_t_23, __pyx_t_1) : __Pyx_PyObject_CallNoArg(__pyx_t_23);
    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 162, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_23); __pyx_t_23 = 0;
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+163:         print(f"Total Log likelihood: {tot_ll: .3f}")
    __pyx_t_2 = PyFloat_FromDouble(__pyx_v_tot_ll); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 163, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_23 = __Pyx_PyObject_Format(__pyx_t_2, __pyx_kp_u_3f); if (unlikely(!__pyx_t_23)) __PYX_ERR(0, 163, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_23);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Total_Log_likelihood, __pyx_t_23); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 163, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_23); __pyx_t_23 = 0;
    __pyx_t_23 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_2); if (unlikely(!__pyx_t_23)) __PYX_ERR(0, 163, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_23);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __Pyx_DECREF(__pyx_t_23); __pyx_t_23 = 0;
 164: 
+165:     post = np.exp(post) # Go to normal space
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 165, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_exp); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 165, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = NULL;
  if (CYTHON_UNPACK_METHODS && 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_23 = (__pyx_t_2) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_2, __pyx_v_post) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_v_post);
  __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (unlikely(!__pyx_t_23)) __PYX_ERR(0, 165, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_23);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF_SET(__pyx_v_post, __pyx_t_23);
  __pyx_t_23 = 0;
 166: 
+167:     if full==False:
  __pyx_t_23 = PyObject_RichCompare(__pyx_v_full, Py_False, Py_EQ); __Pyx_XGOTREF(__pyx_t_23); if (unlikely(!__pyx_t_23)) __PYX_ERR(0, 167, __pyx_L1_error)
  __pyx_t_24 = __Pyx_PyObject_IsTrue(__pyx_t_23); if (unlikely(__pyx_t_24 < 0)) __PYX_ERR(0, 167, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_23); __pyx_t_23 = 0;
  if (__pyx_t_24) {
/* … */
  }
+168:       return post
    __Pyx_XDECREF(__pyx_r);
    __Pyx_INCREF(__pyx_v_post);
    __pyx_r = __pyx_v_post;
    goto __pyx_L0;
 169: 
+170:     elif full==True:   # Return everything
  __pyx_t_23 = PyObject_RichCompare(__pyx_v_full, Py_True, Py_EQ); __Pyx_XGOTREF(__pyx_t_23); if (unlikely(!__pyx_t_23)) __PYX_ERR(0, 170, __pyx_L1_error)
  __pyx_t_24 = __Pyx_PyObject_IsTrue(__pyx_t_23); if (unlikely(__pyx_t_24 < 0)) __PYX_ERR(0, 170, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_23); __pyx_t_23 = 0;
  if (__pyx_t_24) {
/* … */
  }
+171:       return post, fwd1, bwd1, tot_ll
    __Pyx_XDECREF(__pyx_r);
    __pyx_t_23 = PyFloat_FromDouble(__pyx_v_tot_ll); if (unlikely(!__pyx_t_23)) __PYX_ERR(0, 171, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_23);
    __pyx_t_1 = PyTuple_New(4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 171, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_INCREF(__pyx_v_post);
    __Pyx_GIVEREF(__pyx_v_post);
    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_post);
    __Pyx_INCREF(__pyx_v_fwd1);
    __Pyx_GIVEREF(__pyx_v_fwd1);
    PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_fwd1);
    __Pyx_INCREF(__pyx_v_bwd1);
    __Pyx_GIVEREF(__pyx_v_bwd1);
    PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_bwd1);
    __Pyx_GIVEREF(__pyx_t_23);
    PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_t_23);
    __pyx_t_23 = 0;
    __pyx_r = __pyx_t_1;
    __pyx_t_1 = 0;
    goto __pyx_L0;
 172: 
 173: 
+174: def fwd_bkwd_lowmem(double[:, :] e_mat, double[:, :, :] t_mat,
/* Python wrapper */
static PyObject *__pyx_pw_8hapsburg_5cfunc_5fwd_bkwd_lowmem(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_8hapsburg_5cfunc_4fwd_bkwd_lowmem[] = "Takes emission and transition probabilities, and calculates posteriors.\n    Uses speed-up specific for Genotype data (pooling same transition rates)\n    Low-Mem: Do no save the full FWD BWD and Posterior. Use temporary\n    Arrays for saving. Input:\n    e_mat: Emission probabilities: [k x l]  (normal space)\n    t_mat: Transition Matrix:  [l x 3 x 3]  (normal space)\n    in_val: Intitial probability of single symmetric state (normal space)\n    full: Boolean whether to return (post, fwd1, bwd1, tot_ll)\n    else only return post\n    output: Whether to print output useful for monitoring.\n    Otherwise only posterior mat [kxl] of post is returned";
static PyMethodDef __pyx_mdef_8hapsburg_5cfunc_5fwd_bkwd_lowmem = {"fwd_bkwd_lowmem", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_8hapsburg_5cfunc_5fwd_bkwd_lowmem, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8hapsburg_5cfunc_4fwd_bkwd_lowmem};
static PyObject *__pyx_pw_8hapsburg_5cfunc_5fwd_bkwd_lowmem(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  __Pyx_memviewslice __pyx_v_e_mat = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_t_mat = { 0, 0, { 0 }, { 0 }, { 0 } };
  double __pyx_v_in_val;
  PyObject *__pyx_v_full = 0;
  PyObject *__pyx_v_output = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("fwd_bkwd_lowmem (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_e_mat,&__pyx_n_s_t_mat,&__pyx_n_s_in_val,&__pyx_n_s_full,&__pyx_n_s_output,0};
    PyObject* values[5] = {0,0,0,0,0};
/* … */
  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_8hapsburg_5cfunc_4fwd_bkwd_lowmem(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_e_mat, __Pyx_memviewslice __pyx_v_t_mat, double __pyx_v_in_val, PyObject *__pyx_v_full, PyObject *__pyx_v_output) {
  int __pyx_v_n_states;
  int __pyx_v_n_loci;
  Py_ssize_t __pyx_v_i;
  Py_ssize_t __pyx_v_j;
  Py_ssize_t __pyx_v_k;
  double __pyx_v_stay;
  double __pyx_v_tot_ll;
  __Pyx_memviewslice __pyx_v_t0 = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_e_mat0 = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_post = NULL;
  __Pyx_memviewslice __pyx_v_post_view = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_trans_ll = NULL;
  __Pyx_memviewslice __pyx_v_trans_ll_view = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_trans_ll1 = NULL;
  __Pyx_memviewslice __pyx_v_trans_ll_view1 = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_three_v = NULL;
  __Pyx_memviewslice __pyx_v_three_v_view = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_two_v = NULL;
  __Pyx_memviewslice __pyx_v_two_v_view = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_fwd0 = NULL;
  __Pyx_memviewslice __pyx_v_fwd = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_bwd0 = NULL;
  __Pyx_memviewslice __pyx_v_bwd = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_tmp0 = NULL;
  __Pyx_memviewslice __pyx_v_tmp = { 0, 0, { 0 }, { 0 }, { 0 } };
  double __pyx_v_f_l;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("fwd_bkwd_lowmem", 0);
/* … */
  /* function exit code */
  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  goto __pyx_L0;
  __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_XDEC_MEMVIEW(&__pyx_t_6, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_t_7, 1);
  __Pyx_AddTraceback("hapsburg.cfunc.fwd_bkwd_lowmem", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __PYX_XDEC_MEMVIEW(&__pyx_v_t0, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_e_mat0, 1);
  __Pyx_XDECREF(__pyx_v_post);
  __PYX_XDEC_MEMVIEW(&__pyx_v_post_view, 1);
  __Pyx_XDECREF(__pyx_v_trans_ll);
  __PYX_XDEC_MEMVIEW(&__pyx_v_trans_ll_view, 1);
  __Pyx_XDECREF(__pyx_v_trans_ll1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_trans_ll_view1, 1);
  __Pyx_XDECREF(__pyx_v_three_v);
  __PYX_XDEC_MEMVIEW(&__pyx_v_three_v_view, 1);
  __Pyx_XDECREF(__pyx_v_two_v);
  __PYX_XDEC_MEMVIEW(&__pyx_v_two_v_view, 1);
  __Pyx_XDECREF(__pyx_v_fwd0);
  __PYX_XDEC_MEMVIEW(&__pyx_v_fwd, 1);
  __Pyx_XDECREF(__pyx_v_bwd0);
  __PYX_XDEC_MEMVIEW(&__pyx_v_bwd, 1);
  __Pyx_XDECREF(__pyx_v_tmp0);
  __PYX_XDEC_MEMVIEW(&__pyx_v_tmp, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_e_mat, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_t_mat, 1);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__32 = PyTuple_Pack(31, __pyx_n_s_e_mat, __pyx_n_s_t_mat, __pyx_n_s_in_val, __pyx_n_s_full, __pyx_n_s_output, __pyx_n_s_n_states, __pyx_n_s_n_loci, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_k, __pyx_n_s_stay, __pyx_n_s_tot_ll, __pyx_n_s_t0, __pyx_n_s_e_mat0, __pyx_n_s_post, __pyx_n_s_post_view, __pyx_n_s_trans_ll, __pyx_n_s_trans_ll_view, __pyx_n_s_trans_ll1, __pyx_n_s_trans_ll_view1, __pyx_n_s_three_v, __pyx_n_s_three_v_view, __pyx_n_s_two_v, __pyx_n_s_two_v_view, __pyx_n_s_fwd0, __pyx_n_s_fwd, __pyx_n_s_bwd0, __pyx_n_s_bwd, __pyx_n_s_tmp0, __pyx_n_s_tmp, __pyx_n_s_f_l); if (unlikely(!__pyx_tuple__32)) __PYX_ERR(0, 174, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__32);
  __Pyx_GIVEREF(__pyx_tuple__32);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_8hapsburg_5cfunc_5fwd_bkwd_lowmem, NULL, __pyx_n_s_hapsburg_cfunc); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 174, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_fwd_bkwd_lowmem, __pyx_t_2) < 0) __PYX_ERR(0, 174, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__33 = (PyObject*)__Pyx_PyCode_New(5, 0, 31, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__32, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_hapsburg_cfunc_pyx, __pyx_n_s_fwd_bkwd_lowmem, 174, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__33)) __PYX_ERR(0, 174, __pyx_L1_error)
+175:                     double in_val = 1e-4, full=False, output=True):
    values[3] = ((PyObject *)Py_False);
    values[4] = ((PyObject *)Py_True);
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        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_e_mat)) != 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_t_mat)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("fwd_bkwd_lowmem", 0, 2, 5, 1); __PYX_ERR(0, 174, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_in_val);
          if (value) { values[2] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_full);
          if (value) { values[3] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  4:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_output);
          if (value) { values[4] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "fwd_bkwd_lowmem") < 0)) __PYX_ERR(0, 174, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        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);
        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_e_mat = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(values[0], PyBUF_WRITABLE); if (unlikely(!__pyx_v_e_mat.memview)) __PYX_ERR(0, 174, __pyx_L3_error)
    __pyx_v_t_mat = __Pyx_PyObject_to_MemoryviewSlice_dsdsds_double(values[1], PyBUF_WRITABLE); if (unlikely(!__pyx_v_t_mat.memview)) __PYX_ERR(0, 174, __pyx_L3_error)
    if (values[2]) {
      __pyx_v_in_val = __pyx_PyFloat_AsDouble(values[2]); if (unlikely((__pyx_v_in_val == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 175, __pyx_L3_error)
    } else {
      __pyx_v_in_val = ((double)1e-4);
    }
    __pyx_v_full = values[3];
    __pyx_v_output = values[4];
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("fwd_bkwd_lowmem", 0, 2, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 174, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("hapsburg.cfunc.fwd_bkwd_lowmem", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_8hapsburg_5cfunc_4fwd_bkwd_lowmem(__pyx_self, __pyx_v_e_mat, __pyx_v_t_mat, __pyx_v_in_val, __pyx_v_full, __pyx_v_output);
 176:     """Takes emission and transition probabilities, and calculates posteriors.
 177:     Uses speed-up specific for Genotype data (pooling same transition rates)
 178:     Low-Mem: Do no save the full FWD BWD and Posterior. Use temporary
 179:     Arrays for saving. Input:
 180:     e_mat: Emission probabilities: [k x l]  (normal space)
 181:     t_mat: Transition Matrix:  [l x 3 x 3]  (normal space)
 182:     in_val: Intitial probability of single symmetric state (normal space)
 183:     full: Boolean whether to return (post, fwd1, bwd1, tot_ll)
 184:     else only return post
 185:     output: Whether to print output useful for monitoring.
 186:     Otherwise only posterior mat [kxl] of post is returned"""
+187:     cdef int n_states = e_mat.shape[0]
  __pyx_v_n_states = (__pyx_v_e_mat.shape[0]);
+188:     cdef int n_loci = e_mat.shape[1]
  __pyx_v_n_loci = (__pyx_v_e_mat.shape[1]);
 189:     cdef Py_ssize_t i, j, k    # The Array Indices
 190:     cdef double stay           # The Probablility of Staying
 191:     cdef double tot_ll  # The total Likelihood (need for Posterior)
 192: 
 193:     # Do transform to Log Space:
+194:     cdef double[:,:,:] t0 = np.log(t_mat)
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 194, __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, 194, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __pyx_memoryview_fromslice(__pyx_v_t_mat, 3, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 194, __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, 194, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_dsdsds_double(__pyx_t_1, PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 194, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_t0 = __pyx_t_5;
  __pyx_t_5.memview = NULL;
  __pyx_t_5.data = NULL;
+195:     cdef double[:, :] e_mat0 = np.log(e_mat)
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 195, __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, 195, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_e_mat, 2, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 195, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
    if (likely(__pyx_t_4)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
      __Pyx_INCREF(__pyx_t_4);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_2, function);
    }
  }
  __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 195, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(__pyx_t_1, PyBUF_WRITABLE); if (unlikely(!__pyx_t_6.memview)) __PYX_ERR(0, 195, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_e_mat0 = __pyx_t_6;
  __pyx_t_6.memview = NULL;
  __pyx_t_6.data = NULL;
 196: 
 197:     # Initialize Posterior and Transition Probabilities
+198:     post = np.empty(n_loci, dtype=DTYPE) # Array of 0 State Posterior
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 198, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 198, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_n_loci); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 198, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 198, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
  __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 198, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 198, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_4) < 0) __PYX_ERR(0, 198, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 198, __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_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_post = __pyx_t_4;
  __pyx_t_4 = 0;
+199:     cdef double[:] post_view = post
  __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_post, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 199, __pyx_L1_error)
  __pyx_v_post_view = __pyx_t_7;
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
 200: 
+201:     trans_ll = np.empty(n_states-1, dtype=DTYPE) # Array for pre-calculations
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 201, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_empty); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 201, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyInt_From_long((__pyx_v_n_states - 1)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 201, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 201, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
  __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 201, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 201, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_2) < 0) __PYX_ERR(0, 201, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 201, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_v_trans_ll = __pyx_t_2;
  __pyx_t_2 = 0;
+202:     cdef double[:] trans_ll_view = trans_ll
  __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_trans_ll, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 202, __pyx_L1_error)
  __pyx_v_trans_ll_view = __pyx_t_7;
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
 203: 
+204:     trans_ll1 = np.empty(n_states, dtype=DTYPE) # Array for calculations
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 204, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 204, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_n_states); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 204, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 204, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_2);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
  __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 204, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 204, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_1) < 0) __PYX_ERR(0, 204, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 204, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_trans_ll1 = __pyx_t_1;
  __pyx_t_1 = 0;
+205:     cdef double[:] trans_ll_view1 = trans_ll1
  __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_trans_ll1, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 205, __pyx_L1_error)
  __pyx_v_trans_ll_view1 = __pyx_t_7;
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
 206: 
+207:     three_v = np.empty(3, dtype=DTYPE)     # Array of size three
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 207, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 207, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 207, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 207, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_3) < 0) __PYX_ERR(0, 207, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple_, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 207, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_three_v = __pyx_t_3;
  __pyx_t_3 = 0;
+208:     cdef double[:] three_v_view = three_v
  __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_three_v, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 208, __pyx_L1_error)
  __pyx_v_three_v_view = __pyx_t_7;
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
 209: 
+210:     two_v = np.empty(2, dtype=DTYPE)       # Array of size two
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 210, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_empty); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 210, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 210, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 210, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_2) < 0) __PYX_ERR(0, 210, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__2, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 210, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_v_two_v = __pyx_t_2;
  __pyx_t_2 = 0;
+211:     cdef double[:] two_v_view = two_v
  __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_two_v, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 211, __pyx_L1_error)
  __pyx_v_two_v_view = __pyx_t_7;
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
 212: 
 213: 
 214:     ### Initialize FWD BWD Arrays
+215:     fwd0 = np.zeros(n_states, dtype=DTYPE)
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 215, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_zeros); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 215, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_n_states); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 215, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 215, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_GIVEREF(__pyx_t_2);
  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
  __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 215, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 215, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_4) < 0) __PYX_ERR(0, 215, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 215, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_fwd0 = __pyx_t_4;
  __pyx_t_4 = 0;
+216:     fwd0[:] = in_val  # Initial Probabilities
  __pyx_t_4 = PyFloat_FromDouble(__pyx_v_in_val); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 216, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (__Pyx_PyObject_SetSlice(__pyx_v_fwd0, __pyx_t_4, 0, 0, NULL, NULL, &__pyx_slice__3, 0, 0, 0) < 0) __PYX_ERR(0, 216, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+217:     fwd0[0] = 1 - (n_states - 1) * in_val
  __pyx_t_4 = PyFloat_FromDouble((1.0 - ((__pyx_v_n_states - 1) * __pyx_v_in_val))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 217, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (unlikely(__Pyx_SetItemInt(__pyx_v_fwd0, 0, __pyx_t_4, long, 1, __Pyx_PyInt_From_long, 0, 0, 1) < 0)) __PYX_ERR(0, 217, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+218:     cdef double[:] fwd = fwd0
  __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_fwd0, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 218, __pyx_L1_error)
  __pyx_v_fwd = __pyx_t_7;
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
 219: 
+220:     bwd0 = np.zeros(n_states, dtype=DTYPE)
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 220, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_zeros); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 220, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_n_states); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 220, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 220, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_4);
  __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 220, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 220, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_3) < 0) __PYX_ERR(0, 220, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 220, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_v_bwd0 = __pyx_t_3;
  __pyx_t_3 = 0;
+221:     bwd0[:] = in_val
  __pyx_t_3 = PyFloat_FromDouble(__pyx_v_in_val); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 221, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  if (__Pyx_PyObject_SetSlice(__pyx_v_bwd0, __pyx_t_3, 0, 0, NULL, NULL, &__pyx_slice__3, 0, 0, 0) < 0) __PYX_ERR(0, 221, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+222:     bwd0[0] = 1 - (n_states - 1) * in_val
  __pyx_t_3 = PyFloat_FromDouble((1.0 - ((__pyx_v_n_states - 1) * __pyx_v_in_val))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 222, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  if (unlikely(__Pyx_SetItemInt(__pyx_v_bwd0, 0, __pyx_t_3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1) < 0)) __PYX_ERR(0, 222, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+223:     cdef double[:] bwd = bwd0
  __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_bwd0, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 223, __pyx_L1_error)
  __pyx_v_bwd = __pyx_t_7;
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
 224: 
+225:     tmp0 = np.zeros(n_states, dtype=DTYPE)
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 225, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_zeros); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 225, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_n_states); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 225, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 225, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_GIVEREF(__pyx_t_3);
  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3);
  __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 225, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 225, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 225, __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_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_v_tmp0 = __pyx_t_2;
  __pyx_t_2 = 0;
+226:     cdef double[:] tmp = tmp0
  __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_tmp0, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 226, __pyx_L1_error)
  __pyx_v_tmp = __pyx_t_7;
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
 227: 
 228:     #############################
 229:     ### Do the Forward Algorithm
 230: 
+231:     post_view[0] = fwd[0] # Add to first locus 0 Posterior
  __pyx_t_8 = 0;
  __pyx_t_9 = -1;
  if (__pyx_t_8 < 0) {
    __pyx_t_9 = 0;
  } else if (unlikely(__pyx_t_8 >= __pyx_v_fwd.shape[0])) __pyx_t_9 = 0;
  if (unlikely(__pyx_t_9 != -1)) {
    __Pyx_RaiseBufferIndexError(__pyx_t_9);
    __PYX_ERR(0, 231, __pyx_L1_error)
  }
  __pyx_t_10 = 0;
  __pyx_t_9 = -1;
  if (__pyx_t_10 < 0) {
    __pyx_t_9 = 0;
  } else if (unlikely(__pyx_t_10 >= __pyx_v_post_view.shape[0])) __pyx_t_9 = 0;
  if (unlikely(__pyx_t_9 != -1)) {
    __Pyx_RaiseBufferIndexError(__pyx_t_9);
    __PYX_ERR(0, 231, __pyx_L1_error)
  }
  *((double *) ( /* dim=0 */ (__pyx_v_post_view.data + __pyx_t_10 * __pyx_v_post_view.strides[0]) )) = (*((double *) ( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_8 * __pyx_v_fwd.strides[0]) )));
+232:     for i in range(1, n_loci):  # Run forward recursion
  __pyx_t_9 = __pyx_v_n_loci;
  __pyx_t_11 = __pyx_t_9;
  for (__pyx_t_12 = 1; __pyx_t_12 < __pyx_t_11; __pyx_t_12+=1) {
    __pyx_v_i = __pyx_t_12;
+233:         stay = log(t_mat[i, 1, 1] - t_mat[i, 1, 2])  # Do the log of the Stay term
    __pyx_t_8 = __pyx_v_i;
    __pyx_t_10 = 1;
    __pyx_t_13 = 1;
    __pyx_t_14 = -1;
    if (__pyx_t_8 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_8 >= __pyx_v_t_mat.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_10 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_10 >= __pyx_v_t_mat.shape[1])) __pyx_t_14 = 1;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 2;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_t_mat.shape[2])) __pyx_t_14 = 2;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 233, __pyx_L1_error)
    }
    __pyx_t_15 = __pyx_v_i;
    __pyx_t_16 = 1;
    __pyx_t_17 = 2;
    __pyx_t_14 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t_mat.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_16 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t_mat.shape[1])) __pyx_t_14 = 1;
    if (__pyx_t_17 < 0) {
      __pyx_t_14 = 2;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_t_mat.shape[2])) __pyx_t_14 = 2;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 233, __pyx_L1_error)
    }
    __pyx_v_stay = log(((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t_mat.data + __pyx_t_8 * __pyx_v_t_mat.strides[0]) ) + __pyx_t_10 * __pyx_v_t_mat.strides[1]) ) + __pyx_t_13 * __pyx_v_t_mat.strides[2]) ))) - (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t_mat.data + __pyx_t_15 * __pyx_v_t_mat.strides[0]) ) + __pyx_t_16 * __pyx_v_t_mat.strides[1]) ) + __pyx_t_17 * __pyx_v_t_mat.strides[2]) )))));
 234: 
+235:         for k in range(1, n_states): # Calculate logsum of ROH states:
    __pyx_t_14 = __pyx_v_n_states;
    __pyx_t_18 = __pyx_t_14;
    for (__pyx_t_19 = 1; __pyx_t_19 < __pyx_t_18; __pyx_t_19+=1) {
      __pyx_v_k = __pyx_t_19;
+236:             trans_ll_view[k-1] = fwd[k]
      __pyx_t_17 = __pyx_v_k;
      __pyx_t_20 = -1;
      if (__pyx_t_17 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_17 >= __pyx_v_fwd.shape[0])) __pyx_t_20 = 0;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 236, __pyx_L1_error)
      }
      __pyx_t_16 = (__pyx_v_k - 1);
      __pyx_t_20 = -1;
      if (__pyx_t_16 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_16 >= __pyx_v_trans_ll_view.shape[0])) __pyx_t_20 = 0;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 236, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_trans_ll_view.data + __pyx_t_16 * __pyx_v_trans_ll_view.strides[0]) )) = (*((double *) ( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_17 * __pyx_v_fwd.strides[0]) )));
    }
+237:         f_l = logsumexp(trans_ll_view) # Logsum of ROH States
    __pyx_v_f_l = __pyx_f_8hapsburg_5cfunc_logsumexp(__pyx_v_trans_ll_view);
 238: 
 239:         # Do the 0 State:
+240:         two_v_view[0] = fwd[0] + t0[i, 0, 0]   # Staying in 0 State
    __pyx_t_17 = 0;
    __pyx_t_14 = -1;
    if (__pyx_t_17 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_fwd.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 240, __pyx_L1_error)
    }
    __pyx_t_16 = __pyx_v_i;
    __pyx_t_15 = 0;
    __pyx_t_13 = 0;
    __pyx_t_14 = -1;
    if (__pyx_t_16 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t0.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_15 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t0.shape[1])) __pyx_t_14 = 1;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 2;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_t0.shape[2])) __pyx_t_14 = 2;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 240, __pyx_L1_error)
    }
    __pyx_t_10 = 0;
    __pyx_t_14 = -1;
    if (__pyx_t_10 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_10 >= __pyx_v_two_v_view.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 240, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_two_v_view.data + __pyx_t_10 * __pyx_v_two_v_view.strides[0]) )) = ((*((double *) ( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_17 * __pyx_v_fwd.strides[0]) ))) + (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t0.data + __pyx_t_16 * __pyx_v_t0.strides[0]) ) + __pyx_t_15 * __pyx_v_t0.strides[1]) ) + __pyx_t_13 * __pyx_v_t0.strides[2]) ))));
+241:         two_v_view[1] = f_l + t0[i, 1, 0]             # Going into 0 State
    __pyx_t_13 = __pyx_v_i;
    __pyx_t_15 = 1;
    __pyx_t_16 = 0;
    __pyx_t_14 = -1;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_t0.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_15 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t0.shape[1])) __pyx_t_14 = 1;
    if (__pyx_t_16 < 0) {
      __pyx_t_14 = 2;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t0.shape[2])) __pyx_t_14 = 2;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 241, __pyx_L1_error)
    }
    __pyx_t_17 = 1;
    __pyx_t_14 = -1;
    if (__pyx_t_17 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_two_v_view.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 241, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_two_v_view.data + __pyx_t_17 * __pyx_v_two_v_view.strides[0]) )) = (__pyx_v_f_l + (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t0.data + __pyx_t_13 * __pyx_v_t0.strides[0]) ) + __pyx_t_15 * __pyx_v_t0.strides[1]) ) + __pyx_t_16 * __pyx_v_t0.strides[2]) ))));
+242:         tmp[0] = e_mat0[0, i] + logsumexp(two_v_view)
    __pyx_t_16 = 0;
    __pyx_t_15 = __pyx_v_i;
    __pyx_t_14 = -1;
    if (__pyx_t_16 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_e_mat0.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_15 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_e_mat0.shape[1])) __pyx_t_14 = 1;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 242, __pyx_L1_error)
    }
    __pyx_t_13 = 0;
    __pyx_t_14 = -1;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_tmp.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 242, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_tmp.data + __pyx_t_13 * __pyx_v_tmp.strides[0]) )) = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat0.data + __pyx_t_16 * __pyx_v_e_mat0.strides[0]) ) + __pyx_t_15 * __pyx_v_e_mat0.strides[1]) ))) + __pyx_f_8hapsburg_5cfunc_logsumexp(__pyx_v_two_v_view));
 243: 
 244:         ### Do the other states
 245:         # Preprocessing:
+246:         three_v_view[0] = fwd[0] + t0[i, 0, 1]   # Coming from 0 State
    __pyx_t_15 = 0;
    __pyx_t_14 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_fwd.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 246, __pyx_L1_error)
    }
    __pyx_t_16 = __pyx_v_i;
    __pyx_t_13 = 0;
    __pyx_t_17 = 1;
    __pyx_t_14 = -1;
    if (__pyx_t_16 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t0.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_t0.shape[1])) __pyx_t_14 = 1;
    if (__pyx_t_17 < 0) {
      __pyx_t_14 = 2;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_t0.shape[2])) __pyx_t_14 = 2;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 246, __pyx_L1_error)
    }
    __pyx_t_10 = 0;
    __pyx_t_14 = -1;
    if (__pyx_t_10 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_10 >= __pyx_v_three_v_view.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 246, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_three_v_view.data + __pyx_t_10 * __pyx_v_three_v_view.strides[0]) )) = ((*((double *) ( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_15 * __pyx_v_fwd.strides[0]) ))) + (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t0.data + __pyx_t_16 * __pyx_v_t0.strides[0]) ) + __pyx_t_13 * __pyx_v_t0.strides[1]) ) + __pyx_t_17 * __pyx_v_t0.strides[2]) ))));
+247:         three_v_view[1] = f_l + t0[i, 1, 2]             # Coming from other ROH State
    __pyx_t_17 = __pyx_v_i;
    __pyx_t_13 = 1;
    __pyx_t_16 = 2;
    __pyx_t_14 = -1;
    if (__pyx_t_17 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_t0.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_t0.shape[1])) __pyx_t_14 = 1;
    if (__pyx_t_16 < 0) {
      __pyx_t_14 = 2;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t0.shape[2])) __pyx_t_14 = 2;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 247, __pyx_L1_error)
    }
    __pyx_t_15 = 1;
    __pyx_t_14 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_three_v_view.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 247, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_three_v_view.data + __pyx_t_15 * __pyx_v_three_v_view.strides[0]) )) = (__pyx_v_f_l + (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t0.data + __pyx_t_17 * __pyx_v_t0.strides[0]) ) + __pyx_t_13 * __pyx_v_t0.strides[1]) ) + __pyx_t_16 * __pyx_v_t0.strides[2]) ))));
 248: 
+249:         for j in range(1, n_states):  # Do the final run over all states
    __pyx_t_14 = __pyx_v_n_states;
    __pyx_t_18 = __pyx_t_14;
    for (__pyx_t_19 = 1; __pyx_t_19 < __pyx_t_18; __pyx_t_19+=1) {
      __pyx_v_j = __pyx_t_19;
+250:           three_v_view[2] = fwd[j] +  stay
      __pyx_t_16 = __pyx_v_j;
      __pyx_t_20 = -1;
      if (__pyx_t_16 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_16 >= __pyx_v_fwd.shape[0])) __pyx_t_20 = 0;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 250, __pyx_L1_error)
      }
      __pyx_t_13 = 2;
      __pyx_t_20 = -1;
      if (__pyx_t_13 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_13 >= __pyx_v_three_v_view.shape[0])) __pyx_t_20 = 0;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 250, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_three_v_view.data + __pyx_t_13 * __pyx_v_three_v_view.strides[0]) )) = ((*((double *) ( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_16 * __pyx_v_fwd.strides[0]) ))) + __pyx_v_stay);
+251:           tmp[j] = e_mat0[j, i] + logsumexp(three_v_view)
      __pyx_t_16 = __pyx_v_j;
      __pyx_t_13 = __pyx_v_i;
      __pyx_t_20 = -1;
      if (__pyx_t_16 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_16 >= __pyx_v_e_mat0.shape[0])) __pyx_t_20 = 0;
      if (__pyx_t_13 < 0) {
        __pyx_t_20 = 1;
      } else if (unlikely(__pyx_t_13 >= __pyx_v_e_mat0.shape[1])) __pyx_t_20 = 1;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 251, __pyx_L1_error)
      }
      __pyx_t_17 = __pyx_v_j;
      __pyx_t_20 = -1;
      if (__pyx_t_17 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_17 >= __pyx_v_tmp.shape[0])) __pyx_t_20 = 0;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 251, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_tmp.data + __pyx_t_17 * __pyx_v_tmp.strides[0]) )) = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat0.data + __pyx_t_16 * __pyx_v_e_mat0.strides[0]) ) + __pyx_t_13 * __pyx_v_e_mat0.strides[1]) ))) + __pyx_f_8hapsburg_5cfunc_logsumexp(__pyx_v_three_v_view));
    }
 252: 
 253:         ### Make tmp new fwd vec:
+254:         for j in range(0, n_states):
    __pyx_t_14 = __pyx_v_n_states;
    __pyx_t_18 = __pyx_t_14;
    for (__pyx_t_19 = 0; __pyx_t_19 < __pyx_t_18; __pyx_t_19+=1) {
      __pyx_v_j = __pyx_t_19;
+255:           fwd[j] = tmp[j]
      __pyx_t_13 = __pyx_v_j;
      __pyx_t_20 = -1;
      if (__pyx_t_13 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_13 >= __pyx_v_tmp.shape[0])) __pyx_t_20 = 0;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 255, __pyx_L1_error)
      }
      __pyx_t_16 = __pyx_v_j;
      __pyx_t_20 = -1;
      if (__pyx_t_16 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_16 >= __pyx_v_fwd.shape[0])) __pyx_t_20 = 0;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 255, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_16 * __pyx_v_fwd.strides[0]) )) = (*((double *) ( /* dim=0 */ (__pyx_v_tmp.data + __pyx_t_13 * __pyx_v_tmp.strides[0]) )));
    }
+256:         post_view[i] = fwd[0]  # Add to 0-State Posterior
    __pyx_t_13 = 0;
    __pyx_t_14 = -1;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_fwd.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 256, __pyx_L1_error)
    }
    __pyx_t_16 = __pyx_v_i;
    __pyx_t_14 = -1;
    if (__pyx_t_16 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_post_view.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 256, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_post_view.data + __pyx_t_16 * __pyx_v_post_view.strides[0]) )) = (*((double *) ( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_13 * __pyx_v_fwd.strides[0]) )));
  }
 257: 
 258:     ### Get total log likelihood
+259:     for k in range(n_states):  # Simply sum the two 1D arrays
  __pyx_t_9 = __pyx_v_n_states;
  __pyx_t_11 = __pyx_t_9;
  for (__pyx_t_12 = 0; __pyx_t_12 < __pyx_t_11; __pyx_t_12+=1) {
    __pyx_v_k = __pyx_t_12;
+260:       trans_ll_view1[k] = fwd[k] + bwd[k]
    __pyx_t_13 = __pyx_v_k;
    __pyx_t_14 = -1;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_fwd.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 260, __pyx_L1_error)
    }
    __pyx_t_16 = __pyx_v_k;
    __pyx_t_14 = -1;
    if (__pyx_t_16 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_bwd.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 260, __pyx_L1_error)
    }
    __pyx_t_17 = __pyx_v_k;
    __pyx_t_14 = -1;
    if (__pyx_t_17 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_trans_ll_view1.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 260, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_trans_ll_view1.data + __pyx_t_17 * __pyx_v_trans_ll_view1.strides[0]) )) = ((*((double *) ( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_13 * __pyx_v_fwd.strides[0]) ))) + (*((double *) ( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_16 * __pyx_v_bwd.strides[0]) ))));
  }
+261:     tot_ll = logsumexp(trans_ll_view1)
  __pyx_v_tot_ll = __pyx_f_8hapsburg_5cfunc_logsumexp(__pyx_v_trans_ll_view1);
 262: 
 263:     #############################
 264:     ### Do the Backward Algorithm
 265:     ## last0-State Posterior
+266:     post_view[n_loci-1] = post_view[n_loci-1] + bwd[0] - tot_ll
  __pyx_t_16 = (__pyx_v_n_loci - 1);
  __pyx_t_9 = -1;
  if (__pyx_t_16 < 0) {
    __pyx_t_9 = 0;
  } else if (unlikely(__pyx_t_16 >= __pyx_v_post_view.shape[0])) __pyx_t_9 = 0;
  if (unlikely(__pyx_t_9 != -1)) {
    __Pyx_RaiseBufferIndexError(__pyx_t_9);
    __PYX_ERR(0, 266, __pyx_L1_error)
  }
  __pyx_t_13 = 0;
  __pyx_t_9 = -1;
  if (__pyx_t_13 < 0) {
    __pyx_t_9 = 0;
  } else if (unlikely(__pyx_t_13 >= __pyx_v_bwd.shape[0])) __pyx_t_9 = 0;
  if (unlikely(__pyx_t_9 != -1)) {
    __Pyx_RaiseBufferIndexError(__pyx_t_9);
    __PYX_ERR(0, 266, __pyx_L1_error)
  }
  __pyx_t_17 = (__pyx_v_n_loci - 1);
  __pyx_t_9 = -1;
  if (__pyx_t_17 < 0) {
    __pyx_t_9 = 0;
  } else if (unlikely(__pyx_t_17 >= __pyx_v_post_view.shape[0])) __pyx_t_9 = 0;
  if (unlikely(__pyx_t_9 != -1)) {
    __Pyx_RaiseBufferIndexError(__pyx_t_9);
    __PYX_ERR(0, 266, __pyx_L1_error)
  }
  *((double *) ( /* dim=0 */ (__pyx_v_post_view.data + __pyx_t_17 * __pyx_v_post_view.strides[0]) )) = (((*((double *) ( /* dim=0 */ (__pyx_v_post_view.data + __pyx_t_16 * __pyx_v_post_view.strides[0]) ))) + (*((double *) ( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_13 * __pyx_v_bwd.strides[0]) )))) - __pyx_v_tot_ll);
 267: 
+268:     for i in range(n_loci-1, 0, -1):  # Run backward recursion
  for (__pyx_t_12 = (__pyx_v_n_loci - 1); __pyx_t_12 > 0; __pyx_t_12-=1) {
    __pyx_v_i = __pyx_t_12;
+269:       stay = log(t_mat[i, 1, 1] - t_mat[i, 1, 2])
    __pyx_t_13 = __pyx_v_i;
    __pyx_t_16 = 1;
    __pyx_t_17 = 1;
    __pyx_t_9 = -1;
    if (__pyx_t_13 < 0) {
      __pyx_t_9 = 0;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_t_mat.shape[0])) __pyx_t_9 = 0;
    if (__pyx_t_16 < 0) {
      __pyx_t_9 = 1;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t_mat.shape[1])) __pyx_t_9 = 1;
    if (__pyx_t_17 < 0) {
      __pyx_t_9 = 2;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_t_mat.shape[2])) __pyx_t_9 = 2;
    if (unlikely(__pyx_t_9 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_9);
      __PYX_ERR(0, 269, __pyx_L1_error)
    }
    __pyx_t_15 = __pyx_v_i;
    __pyx_t_10 = 1;
    __pyx_t_8 = 2;
    __pyx_t_9 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_9 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t_mat.shape[0])) __pyx_t_9 = 0;
    if (__pyx_t_10 < 0) {
      __pyx_t_9 = 1;
    } else if (unlikely(__pyx_t_10 >= __pyx_v_t_mat.shape[1])) __pyx_t_9 = 1;
    if (__pyx_t_8 < 0) {
      __pyx_t_9 = 2;
    } else if (unlikely(__pyx_t_8 >= __pyx_v_t_mat.shape[2])) __pyx_t_9 = 2;
    if (unlikely(__pyx_t_9 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_9);
      __PYX_ERR(0, 269, __pyx_L1_error)
    }
    __pyx_v_stay = log(((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t_mat.data + __pyx_t_13 * __pyx_v_t_mat.strides[0]) ) + __pyx_t_16 * __pyx_v_t_mat.strides[1]) ) + __pyx_t_17 * __pyx_v_t_mat.strides[2]) ))) - (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t_mat.data + __pyx_t_15 * __pyx_v_t_mat.strides[0]) ) + __pyx_t_10 * __pyx_v_t_mat.strides[1]) ) + __pyx_t_8 * __pyx_v_t_mat.strides[2]) )))));
 270: 
+271:       for k in range(1, n_states): # Calculate logsum of ROH states:
    __pyx_t_9 = __pyx_v_n_states;
    __pyx_t_11 = __pyx_t_9;
    for (__pyx_t_19 = 1; __pyx_t_19 < __pyx_t_11; __pyx_t_19+=1) {
      __pyx_v_k = __pyx_t_19;
+272:           trans_ll_view[k-1] = bwd[k] + e_mat0[k, i]
      __pyx_t_8 = __pyx_v_k;
      __pyx_t_14 = -1;
      if (__pyx_t_8 < 0) {
        __pyx_t_14 = 0;
      } else if (unlikely(__pyx_t_8 >= __pyx_v_bwd.shape[0])) __pyx_t_14 = 0;
      if (unlikely(__pyx_t_14 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_14);
        __PYX_ERR(0, 272, __pyx_L1_error)
      }
      __pyx_t_10 = __pyx_v_k;
      __pyx_t_15 = __pyx_v_i;
      __pyx_t_14 = -1;
      if (__pyx_t_10 < 0) {
        __pyx_t_14 = 0;
      } else if (unlikely(__pyx_t_10 >= __pyx_v_e_mat0.shape[0])) __pyx_t_14 = 0;
      if (__pyx_t_15 < 0) {
        __pyx_t_14 = 1;
      } else if (unlikely(__pyx_t_15 >= __pyx_v_e_mat0.shape[1])) __pyx_t_14 = 1;
      if (unlikely(__pyx_t_14 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_14);
        __PYX_ERR(0, 272, __pyx_L1_error)
      }
      __pyx_t_17 = (__pyx_v_k - 1);
      __pyx_t_14 = -1;
      if (__pyx_t_17 < 0) {
        __pyx_t_14 = 0;
      } else if (unlikely(__pyx_t_17 >= __pyx_v_trans_ll_view.shape[0])) __pyx_t_14 = 0;
      if (unlikely(__pyx_t_14 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_14);
        __PYX_ERR(0, 272, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_trans_ll_view.data + __pyx_t_17 * __pyx_v_trans_ll_view.strides[0]) )) = ((*((double *) ( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_8 * __pyx_v_bwd.strides[0]) ))) + (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat0.data + __pyx_t_10 * __pyx_v_e_mat0.strides[0]) ) + __pyx_t_15 * __pyx_v_e_mat0.strides[1]) ))));
    }
+273:       f_l = logsumexp(trans_ll_view) # Logsum of ROH States
    __pyx_v_f_l = __pyx_f_8hapsburg_5cfunc_logsumexp(__pyx_v_trans_ll_view);
 274: 
 275:       # Do the 0 State:
+276:       two_v_view[0] = bwd[0] + t0[i, 0, 0] + e_mat0[0, i]   # Staying in 0 State
    __pyx_t_15 = 0;
    __pyx_t_9 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_9 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_bwd.shape[0])) __pyx_t_9 = 0;
    if (unlikely(__pyx_t_9 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_9);
      __PYX_ERR(0, 276, __pyx_L1_error)
    }
    __pyx_t_10 = __pyx_v_i;
    __pyx_t_8 = 0;
    __pyx_t_17 = 0;
    __pyx_t_9 = -1;
    if (__pyx_t_10 < 0) {
      __pyx_t_9 = 0;
    } else if (unlikely(__pyx_t_10 >= __pyx_v_t0.shape[0])) __pyx_t_9 = 0;
    if (__pyx_t_8 < 0) {
      __pyx_t_9 = 1;
    } else if (unlikely(__pyx_t_8 >= __pyx_v_t0.shape[1])) __pyx_t_9 = 1;
    if (__pyx_t_17 < 0) {
      __pyx_t_9 = 2;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_t0.shape[2])) __pyx_t_9 = 2;
    if (unlikely(__pyx_t_9 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_9);
      __PYX_ERR(0, 276, __pyx_L1_error)
    }
    __pyx_t_16 = 0;
    __pyx_t_13 = __pyx_v_i;
    __pyx_t_9 = -1;
    if (__pyx_t_16 < 0) {
      __pyx_t_9 = 0;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_e_mat0.shape[0])) __pyx_t_9 = 0;
    if (__pyx_t_13 < 0) {
      __pyx_t_9 = 1;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_e_mat0.shape[1])) __pyx_t_9 = 1;
    if (unlikely(__pyx_t_9 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_9);
      __PYX_ERR(0, 276, __pyx_L1_error)
    }
    __pyx_t_21 = 0;
    __pyx_t_9 = -1;
    if (__pyx_t_21 < 0) {
      __pyx_t_9 = 0;
    } else if (unlikely(__pyx_t_21 >= __pyx_v_two_v_view.shape[0])) __pyx_t_9 = 0;
    if (unlikely(__pyx_t_9 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_9);
      __PYX_ERR(0, 276, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_two_v_view.data + __pyx_t_21 * __pyx_v_two_v_view.strides[0]) )) = (((*((double *) ( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_15 * __pyx_v_bwd.strides[0]) ))) + (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t0.data + __pyx_t_10 * __pyx_v_t0.strides[0]) ) + __pyx_t_8 * __pyx_v_t0.strides[1]) ) + __pyx_t_17 * __pyx_v_t0.strides[2]) )))) + (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat0.data + __pyx_t_16 * __pyx_v_e_mat0.strides[0]) ) + __pyx_t_13 * __pyx_v_e_mat0.strides[1]) ))));
+277:       two_v_view[1] = f_l + t0[i, 0, 1]                         # Going into 0 State
    __pyx_t_13 = __pyx_v_i;
    __pyx_t_16 = 0;
    __pyx_t_17 = 1;
    __pyx_t_9 = -1;
    if (__pyx_t_13 < 0) {
      __pyx_t_9 = 0;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_t0.shape[0])) __pyx_t_9 = 0;
    if (__pyx_t_16 < 0) {
      __pyx_t_9 = 1;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t0.shape[1])) __pyx_t_9 = 1;
    if (__pyx_t_17 < 0) {
      __pyx_t_9 = 2;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_t0.shape[2])) __pyx_t_9 = 2;
    if (unlikely(__pyx_t_9 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_9);
      __PYX_ERR(0, 277, __pyx_L1_error)
    }
    __pyx_t_8 = 1;
    __pyx_t_9 = -1;
    if (__pyx_t_8 < 0) {
      __pyx_t_9 = 0;
    } else if (unlikely(__pyx_t_8 >= __pyx_v_two_v_view.shape[0])) __pyx_t_9 = 0;
    if (unlikely(__pyx_t_9 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_9);
      __PYX_ERR(0, 277, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_two_v_view.data + __pyx_t_8 * __pyx_v_two_v_view.strides[0]) )) = (__pyx_v_f_l + (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t0.data + __pyx_t_13 * __pyx_v_t0.strides[0]) ) + __pyx_t_16 * __pyx_v_t0.strides[1]) ) + __pyx_t_17 * __pyx_v_t0.strides[2]) ))));
+278:       tmp[0] = logsumexp(two_v_view)
    __pyx_t_17 = 0;
    __pyx_t_9 = -1;
    if (__pyx_t_17 < 0) {
      __pyx_t_9 = 0;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_tmp.shape[0])) __pyx_t_9 = 0;
    if (unlikely(__pyx_t_9 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_9);
      __PYX_ERR(0, 278, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_tmp.data + __pyx_t_17 * __pyx_v_tmp.strides[0]) )) = __pyx_f_8hapsburg_5cfunc_logsumexp(__pyx_v_two_v_view);
 279: 
 280:       ### Do the other states
 281:       # Preprocessing:
+282:       three_v_view[0] = e_mat0[0, i] + bwd[0] + t0[i, 1, 0]
    __pyx_t_17 = 0;
    __pyx_t_16 = __pyx_v_i;
    __pyx_t_9 = -1;
    if (__pyx_t_17 < 0) {
      __pyx_t_9 = 0;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_e_mat0.shape[0])) __pyx_t_9 = 0;
    if (__pyx_t_16 < 0) {
      __pyx_t_9 = 1;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_e_mat0.shape[1])) __pyx_t_9 = 1;
    if (unlikely(__pyx_t_9 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_9);
      __PYX_ERR(0, 282, __pyx_L1_error)
    }
    __pyx_t_13 = 0;
    __pyx_t_9 = -1;
    if (__pyx_t_13 < 0) {
      __pyx_t_9 = 0;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_bwd.shape[0])) __pyx_t_9 = 0;
    if (unlikely(__pyx_t_9 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_9);
      __PYX_ERR(0, 282, __pyx_L1_error)
    }
    __pyx_t_8 = __pyx_v_i;
    __pyx_t_10 = 1;
    __pyx_t_15 = 0;
    __pyx_t_9 = -1;
    if (__pyx_t_8 < 0) {
      __pyx_t_9 = 0;
    } else if (unlikely(__pyx_t_8 >= __pyx_v_t0.shape[0])) __pyx_t_9 = 0;
    if (__pyx_t_10 < 0) {
      __pyx_t_9 = 1;
    } else if (unlikely(__pyx_t_10 >= __pyx_v_t0.shape[1])) __pyx_t_9 = 1;
    if (__pyx_t_15 < 0) {
      __pyx_t_9 = 2;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t0.shape[2])) __pyx_t_9 = 2;
    if (unlikely(__pyx_t_9 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_9);
      __PYX_ERR(0, 282, __pyx_L1_error)
    }
    __pyx_t_21 = 0;
    __pyx_t_9 = -1;
    if (__pyx_t_21 < 0) {
      __pyx_t_9 = 0;
    } else if (unlikely(__pyx_t_21 >= __pyx_v_three_v_view.shape[0])) __pyx_t_9 = 0;
    if (unlikely(__pyx_t_9 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_9);
      __PYX_ERR(0, 282, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_three_v_view.data + __pyx_t_21 * __pyx_v_three_v_view.strides[0]) )) = (((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat0.data + __pyx_t_17 * __pyx_v_e_mat0.strides[0]) ) + __pyx_t_16 * __pyx_v_e_mat0.strides[1]) ))) + (*((double *) ( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_13 * __pyx_v_bwd.strides[0]) )))) + (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t0.data + __pyx_t_8 * __pyx_v_t0.strides[0]) ) + __pyx_t_10 * __pyx_v_t0.strides[1]) ) + __pyx_t_15 * __pyx_v_t0.strides[2]) ))));
+283:       three_v_view[1] = f_l + t0[i, 1, 2]    # Coming from other ROH State
    __pyx_t_15 = __pyx_v_i;
    __pyx_t_10 = 1;
    __pyx_t_8 = 2;
    __pyx_t_9 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_9 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t0.shape[0])) __pyx_t_9 = 0;
    if (__pyx_t_10 < 0) {
      __pyx_t_9 = 1;
    } else if (unlikely(__pyx_t_10 >= __pyx_v_t0.shape[1])) __pyx_t_9 = 1;
    if (__pyx_t_8 < 0) {
      __pyx_t_9 = 2;
    } else if (unlikely(__pyx_t_8 >= __pyx_v_t0.shape[2])) __pyx_t_9 = 2;
    if (unlikely(__pyx_t_9 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_9);
      __PYX_ERR(0, 283, __pyx_L1_error)
    }
    __pyx_t_13 = 1;
    __pyx_t_9 = -1;
    if (__pyx_t_13 < 0) {
      __pyx_t_9 = 0;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_three_v_view.shape[0])) __pyx_t_9 = 0;
    if (unlikely(__pyx_t_9 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_9);
      __PYX_ERR(0, 283, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_three_v_view.data + __pyx_t_13 * __pyx_v_three_v_view.strides[0]) )) = (__pyx_v_f_l + (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t0.data + __pyx_t_15 * __pyx_v_t0.strides[0]) ) + __pyx_t_10 * __pyx_v_t0.strides[1]) ) + __pyx_t_8 * __pyx_v_t0.strides[2]) ))));
 284: 
+285:       for j in range(1, n_states):  # Do the final run over all states
    __pyx_t_9 = __pyx_v_n_states;
    __pyx_t_11 = __pyx_t_9;
    for (__pyx_t_19 = 1; __pyx_t_19 < __pyx_t_11; __pyx_t_19+=1) {
      __pyx_v_j = __pyx_t_19;
+286:         three_v_view[2] = e_mat0[j, i] + bwd[j] +  stay
      __pyx_t_8 = __pyx_v_j;
      __pyx_t_10 = __pyx_v_i;
      __pyx_t_14 = -1;
      if (__pyx_t_8 < 0) {
        __pyx_t_14 = 0;
      } else if (unlikely(__pyx_t_8 >= __pyx_v_e_mat0.shape[0])) __pyx_t_14 = 0;
      if (__pyx_t_10 < 0) {
        __pyx_t_14 = 1;
      } else if (unlikely(__pyx_t_10 >= __pyx_v_e_mat0.shape[1])) __pyx_t_14 = 1;
      if (unlikely(__pyx_t_14 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_14);
        __PYX_ERR(0, 286, __pyx_L1_error)
      }
      __pyx_t_15 = __pyx_v_j;
      __pyx_t_14 = -1;
      if (__pyx_t_15 < 0) {
        __pyx_t_14 = 0;
      } else if (unlikely(__pyx_t_15 >= __pyx_v_bwd.shape[0])) __pyx_t_14 = 0;
      if (unlikely(__pyx_t_14 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_14);
        __PYX_ERR(0, 286, __pyx_L1_error)
      }
      __pyx_t_13 = 2;
      __pyx_t_14 = -1;
      if (__pyx_t_13 < 0) {
        __pyx_t_14 = 0;
      } else if (unlikely(__pyx_t_13 >= __pyx_v_three_v_view.shape[0])) __pyx_t_14 = 0;
      if (unlikely(__pyx_t_14 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_14);
        __PYX_ERR(0, 286, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_three_v_view.data + __pyx_t_13 * __pyx_v_three_v_view.strides[0]) )) = (((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat0.data + __pyx_t_8 * __pyx_v_e_mat0.strides[0]) ) + __pyx_t_10 * __pyx_v_e_mat0.strides[1]) ))) + (*((double *) ( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_15 * __pyx_v_bwd.strides[0]) )))) + __pyx_v_stay);
+287:         tmp[j] = logsumexp(three_v_view)  # Fill in the backward Probability
      __pyx_t_15 = __pyx_v_j;
      __pyx_t_14 = -1;
      if (__pyx_t_15 < 0) {
        __pyx_t_14 = 0;
      } else if (unlikely(__pyx_t_15 >= __pyx_v_tmp.shape[0])) __pyx_t_14 = 0;
      if (unlikely(__pyx_t_14 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_14);
        __PYX_ERR(0, 287, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_tmp.data + __pyx_t_15 * __pyx_v_tmp.strides[0]) )) = __pyx_f_8hapsburg_5cfunc_logsumexp(__pyx_v_three_v_view);
    }
 288: 
 289:       ### Make tmp new bwd vec:
+290:       for j in range(0, n_states):
    __pyx_t_9 = __pyx_v_n_states;
    __pyx_t_11 = __pyx_t_9;
    for (__pyx_t_19 = 0; __pyx_t_19 < __pyx_t_11; __pyx_t_19+=1) {
      __pyx_v_j = __pyx_t_19;
+291:         bwd[j] = tmp[j]
      __pyx_t_15 = __pyx_v_j;
      __pyx_t_14 = -1;
      if (__pyx_t_15 < 0) {
        __pyx_t_14 = 0;
      } else if (unlikely(__pyx_t_15 >= __pyx_v_tmp.shape[0])) __pyx_t_14 = 0;
      if (unlikely(__pyx_t_14 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_14);
        __PYX_ERR(0, 291, __pyx_L1_error)
      }
      __pyx_t_10 = __pyx_v_j;
      __pyx_t_14 = -1;
      if (__pyx_t_10 < 0) {
        __pyx_t_14 = 0;
      } else if (unlikely(__pyx_t_10 >= __pyx_v_bwd.shape[0])) __pyx_t_14 = 0;
      if (unlikely(__pyx_t_14 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_14);
        __PYX_ERR(0, 291, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_10 * __pyx_v_bwd.strides[0]) )) = (*((double *) ( /* dim=0 */ (__pyx_v_tmp.data + __pyx_t_15 * __pyx_v_tmp.strides[0]) )));
    }
 292: 
 293:       ### Finalize the 0 Posterior
+294:       post_view[i-1] = post_view[i-1] + bwd[0] - tot_ll
    __pyx_t_15 = (__pyx_v_i - 1);
    __pyx_t_9 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_9 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_post_view.shape[0])) __pyx_t_9 = 0;
    if (unlikely(__pyx_t_9 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_9);
      __PYX_ERR(0, 294, __pyx_L1_error)
    }
    __pyx_t_10 = 0;
    __pyx_t_9 = -1;
    if (__pyx_t_10 < 0) {
      __pyx_t_9 = 0;
    } else if (unlikely(__pyx_t_10 >= __pyx_v_bwd.shape[0])) __pyx_t_9 = 0;
    if (unlikely(__pyx_t_9 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_9);
      __PYX_ERR(0, 294, __pyx_L1_error)
    }
    __pyx_t_8 = (__pyx_v_i - 1);
    __pyx_t_9 = -1;
    if (__pyx_t_8 < 0) {
      __pyx_t_9 = 0;
    } else if (unlikely(__pyx_t_8 >= __pyx_v_post_view.shape[0])) __pyx_t_9 = 0;
    if (unlikely(__pyx_t_9 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_9);
      __PYX_ERR(0, 294, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_post_view.data + __pyx_t_8 * __pyx_v_post_view.strides[0]) )) = (((*((double *) ( /* dim=0 */ (__pyx_v_post_view.data + __pyx_t_15 * __pyx_v_post_view.strides[0]) ))) + (*((double *) ( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_10 * __pyx_v_bwd.strides[0]) )))) - __pyx_v_tot_ll);
  }
 295: 
+296:     post = np.exp(post) # Go to normal space
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 296, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_exp); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 296, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_1))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_1, function);
    }
  }
  __pyx_t_2 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_3, __pyx_v_post) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_v_post);
  __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 296, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF_SET(__pyx_v_post, __pyx_t_2);
  __pyx_t_2 = 0;
 297: 
+298:     if output:
  __pyx_t_22 = __Pyx_PyObject_IsTrue(__pyx_v_output); if (unlikely(__pyx_t_22 < 0)) __PYX_ERR(0, 298, __pyx_L1_error)
  if (__pyx_t_22) {
/* … */
  }
+299:         print(f"Total Log likelihood: {tot_ll: .3f}")
    __pyx_t_2 = PyFloat_FromDouble(__pyx_v_tot_ll); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 299, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_1 = __Pyx_PyObject_Format(__pyx_t_2, __pyx_kp_u_3f); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 299, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Total_Log_likelihood, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 299, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 299, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+300:         print_memory_usage()   ## For MEMORY_BENCH
    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_print_memory_usage); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 300, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_3 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
      __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
      if (likely(__pyx_t_3)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
        __Pyx_INCREF(__pyx_t_3);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_2, function);
      }
    }
    __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2);
    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 300, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 301: 
+302:     if full==False:
  __pyx_t_1 = PyObject_RichCompare(__pyx_v_full, Py_False, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 302, __pyx_L1_error)
  __pyx_t_22 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_22 < 0)) __PYX_ERR(0, 302, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (__pyx_t_22) {
/* … */
  }
+303:       return post[None,:]  # For "fake" axis
    __Pyx_XDECREF(__pyx_r);
    __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_post, __pyx_tuple__9); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 303, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_r = __pyx_t_1;
    __pyx_t_1 = 0;
    goto __pyx_L0;
/* … */
  __pyx_tuple__9 = PyTuple_Pack(2, Py_None, __pyx_slice__3); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(0, 303, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__9);
  __Pyx_GIVEREF(__pyx_tuple__9);
 304: 
+305:     elif full==True:   # Return everything
  __pyx_t_1 = PyObject_RichCompare(__pyx_v_full, Py_True, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 305, __pyx_L1_error)
  __pyx_t_22 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_22 < 0)) __PYX_ERR(0, 305, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (__pyx_t_22) {
/* … */
  }
+306:       return post[None,:], fwd0, bwd0, tot_ll
    __Pyx_XDECREF(__pyx_r);
    __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_post, __pyx_tuple__9); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 306, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_2 = PyFloat_FromDouble(__pyx_v_tot_ll); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 306, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_3 = PyTuple_New(4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 306, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_GIVEREF(__pyx_t_1);
    PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
    __Pyx_INCREF(__pyx_v_fwd0);
    __Pyx_GIVEREF(__pyx_v_fwd0);
    PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_fwd0);
    __Pyx_INCREF(__pyx_v_bwd0);
    __Pyx_GIVEREF(__pyx_v_bwd0);
    PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_v_bwd0);
    __Pyx_GIVEREF(__pyx_t_2);
    PyTuple_SET_ITEM(__pyx_t_3, 3, __pyx_t_2);
    __pyx_t_1 = 0;
    __pyx_t_2 = 0;
    __pyx_r = __pyx_t_3;
    __pyx_t_3 = 0;
    goto __pyx_L0;
 307: 
 308: 
 309: 
 310: 
 311: 
 312: 
+313: def fwd_bkwd_scaled(double[:, :] e_mat, double[:, :, :] t_mat,
/* Python wrapper */
static PyObject *__pyx_pw_8hapsburg_5cfunc_7fwd_bkwd_scaled(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_8hapsburg_5cfunc_6fwd_bkwd_scaled[] = "\n    Uses speed-up specific for Genotype data (pooling same transition rates)\n    Uses rescaling of fwd and bwd calculations - NOT LOGSPACE\n    Saves and returns full posterior (WARNING: Need 3x as much memory as low mem version)\n    arrays for saving only last vectors. Saves only 0-state posterior long term.\n    e_mat: Emission probabilities: [k x l]  (normal space)\n    t_mat: Transition Matrix:  [l x 3 x 3]  (normal space)\n    in_val: Intitial probability of single symmetric state (normal space)\n    full: Boolean whether to return (post, fwd1, bwd1, tot_ll)\n    else only return post\n    output: Whether to print output useful for monitoring.\n    Otherwise only posterior mat [kxl] of post is returned\n    ";
static PyMethodDef __pyx_mdef_8hapsburg_5cfunc_7fwd_bkwd_scaled = {"fwd_bkwd_scaled", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_8hapsburg_5cfunc_7fwd_bkwd_scaled, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8hapsburg_5cfunc_6fwd_bkwd_scaled};
static PyObject *__pyx_pw_8hapsburg_5cfunc_7fwd_bkwd_scaled(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  __Pyx_memviewslice __pyx_v_e_mat = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_t_mat = { 0, 0, { 0 }, { 0 }, { 0 } };
  double __pyx_v_in_val;
  PyObject *__pyx_v_full = 0;
  PyObject *__pyx_v_output = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("fwd_bkwd_scaled (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_e_mat,&__pyx_n_s_t_mat,&__pyx_n_s_in_val,&__pyx_n_s_full,&__pyx_n_s_output,0};
    PyObject* values[5] = {0,0,0,0,0};
/* … */
  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_8hapsburg_5cfunc_6fwd_bkwd_scaled(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_e_mat, __Pyx_memviewslice __pyx_v_t_mat, double __pyx_v_in_val, PyObject *__pyx_v_full, PyObject *__pyx_v_output) {
  int __pyx_v_n_states;
  int __pyx_v_n_loci;
  Py_ssize_t __pyx_v_i;
  Py_ssize_t __pyx_v_j;
  Py_ssize_t __pyx_v_k;
  double __pyx_v_stay;
  double __pyx_v_x1;
  double __pyx_v_x2;
  double __pyx_v_x3;
  PyObject *__pyx_v_post = NULL;
  PyObject *__pyx_v_c = NULL;
  __Pyx_memviewslice __pyx_v_c_view = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_temp = NULL;
  __Pyx_memviewslice __pyx_v_temp_v = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_temp1 = NULL;
  __Pyx_memviewslice __pyx_v_temp1_v = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_t = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_fwd1 = NULL;
  __Pyx_memviewslice __pyx_v_fwd = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_bwd1 = NULL;
  __Pyx_memviewslice __pyx_v_bwd = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_f_l = NULL;
  PyObject *__pyx_v_tot_ll = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("fwd_bkwd_scaled", 0);
/* … */
  /* 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_XDEC_MEMVIEW(&__pyx_t_6, 1);
  __Pyx_XDECREF(__pyx_t_24);
  __Pyx_AddTraceback("hapsburg.cfunc.fwd_bkwd_scaled", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_post);
  __Pyx_XDECREF(__pyx_v_c);
  __PYX_XDEC_MEMVIEW(&__pyx_v_c_view, 1);
  __Pyx_XDECREF(__pyx_v_temp);
  __PYX_XDEC_MEMVIEW(&__pyx_v_temp_v, 1);
  __Pyx_XDECREF(__pyx_v_temp1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_temp1_v, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_t, 1);
  __Pyx_XDECREF(__pyx_v_fwd1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_fwd, 1);
  __Pyx_XDECREF(__pyx_v_bwd1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_bwd, 1);
  __Pyx_XDECREF(__pyx_v_f_l);
  __Pyx_XDECREF(__pyx_v_tot_ll);
  __PYX_XDEC_MEMVIEW(&__pyx_v_e_mat, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_t_mat, 1);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__34 = PyTuple_Pack(28, __pyx_n_s_e_mat, __pyx_n_s_t_mat, __pyx_n_s_in_val, __pyx_n_s_full, __pyx_n_s_output, __pyx_n_s_n_states, __pyx_n_s_n_loci, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_k, __pyx_n_s_stay, __pyx_n_s_x1, __pyx_n_s_x2, __pyx_n_s_x3, __pyx_n_s_post, __pyx_n_s_c, __pyx_n_s_c_view, __pyx_n_s_temp, __pyx_n_s_temp_v, __pyx_n_s_temp1, __pyx_n_s_temp1_v, __pyx_n_s_t, __pyx_n_s_fwd1, __pyx_n_s_fwd, __pyx_n_s_bwd1, __pyx_n_s_bwd, __pyx_n_s_f_l, __pyx_n_s_tot_ll); if (unlikely(!__pyx_tuple__34)) __PYX_ERR(0, 313, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__34);
  __Pyx_GIVEREF(__pyx_tuple__34);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_8hapsburg_5cfunc_7fwd_bkwd_scaled, NULL, __pyx_n_s_hapsburg_cfunc); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 313, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_fwd_bkwd_scaled, __pyx_t_2) < 0) __PYX_ERR(0, 313, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__35 = (PyObject*)__Pyx_PyCode_New(5, 0, 28, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__34, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_hapsburg_cfunc_pyx, __pyx_n_s_fwd_bkwd_scaled, 313, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__35)) __PYX_ERR(0, 313, __pyx_L1_error)
+314:                     double in_val = 1e-4, full=False, output=True):
    values[3] = ((PyObject *)Py_False);
    values[4] = ((PyObject *)Py_True);
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        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_e_mat)) != 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_t_mat)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("fwd_bkwd_scaled", 0, 2, 5, 1); __PYX_ERR(0, 313, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_in_val);
          if (value) { values[2] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_full);
          if (value) { values[3] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  4:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_output);
          if (value) { values[4] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "fwd_bkwd_scaled") < 0)) __PYX_ERR(0, 313, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        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);
        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_e_mat = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(values[0], PyBUF_WRITABLE); if (unlikely(!__pyx_v_e_mat.memview)) __PYX_ERR(0, 313, __pyx_L3_error)
    __pyx_v_t_mat = __Pyx_PyObject_to_MemoryviewSlice_dsdsds_double(values[1], PyBUF_WRITABLE); if (unlikely(!__pyx_v_t_mat.memview)) __PYX_ERR(0, 313, __pyx_L3_error)
    if (values[2]) {
      __pyx_v_in_val = __pyx_PyFloat_AsDouble(values[2]); if (unlikely((__pyx_v_in_val == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 314, __pyx_L3_error)
    } else {
      __pyx_v_in_val = ((double)1e-4);
    }
    __pyx_v_full = values[3];
    __pyx_v_output = values[4];
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("fwd_bkwd_scaled", 0, 2, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 313, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("hapsburg.cfunc.fwd_bkwd_scaled", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_8hapsburg_5cfunc_6fwd_bkwd_scaled(__pyx_self, __pyx_v_e_mat, __pyx_v_t_mat, __pyx_v_in_val, __pyx_v_full, __pyx_v_output);
 315:     """
 316:     Uses speed-up specific for Genotype data (pooling same transition rates)
 317:     Uses rescaling of fwd and bwd calculations - NOT LOGSPACE
 318:     Saves and returns full posterior (WARNING: Need 3x as much memory as low mem version)
 319:     arrays for saving only last vectors. Saves only 0-state posterior long term.
 320:     e_mat: Emission probabilities: [k x l]  (normal space)
 321:     t_mat: Transition Matrix:  [l x 3 x 3]  (normal space)
 322:     in_val: Intitial probability of single symmetric state (normal space)
 323:     full: Boolean whether to return (post, fwd1, bwd1, tot_ll)
 324:     else only return post
 325:     output: Whether to print output useful for monitoring.
 326:     Otherwise only posterior mat [kxl] of post is returned
 327:     """
+328:     cdef int n_states = e_mat.shape[0]
  __pyx_v_n_states = (__pyx_v_e_mat.shape[0]);
+329:     cdef int n_loci = e_mat.shape[1]
  __pyx_v_n_loci = (__pyx_v_e_mat.shape[1]);
 330:     cdef Py_ssize_t i, j, k    # The Array and Iteration Indices
 331:     cdef double stay           # The Probablility of Staying
 332:     cdef double x1, x2, x3     # Place holder variables [make code readable]
 333: 
 334:     # Initialize Posterior and Transition Probabilities
+335:     post = np.empty([n_states, n_loci], dtype=DTYPE)
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 335, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 335, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_n_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 335, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_n_loci); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 335, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = PyList_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 335, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_1);
  PyList_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
  __Pyx_GIVEREF(__pyx_t_3);
  PyList_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
  __pyx_t_1 = 0;
  __pyx_t_3 = 0;
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 335, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
  __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 335, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 335, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_1) < 0) __PYX_ERR(0, 335, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 335, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_v_post = __pyx_t_1;
  __pyx_t_1 = 0;
 336: 
+337:     c = np.empty(n_loci, dtype=DTYPE) # Array of normalization constants
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 337, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 337, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_n_loci); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 337, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 337, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
  __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 337, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 337, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_2) < 0) __PYX_ERR(0, 337, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 337, __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_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_c = __pyx_t_2;
  __pyx_t_2 = 0;
+338:     cdef double[:] c_view = c
  __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_c, PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 338, __pyx_L1_error)
  __pyx_v_c_view = __pyx_t_5;
  __pyx_t_5.memview = NULL;
  __pyx_t_5.data = NULL;
 339: 
+340:     temp = np.empty(n_states, dtype=DTYPE) # l Array for calculations
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 340, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 340, __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_n_states); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 340, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 340, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_2);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
  __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 340, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 340, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_4) < 0) __PYX_ERR(0, 340, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 340, __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_temp = __pyx_t_4;
  __pyx_t_4 = 0;
+341:     cdef double[:] temp_v = temp
  __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_temp, PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 341, __pyx_L1_error)
  __pyx_v_temp_v = __pyx_t_5;
  __pyx_t_5.memview = NULL;
  __pyx_t_5.data = NULL;
 342: 
+343:     temp1 = np.empty(n_states-1, dtype=DTYPE) # l-1 Array for calculatons
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 343, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 343, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyInt_From_long((__pyx_v_n_states - 1)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 343, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 343, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
  __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 343, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 343, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_1) < 0) __PYX_ERR(0, 343, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 343, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_v_temp1 = __pyx_t_1;
  __pyx_t_1 = 0;
+344:     cdef double[:] temp1_v = temp1
  __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_temp1, PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 344, __pyx_L1_error)
  __pyx_v_temp1_v = __pyx_t_5;
  __pyx_t_5.memview = NULL;
  __pyx_t_5.data = NULL;
 345: 
+346:     cdef double[:,:,:] t = t_mat   # C View of transition matrix
  __PYX_INC_MEMVIEW(&__pyx_v_t_mat, 0);
  __pyx_v_t = __pyx_v_t_mat;
 347: 
 348:     ### Initialize FWD BWD matrices with first and last entries filled
+349:     fwd1 = np.zeros((n_states, n_loci), dtype="float")
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 349, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_zeros); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 349, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_n_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 349, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_n_loci); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 349, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 349, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
  __Pyx_GIVEREF(__pyx_t_3);
  PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3);
  __pyx_t_1 = 0;
  __pyx_t_3 = 0;
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 349, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_2);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
  __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 349, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_n_u_float) < 0) __PYX_ERR(0, 349, __pyx_L1_error)
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 349, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_fwd1 = __pyx_t_1;
  __pyx_t_1 = 0;
+350:     fwd1[:, 0] = in_val  # Initial Probabilities
  __pyx_t_1 = PyFloat_FromDouble(__pyx_v_in_val); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 350, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (unlikely(PyObject_SetItem(__pyx_v_fwd1, __pyx_tuple__4, __pyx_t_1) < 0)) __PYX_ERR(0, 350, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+351:     fwd1[0, 0] = 1 - (n_states - 1) * in_val
  __pyx_t_1 = PyFloat_FromDouble((1.0 - ((__pyx_v_n_states - 1) * __pyx_v_in_val))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 351, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (unlikely(PyObject_SetItem(__pyx_v_fwd1, __pyx_tuple__5, __pyx_t_1) < 0)) __PYX_ERR(0, 351, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+352:     cdef double[:,:] fwd = fwd1
  __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(__pyx_v_fwd1, PyBUF_WRITABLE); if (unlikely(!__pyx_t_6.memview)) __PYX_ERR(0, 352, __pyx_L1_error)
  __pyx_v_fwd = __pyx_t_6;
  __pyx_t_6.memview = NULL;
  __pyx_t_6.data = NULL;
 353: 
+354:     c_view[0] = 1 # Set the first normalization constant
  __pyx_t_7 = 0;
  __pyx_t_8 = -1;
  if (__pyx_t_7 < 0) {
    __pyx_t_8 = 0;
  } else if (unlikely(__pyx_t_7 >= __pyx_v_c_view.shape[0])) __pyx_t_8 = 0;
  if (unlikely(__pyx_t_8 != -1)) {
    __Pyx_RaiseBufferIndexError(__pyx_t_8);
    __PYX_ERR(0, 354, __pyx_L1_error)
  }
  *((double *) ( /* dim=0 */ (__pyx_v_c_view.data + __pyx_t_7 * __pyx_v_c_view.strides[0]) )) = 1.0;
 355: 
+356:     bwd1 = np.zeros((n_states, n_loci), dtype="float")
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 356, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_zeros); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 356, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_n_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 356, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_n_loci); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 356, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 356, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
  __Pyx_GIVEREF(__pyx_t_3);
  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
  __pyx_t_1 = 0;
  __pyx_t_3 = 0;
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 356, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
  __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 356, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_n_u_float) < 0) __PYX_ERR(0, 356, __pyx_L1_error)
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 356, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_v_bwd1 = __pyx_t_1;
  __pyx_t_1 = 0;
+357:     bwd1[:, -1] = 1 # The initial values for the backward pass
  if (unlikely(PyObject_SetItem(__pyx_v_bwd1, __pyx_tuple__6, __pyx_int_1) < 0)) __PYX_ERR(0, 357, __pyx_L1_error)
 358:     #bwd1[0, -1] = 1 - (n_states - 1) * in_val
+359:     cdef double[:,:] bwd = bwd1
  __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(__pyx_v_bwd1, PyBUF_WRITABLE); if (unlikely(!__pyx_t_6.memview)) __PYX_ERR(0, 359, __pyx_L1_error)
  __pyx_v_bwd = __pyx_t_6;
  __pyx_t_6.memview = NULL;
  __pyx_t_6.data = NULL;
 360: 
 361:     #############################
 362:     ### Do the Forward Algorithm
+363:     for i in range(1, n_loci):  # Run forward recursion
  __pyx_t_8 = __pyx_v_n_loci;
  __pyx_t_9 = __pyx_t_8;
  for (__pyx_t_10 = 1; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
    __pyx_v_i = __pyx_t_10;
+364:         stay = t[i, 1, 1] - t[i, 1, 2]  # Do the log of the Stay term
    __pyx_t_7 = __pyx_v_i;
    __pyx_t_11 = 1;
    __pyx_t_12 = 1;
    __pyx_t_13 = -1;
    if (__pyx_t_7 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_7 >= __pyx_v_t.shape[0])) __pyx_t_13 = 0;
    if (__pyx_t_11 < 0) {
      __pyx_t_13 = 1;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_t.shape[1])) __pyx_t_13 = 1;
    if (__pyx_t_12 < 0) {
      __pyx_t_13 = 2;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_t.shape[2])) __pyx_t_13 = 2;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 364, __pyx_L1_error)
    }
    __pyx_t_14 = __pyx_v_i;
    __pyx_t_15 = 1;
    __pyx_t_16 = 2;
    __pyx_t_13 = -1;
    if (__pyx_t_14 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_t.shape[0])) __pyx_t_13 = 0;
    if (__pyx_t_15 < 0) {
      __pyx_t_13 = 1;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t.shape[1])) __pyx_t_13 = 1;
    if (__pyx_t_16 < 0) {
      __pyx_t_13 = 2;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t.shape[2])) __pyx_t_13 = 2;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 364, __pyx_L1_error)
    }
    __pyx_v_stay = ((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_7 * __pyx_v_t.strides[0]) ) + __pyx_t_11 * __pyx_v_t.strides[1]) ) + __pyx_t_12 * __pyx_v_t.strides[2]) ))) - (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_14 * __pyx_v_t.strides[0]) ) + __pyx_t_15 * __pyx_v_t.strides[1]) ) + __pyx_t_16 * __pyx_v_t.strides[2]) ))));
 365: 
 366:         #for k in range(1, n_states): # Calculate Sum of ROH states. 
+367:         f_l = 1 - fwd[0, i-1]  ### Assume they are normalized!!!
    __pyx_t_16 = 0;
    __pyx_t_15 = (__pyx_v_i - 1);
    __pyx_t_13 = -1;
    if (__pyx_t_16 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_fwd.shape[0])) __pyx_t_13 = 0;
    if (__pyx_t_15 < 0) {
      __pyx_t_13 = 1;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_fwd.shape[1])) __pyx_t_13 = 1;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 367, __pyx_L1_error)
    }
    __pyx_t_1 = PyFloat_FromDouble((1.0 - (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_16 * __pyx_v_fwd.strides[0]) ) + __pyx_t_15 * __pyx_v_fwd.strides[1]) ))))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 367, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_XDECREF_SET(__pyx_v_f_l, __pyx_t_1);
    __pyx_t_1 = 0;
 368: 
 369:         ### Do the 0 State:
+370:         x1 = fwd[0, i - 1] * t[i, 0, 0]    # Staying in 0 State
    __pyx_t_15 = 0;
    __pyx_t_16 = (__pyx_v_i - 1);
    __pyx_t_13 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_fwd.shape[0])) __pyx_t_13 = 0;
    if (__pyx_t_16 < 0) {
      __pyx_t_13 = 1;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_fwd.shape[1])) __pyx_t_13 = 1;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 370, __pyx_L1_error)
    }
    __pyx_t_14 = __pyx_v_i;
    __pyx_t_12 = 0;
    __pyx_t_11 = 0;
    __pyx_t_13 = -1;
    if (__pyx_t_14 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_t.shape[0])) __pyx_t_13 = 0;
    if (__pyx_t_12 < 0) {
      __pyx_t_13 = 1;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_t.shape[1])) __pyx_t_13 = 1;
    if (__pyx_t_11 < 0) {
      __pyx_t_13 = 2;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_t.shape[2])) __pyx_t_13 = 2;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 370, __pyx_L1_error)
    }
    __pyx_v_x1 = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_15 * __pyx_v_fwd.strides[0]) ) + __pyx_t_16 * __pyx_v_fwd.strides[1]) ))) * (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_14 * __pyx_v_t.strides[0]) ) + __pyx_t_12 * __pyx_v_t.strides[1]) ) + __pyx_t_11 * __pyx_v_t.strides[2]) ))));
+371:         x2 = f_l * t[i, 1, 0]               # Going into 0 State from any other
    __pyx_t_11 = __pyx_v_i;
    __pyx_t_12 = 1;
    __pyx_t_14 = 0;
    __pyx_t_13 = -1;
    if (__pyx_t_11 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_t.shape[0])) __pyx_t_13 = 0;
    if (__pyx_t_12 < 0) {
      __pyx_t_13 = 1;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_t.shape[1])) __pyx_t_13 = 1;
    if (__pyx_t_14 < 0) {
      __pyx_t_13 = 2;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_t.shape[2])) __pyx_t_13 = 2;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 371, __pyx_L1_error)
    }
    __pyx_t_1 = PyFloat_FromDouble((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_11 * __pyx_v_t.strides[0]) ) + __pyx_t_12 * __pyx_v_t.strides[1]) ) + __pyx_t_14 * __pyx_v_t.strides[2]) )))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 371, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_4 = PyNumber_Multiply(__pyx_v_f_l, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 371, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_17 = __pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_17 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 371, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_v_x2 = __pyx_t_17;
+372:         temp_v[0] = e_mat[0, i] * (x1 + x2) # Set the unnorm. 0 forward variable
    __pyx_t_14 = 0;
    __pyx_t_12 = __pyx_v_i;
    __pyx_t_13 = -1;
    if (__pyx_t_14 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_e_mat.shape[0])) __pyx_t_13 = 0;
    if (__pyx_t_12 < 0) {
      __pyx_t_13 = 1;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_e_mat.shape[1])) __pyx_t_13 = 1;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 372, __pyx_L1_error)
    }
    __pyx_t_11 = 0;
    __pyx_t_13 = -1;
    if (__pyx_t_11 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_temp_v.shape[0])) __pyx_t_13 = 0;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 372, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_temp_v.data + __pyx_t_11 * __pyx_v_temp_v.strides[0]) )) = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat.data + __pyx_t_14 * __pyx_v_e_mat.strides[0]) ) + __pyx_t_12 * __pyx_v_e_mat.strides[1]) ))) * (__pyx_v_x1 + __pyx_v_x2));
 373: 
 374:         ### Do the other states
 375:         # Preprocessing:
+376:         x1 = fwd[0, i - 1] * t[i, 0, 1]   # Coming from 0 State
    __pyx_t_12 = 0;
    __pyx_t_14 = (__pyx_v_i - 1);
    __pyx_t_13 = -1;
    if (__pyx_t_12 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_fwd.shape[0])) __pyx_t_13 = 0;
    if (__pyx_t_14 < 0) {
      __pyx_t_13 = 1;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_fwd.shape[1])) __pyx_t_13 = 1;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 376, __pyx_L1_error)
    }
    __pyx_t_11 = __pyx_v_i;
    __pyx_t_16 = 0;
    __pyx_t_15 = 1;
    __pyx_t_13 = -1;
    if (__pyx_t_11 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_t.shape[0])) __pyx_t_13 = 0;
    if (__pyx_t_16 < 0) {
      __pyx_t_13 = 1;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t.shape[1])) __pyx_t_13 = 1;
    if (__pyx_t_15 < 0) {
      __pyx_t_13 = 2;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t.shape[2])) __pyx_t_13 = 2;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 376, __pyx_L1_error)
    }
    __pyx_v_x1 = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_12 * __pyx_v_fwd.strides[0]) ) + __pyx_t_14 * __pyx_v_fwd.strides[1]) ))) * (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_11 * __pyx_v_t.strides[0]) ) + __pyx_t_16 * __pyx_v_t.strides[1]) ) + __pyx_t_15 * __pyx_v_t.strides[2]) ))));
+377:         x2 = f_l * t[i, 1, 2]             # Coming from other ROH State
    __pyx_t_15 = __pyx_v_i;
    __pyx_t_16 = 1;
    __pyx_t_11 = 2;
    __pyx_t_13 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t.shape[0])) __pyx_t_13 = 0;
    if (__pyx_t_16 < 0) {
      __pyx_t_13 = 1;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t.shape[1])) __pyx_t_13 = 1;
    if (__pyx_t_11 < 0) {
      __pyx_t_13 = 2;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_t.shape[2])) __pyx_t_13 = 2;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 377, __pyx_L1_error)
    }
    __pyx_t_4 = PyFloat_FromDouble((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_15 * __pyx_v_t.strides[0]) ) + __pyx_t_16 * __pyx_v_t.strides[1]) ) + __pyx_t_11 * __pyx_v_t.strides[2]) )))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 377, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_1 = PyNumber_Multiply(__pyx_v_f_l, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 377, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_t_17 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_17 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 377, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_v_x2 = __pyx_t_17;
 378: 
+379:         for j in range(1, n_states):  # Do the final run over all states
    __pyx_t_13 = __pyx_v_n_states;
    __pyx_t_18 = __pyx_t_13;
    for (__pyx_t_19 = 1; __pyx_t_19 < __pyx_t_18; __pyx_t_19+=1) {
      __pyx_v_j = __pyx_t_19;
+380:             x3 = fwd[j, i-1] *  stay # Staying in state
      __pyx_t_11 = __pyx_v_j;
      __pyx_t_16 = (__pyx_v_i - 1);
      __pyx_t_20 = -1;
      if (__pyx_t_11 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_11 >= __pyx_v_fwd.shape[0])) __pyx_t_20 = 0;
      if (__pyx_t_16 < 0) {
        __pyx_t_20 = 1;
      } else if (unlikely(__pyx_t_16 >= __pyx_v_fwd.shape[1])) __pyx_t_20 = 1;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 380, __pyx_L1_error)
      }
      __pyx_v_x3 = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_11 * __pyx_v_fwd.strides[0]) ) + __pyx_t_16 * __pyx_v_fwd.strides[1]) ))) * __pyx_v_stay);
+381:             temp_v[j] = e_mat[j, i] * (x1 + x2 + x3)
      __pyx_t_16 = __pyx_v_j;
      __pyx_t_11 = __pyx_v_i;
      __pyx_t_20 = -1;
      if (__pyx_t_16 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_16 >= __pyx_v_e_mat.shape[0])) __pyx_t_20 = 0;
      if (__pyx_t_11 < 0) {
        __pyx_t_20 = 1;
      } else if (unlikely(__pyx_t_11 >= __pyx_v_e_mat.shape[1])) __pyx_t_20 = 1;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 381, __pyx_L1_error)
      }
      __pyx_t_15 = __pyx_v_j;
      __pyx_t_20 = -1;
      if (__pyx_t_15 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_15 >= __pyx_v_temp_v.shape[0])) __pyx_t_20 = 0;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 381, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_temp_v.data + __pyx_t_15 * __pyx_v_temp_v.strides[0]) )) = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat.data + __pyx_t_16 * __pyx_v_e_mat.strides[0]) ) + __pyx_t_11 * __pyx_v_e_mat.strides[1]) ))) * ((__pyx_v_x1 + __pyx_v_x2) + __pyx_v_x3));
    }
 382: 
 383:         ### Do the normalization
+384:         c_view[i] = sum_array(temp_v, n_states)
    __pyx_t_11 = __pyx_v_i;
    __pyx_t_13 = -1;
    if (__pyx_t_11 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_c_view.shape[0])) __pyx_t_13 = 0;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 384, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_c_view.data + __pyx_t_11 * __pyx_v_c_view.strides[0]) )) = __pyx_f_8hapsburg_5cfunc_sum_array(__pyx_v_temp_v, __pyx_v_n_states);
+385:         for j in range(n_states):
    __pyx_t_13 = __pyx_v_n_states;
    __pyx_t_18 = __pyx_t_13;
    for (__pyx_t_19 = 0; __pyx_t_19 < __pyx_t_18; __pyx_t_19+=1) {
      __pyx_v_j = __pyx_t_19;
+386:             fwd[j,i] = temp_v[j] / c_view[i] # Rescale to prob. distribution
      __pyx_t_11 = __pyx_v_j;
      __pyx_t_20 = -1;
      if (__pyx_t_11 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_11 >= __pyx_v_temp_v.shape[0])) __pyx_t_20 = 0;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 386, __pyx_L1_error)
      }
      __pyx_t_17 = (*((double *) ( /* dim=0 */ (__pyx_v_temp_v.data + __pyx_t_11 * __pyx_v_temp_v.strides[0]) )));
      __pyx_t_11 = __pyx_v_i;
      __pyx_t_20 = -1;
      if (__pyx_t_11 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_11 >= __pyx_v_c_view.shape[0])) __pyx_t_20 = 0;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 386, __pyx_L1_error)
      }
      __pyx_t_21 = (*((double *) ( /* dim=0 */ (__pyx_v_c_view.data + __pyx_t_11 * __pyx_v_c_view.strides[0]) )));
      if (unlikely(__pyx_t_21 == 0)) {
        PyErr_SetString(PyExc_ZeroDivisionError, "float division");
        __PYX_ERR(0, 386, __pyx_L1_error)
      }
      __pyx_t_11 = __pyx_v_j;
      __pyx_t_16 = __pyx_v_i;
      __pyx_t_20 = -1;
      if (__pyx_t_11 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_11 >= __pyx_v_fwd.shape[0])) __pyx_t_20 = 0;
      if (__pyx_t_16 < 0) {
        __pyx_t_20 = 1;
      } else if (unlikely(__pyx_t_16 >= __pyx_v_fwd.shape[1])) __pyx_t_20 = 1;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 386, __pyx_L1_error)
      }
      *((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_11 * __pyx_v_fwd.strides[0]) ) + __pyx_t_16 * __pyx_v_fwd.strides[1]) )) = (__pyx_t_17 / __pyx_t_21);
    }
  }
 387: 
 388:     #############################
 389:     ### Do the Backward Algorithm
+390:     for i in range(n_loci-1, 0, -1):  # Run backward recursion
  for (__pyx_t_10 = (__pyx_v_n_loci - 1); __pyx_t_10 > 0; __pyx_t_10-=1) {
    __pyx_v_i = __pyx_t_10;
+391:         stay = t[i, 1, 1] - t[i, 1, 2]
    __pyx_t_16 = __pyx_v_i;
    __pyx_t_11 = 1;
    __pyx_t_15 = 1;
    __pyx_t_8 = -1;
    if (__pyx_t_16 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t.shape[0])) __pyx_t_8 = 0;
    if (__pyx_t_11 < 0) {
      __pyx_t_8 = 1;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_t.shape[1])) __pyx_t_8 = 1;
    if (__pyx_t_15 < 0) {
      __pyx_t_8 = 2;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t.shape[2])) __pyx_t_8 = 2;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 391, __pyx_L1_error)
    }
    __pyx_t_14 = __pyx_v_i;
    __pyx_t_12 = 1;
    __pyx_t_7 = 2;
    __pyx_t_8 = -1;
    if (__pyx_t_14 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_t.shape[0])) __pyx_t_8 = 0;
    if (__pyx_t_12 < 0) {
      __pyx_t_8 = 1;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_t.shape[1])) __pyx_t_8 = 1;
    if (__pyx_t_7 < 0) {
      __pyx_t_8 = 2;
    } else if (unlikely(__pyx_t_7 >= __pyx_v_t.shape[2])) __pyx_t_8 = 2;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 391, __pyx_L1_error)
    }
    __pyx_v_stay = ((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_16 * __pyx_v_t.strides[0]) ) + __pyx_t_11 * __pyx_v_t.strides[1]) ) + __pyx_t_15 * __pyx_v_t.strides[2]) ))) - (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_14 * __pyx_v_t.strides[0]) ) + __pyx_t_12 * __pyx_v_t.strides[1]) ) + __pyx_t_7 * __pyx_v_t.strides[2]) ))));
 392: 
+393:         for k in range(1, n_states): # Calculate logsum of ROH states:
    __pyx_t_8 = __pyx_v_n_states;
    __pyx_t_9 = __pyx_t_8;
    for (__pyx_t_19 = 1; __pyx_t_19 < __pyx_t_9; __pyx_t_19+=1) {
      __pyx_v_k = __pyx_t_19;
+394:             temp1_v[k-1] = bwd[k, i] * e_mat[k, i]
      __pyx_t_7 = __pyx_v_k;
      __pyx_t_12 = __pyx_v_i;
      __pyx_t_13 = -1;
      if (__pyx_t_7 < 0) {
        __pyx_t_13 = 0;
      } else if (unlikely(__pyx_t_7 >= __pyx_v_bwd.shape[0])) __pyx_t_13 = 0;
      if (__pyx_t_12 < 0) {
        __pyx_t_13 = 1;
      } else if (unlikely(__pyx_t_12 >= __pyx_v_bwd.shape[1])) __pyx_t_13 = 1;
      if (unlikely(__pyx_t_13 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_13);
        __PYX_ERR(0, 394, __pyx_L1_error)
      }
      __pyx_t_14 = __pyx_v_k;
      __pyx_t_15 = __pyx_v_i;
      __pyx_t_13 = -1;
      if (__pyx_t_14 < 0) {
        __pyx_t_13 = 0;
      } else if (unlikely(__pyx_t_14 >= __pyx_v_e_mat.shape[0])) __pyx_t_13 = 0;
      if (__pyx_t_15 < 0) {
        __pyx_t_13 = 1;
      } else if (unlikely(__pyx_t_15 >= __pyx_v_e_mat.shape[1])) __pyx_t_13 = 1;
      if (unlikely(__pyx_t_13 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_13);
        __PYX_ERR(0, 394, __pyx_L1_error)
      }
      __pyx_t_11 = (__pyx_v_k - 1);
      __pyx_t_13 = -1;
      if (__pyx_t_11 < 0) {
        __pyx_t_13 = 0;
      } else if (unlikely(__pyx_t_11 >= __pyx_v_temp1_v.shape[0])) __pyx_t_13 = 0;
      if (unlikely(__pyx_t_13 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_13);
        __PYX_ERR(0, 394, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_temp1_v.data + __pyx_t_11 * __pyx_v_temp1_v.strides[0]) )) = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_7 * __pyx_v_bwd.strides[0]) ) + __pyx_t_12 * __pyx_v_bwd.strides[1]) ))) * (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat.data + __pyx_t_14 * __pyx_v_e_mat.strides[0]) ) + __pyx_t_15 * __pyx_v_e_mat.strides[1]) ))));
    }
+395:         f_l = sum_array(temp1_v, n_states-1) # Logsum of ROH States
    __pyx_t_1 = PyFloat_FromDouble(__pyx_f_8hapsburg_5cfunc_sum_array(__pyx_v_temp1_v, (__pyx_v_n_states - 1))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 395, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_XDECREF_SET(__pyx_v_f_l, __pyx_t_1);
    __pyx_t_1 = 0;
 396: 
 397:       # Do the 0 State:
+398:         x1 = bwd[0, i] * t[i, 0, 0] * e_mat[0, i]   # Staying in 0 State
    __pyx_t_15 = 0;
    __pyx_t_14 = __pyx_v_i;
    __pyx_t_8 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_bwd.shape[0])) __pyx_t_8 = 0;
    if (__pyx_t_14 < 0) {
      __pyx_t_8 = 1;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_bwd.shape[1])) __pyx_t_8 = 1;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 398, __pyx_L1_error)
    }
    __pyx_t_12 = __pyx_v_i;
    __pyx_t_7 = 0;
    __pyx_t_11 = 0;
    __pyx_t_8 = -1;
    if (__pyx_t_12 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_t.shape[0])) __pyx_t_8 = 0;
    if (__pyx_t_7 < 0) {
      __pyx_t_8 = 1;
    } else if (unlikely(__pyx_t_7 >= __pyx_v_t.shape[1])) __pyx_t_8 = 1;
    if (__pyx_t_11 < 0) {
      __pyx_t_8 = 2;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_t.shape[2])) __pyx_t_8 = 2;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 398, __pyx_L1_error)
    }
    __pyx_t_16 = 0;
    __pyx_t_22 = __pyx_v_i;
    __pyx_t_8 = -1;
    if (__pyx_t_16 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_e_mat.shape[0])) __pyx_t_8 = 0;
    if (__pyx_t_22 < 0) {
      __pyx_t_8 = 1;
    } else if (unlikely(__pyx_t_22 >= __pyx_v_e_mat.shape[1])) __pyx_t_8 = 1;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 398, __pyx_L1_error)
    }
    __pyx_v_x1 = (((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_15 * __pyx_v_bwd.strides[0]) ) + __pyx_t_14 * __pyx_v_bwd.strides[1]) ))) * (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_12 * __pyx_v_t.strides[0]) ) + __pyx_t_7 * __pyx_v_t.strides[1]) ) + __pyx_t_11 * __pyx_v_t.strides[2]) )))) * (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat.data + __pyx_t_16 * __pyx_v_e_mat.strides[0]) ) + __pyx_t_22 * __pyx_v_e_mat.strides[1]) ))));
+399:         x2 = f_l * t[i, 0, 1]                         # Going into 0 State
    __pyx_t_22 = __pyx_v_i;
    __pyx_t_16 = 0;
    __pyx_t_11 = 1;
    __pyx_t_8 = -1;
    if (__pyx_t_22 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_22 >= __pyx_v_t.shape[0])) __pyx_t_8 = 0;
    if (__pyx_t_16 < 0) {
      __pyx_t_8 = 1;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t.shape[1])) __pyx_t_8 = 1;
    if (__pyx_t_11 < 0) {
      __pyx_t_8 = 2;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_t.shape[2])) __pyx_t_8 = 2;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 399, __pyx_L1_error)
    }
    __pyx_t_1 = PyFloat_FromDouble((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_22 * __pyx_v_t.strides[0]) ) + __pyx_t_16 * __pyx_v_t.strides[1]) ) + __pyx_t_11 * __pyx_v_t.strides[2]) )))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 399, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_4 = PyNumber_Multiply(__pyx_v_f_l, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 399, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_21 = __pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_21 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 399, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_v_x2 = __pyx_t_21;
+400:         temp_v[0] = x1 + x2
    __pyx_t_11 = 0;
    __pyx_t_8 = -1;
    if (__pyx_t_11 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_temp_v.shape[0])) __pyx_t_8 = 0;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 400, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_temp_v.data + __pyx_t_11 * __pyx_v_temp_v.strides[0]) )) = (__pyx_v_x1 + __pyx_v_x2);
 401: 
 402:       ### Do the other states
 403:       # Preprocessing:
+404:         x1 = e_mat[0, i] * bwd[0, i] * t[i, 1, 0]
    __pyx_t_11 = 0;
    __pyx_t_16 = __pyx_v_i;
    __pyx_t_8 = -1;
    if (__pyx_t_11 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_e_mat.shape[0])) __pyx_t_8 = 0;
    if (__pyx_t_16 < 0) {
      __pyx_t_8 = 1;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_e_mat.shape[1])) __pyx_t_8 = 1;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 404, __pyx_L1_error)
    }
    __pyx_t_22 = 0;
    __pyx_t_7 = __pyx_v_i;
    __pyx_t_8 = -1;
    if (__pyx_t_22 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_22 >= __pyx_v_bwd.shape[0])) __pyx_t_8 = 0;
    if (__pyx_t_7 < 0) {
      __pyx_t_8 = 1;
    } else if (unlikely(__pyx_t_7 >= __pyx_v_bwd.shape[1])) __pyx_t_8 = 1;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 404, __pyx_L1_error)
    }
    __pyx_t_12 = __pyx_v_i;
    __pyx_t_14 = 1;
    __pyx_t_15 = 0;
    __pyx_t_8 = -1;
    if (__pyx_t_12 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_t.shape[0])) __pyx_t_8 = 0;
    if (__pyx_t_14 < 0) {
      __pyx_t_8 = 1;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_t.shape[1])) __pyx_t_8 = 1;
    if (__pyx_t_15 < 0) {
      __pyx_t_8 = 2;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t.shape[2])) __pyx_t_8 = 2;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 404, __pyx_L1_error)
    }
    __pyx_v_x1 = (((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat.data + __pyx_t_11 * __pyx_v_e_mat.strides[0]) ) + __pyx_t_16 * __pyx_v_e_mat.strides[1]) ))) * (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_22 * __pyx_v_bwd.strides[0]) ) + __pyx_t_7 * __pyx_v_bwd.strides[1]) )))) * (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_12 * __pyx_v_t.strides[0]) ) + __pyx_t_14 * __pyx_v_t.strides[1]) ) + __pyx_t_15 * __pyx_v_t.strides[2]) ))));
+405:         x2 = f_l * t[i, 1, 2]    # Coming from other ROH State
    __pyx_t_15 = __pyx_v_i;
    __pyx_t_14 = 1;
    __pyx_t_12 = 2;
    __pyx_t_8 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t.shape[0])) __pyx_t_8 = 0;
    if (__pyx_t_14 < 0) {
      __pyx_t_8 = 1;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_t.shape[1])) __pyx_t_8 = 1;
    if (__pyx_t_12 < 0) {
      __pyx_t_8 = 2;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_t.shape[2])) __pyx_t_8 = 2;
    if (unlikely(__pyx_t_8 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_8);
      __PYX_ERR(0, 405, __pyx_L1_error)
    }
    __pyx_t_4 = PyFloat_FromDouble((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_15 * __pyx_v_t.strides[0]) ) + __pyx_t_14 * __pyx_v_t.strides[1]) ) + __pyx_t_12 * __pyx_v_t.strides[2]) )))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 405, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_1 = PyNumber_Multiply(__pyx_v_f_l, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 405, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_t_21 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_21 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 405, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_v_x2 = __pyx_t_21;
 406: 
+407:         for j in range(1, n_states):  # Do the final run over all states
    __pyx_t_8 = __pyx_v_n_states;
    __pyx_t_9 = __pyx_t_8;
    for (__pyx_t_19 = 1; __pyx_t_19 < __pyx_t_9; __pyx_t_19+=1) {
      __pyx_v_j = __pyx_t_19;
+408:             x3 = e_mat[j, i] * bwd[j, i] *  stay
      __pyx_t_12 = __pyx_v_j;
      __pyx_t_14 = __pyx_v_i;
      __pyx_t_13 = -1;
      if (__pyx_t_12 < 0) {
        __pyx_t_13 = 0;
      } else if (unlikely(__pyx_t_12 >= __pyx_v_e_mat.shape[0])) __pyx_t_13 = 0;
      if (__pyx_t_14 < 0) {
        __pyx_t_13 = 1;
      } else if (unlikely(__pyx_t_14 >= __pyx_v_e_mat.shape[1])) __pyx_t_13 = 1;
      if (unlikely(__pyx_t_13 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_13);
        __PYX_ERR(0, 408, __pyx_L1_error)
      }
      __pyx_t_15 = __pyx_v_j;
      __pyx_t_7 = __pyx_v_i;
      __pyx_t_13 = -1;
      if (__pyx_t_15 < 0) {
        __pyx_t_13 = 0;
      } else if (unlikely(__pyx_t_15 >= __pyx_v_bwd.shape[0])) __pyx_t_13 = 0;
      if (__pyx_t_7 < 0) {
        __pyx_t_13 = 1;
      } else if (unlikely(__pyx_t_7 >= __pyx_v_bwd.shape[1])) __pyx_t_13 = 1;
      if (unlikely(__pyx_t_13 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_13);
        __PYX_ERR(0, 408, __pyx_L1_error)
      }
      __pyx_v_x3 = (((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat.data + __pyx_t_12 * __pyx_v_e_mat.strides[0]) ) + __pyx_t_14 * __pyx_v_e_mat.strides[1]) ))) * (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_15 * __pyx_v_bwd.strides[0]) ) + __pyx_t_7 * __pyx_v_bwd.strides[1]) )))) * __pyx_v_stay);
+409:             temp_v[j] = x1 + x2 + x3  # Fill in the backward Probability
      __pyx_t_7 = __pyx_v_j;
      __pyx_t_13 = -1;
      if (__pyx_t_7 < 0) {
        __pyx_t_13 = 0;
      } else if (unlikely(__pyx_t_7 >= __pyx_v_temp_v.shape[0])) __pyx_t_13 = 0;
      if (unlikely(__pyx_t_13 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_13);
        __PYX_ERR(0, 409, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_temp_v.data + __pyx_t_7 * __pyx_v_temp_v.strides[0]) )) = ((__pyx_v_x1 + __pyx_v_x2) + __pyx_v_x3);
    }
 410: 
 411:         ### Do the normalization
+412:         for j in range(n_states):
    __pyx_t_8 = __pyx_v_n_states;
    __pyx_t_9 = __pyx_t_8;
    for (__pyx_t_19 = 0; __pyx_t_19 < __pyx_t_9; __pyx_t_19+=1) {
      __pyx_v_j = __pyx_t_19;
+413:             bwd[j, i - 1] = temp_v[j] / c_view[i] # Rescale to prob. distribution
      __pyx_t_7 = __pyx_v_j;
      __pyx_t_13 = -1;
      if (__pyx_t_7 < 0) {
        __pyx_t_13 = 0;
      } else if (unlikely(__pyx_t_7 >= __pyx_v_temp_v.shape[0])) __pyx_t_13 = 0;
      if (unlikely(__pyx_t_13 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_13);
        __PYX_ERR(0, 413, __pyx_L1_error)
      }
      __pyx_t_21 = (*((double *) ( /* dim=0 */ (__pyx_v_temp_v.data + __pyx_t_7 * __pyx_v_temp_v.strides[0]) )));
      __pyx_t_7 = __pyx_v_i;
      __pyx_t_13 = -1;
      if (__pyx_t_7 < 0) {
        __pyx_t_13 = 0;
      } else if (unlikely(__pyx_t_7 >= __pyx_v_c_view.shape[0])) __pyx_t_13 = 0;
      if (unlikely(__pyx_t_13 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_13);
        __PYX_ERR(0, 413, __pyx_L1_error)
      }
      __pyx_t_17 = (*((double *) ( /* dim=0 */ (__pyx_v_c_view.data + __pyx_t_7 * __pyx_v_c_view.strides[0]) )));
      if (unlikely(__pyx_t_17 == 0)) {
        PyErr_SetString(PyExc_ZeroDivisionError, "float division");
        __PYX_ERR(0, 413, __pyx_L1_error)
      }
      __pyx_t_7 = __pyx_v_j;
      __pyx_t_15 = (__pyx_v_i - 1);
      __pyx_t_13 = -1;
      if (__pyx_t_7 < 0) {
        __pyx_t_13 = 0;
      } else if (unlikely(__pyx_t_7 >= __pyx_v_bwd.shape[0])) __pyx_t_13 = 0;
      if (__pyx_t_15 < 0) {
        __pyx_t_13 = 1;
      } else if (unlikely(__pyx_t_15 >= __pyx_v_bwd.shape[1])) __pyx_t_13 = 1;
      if (unlikely(__pyx_t_13 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_13);
        __PYX_ERR(0, 413, __pyx_L1_error)
      }
      *((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_7 * __pyx_v_bwd.strides[0]) ) + __pyx_t_15 * __pyx_v_bwd.strides[1]) )) = (__pyx_t_21 / __pyx_t_17);
    }
  }
 414: 
 415:     ### Combine the forward and backward calculations for posterior
+416:     post = fwd1 * bwd1
  __pyx_t_1 = PyNumber_Multiply(__pyx_v_fwd1, __pyx_v_bwd1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 416, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF_SET(__pyx_v_post, __pyx_t_1);
  __pyx_t_1 = 0;
+417:     if output:
  __pyx_t_23 = __Pyx_PyObject_IsTrue(__pyx_v_output); if (unlikely(__pyx_t_23 < 0)) __PYX_ERR(0, 417, __pyx_L1_error)
  if (__pyx_t_23) {
/* … */
  }
+418:         print("Memory Usage at end of HMM:")
    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_print, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 418, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
/* … */
  __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_u_Memory_Usage_at_end_of_HMM); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(0, 418, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__10);
  __Pyx_GIVEREF(__pyx_tuple__10);
+419:         print_memory_usage()   ## For MEMORY_BENCH
    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_print_memory_usage); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 419, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_3 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
      __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_4);
      if (likely(__pyx_t_3)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
        __Pyx_INCREF(__pyx_t_3);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_4, function);
      }
    }
    __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_4);
    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 419, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+420:         tot_ll = np.sum(np.log(c)) # Tot Likelihood is product over all c.
    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 420, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_sum); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 420, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 420, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_24 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_log); if (unlikely(!__pyx_t_24)) __PYX_ERR(0, 420, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_24);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_2 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_24))) {
      __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_24);
      if (likely(__pyx_t_2)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_24);
        __Pyx_INCREF(__pyx_t_2);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_24, function);
      }
    }
    __pyx_t_4 = (__pyx_t_2) ? __Pyx_PyObject_Call2Args(__pyx_t_24, __pyx_t_2, __pyx_v_c) : __Pyx_PyObject_CallOneArg(__pyx_t_24, __pyx_v_c);
    __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 420, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_24); __pyx_t_24 = 0;
    __pyx_t_24 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
      __pyx_t_24 = PyMethod_GET_SELF(__pyx_t_3);
      if (likely(__pyx_t_24)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
        __Pyx_INCREF(__pyx_t_24);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_3, function);
      }
    }
    __pyx_t_1 = (__pyx_t_24) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_24, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4);
    __Pyx_XDECREF(__pyx_t_24); __pyx_t_24 = 0;
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 420, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __pyx_v_tot_ll = __pyx_t_1;
    __pyx_t_1 = 0;
+421:         print(f"Total Log likelihood: {tot_ll: .3f}")
    __pyx_t_1 = __Pyx_PyObject_Format(__pyx_v_tot_ll, __pyx_kp_u_3f); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 421, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_3 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Total_Log_likelihood, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 421, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 421, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 422: 
+423:     if full:   # Return everything
  __pyx_t_23 = __Pyx_PyObject_IsTrue(__pyx_v_full); if (unlikely(__pyx_t_23 < 0)) __PYX_ERR(0, 423, __pyx_L1_error)
  if (__pyx_t_23) {
/* … */
  }
+424:         tot_ll = np.sum(np.log(c)) # Tot Likelihood is product over all c. 
    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 424, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_sum); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 424, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_GetModuleGlobalName(__pyx_t_24, __pyx_n_s_np); if (unlikely(!__pyx_t_24)) __PYX_ERR(0, 424, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_24);
    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_24, __pyx_n_s_log); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 424, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_24); __pyx_t_24 = 0;
    __pyx_t_24 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
      __pyx_t_24 = PyMethod_GET_SELF(__pyx_t_2);
      if (likely(__pyx_t_24)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
        __Pyx_INCREF(__pyx_t_24);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_2, function);
      }
    }
    __pyx_t_3 = (__pyx_t_24) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_24, __pyx_v_c) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_c);
    __Pyx_XDECREF(__pyx_t_24); __pyx_t_24 = 0;
    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 424, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_2 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
      __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_4);
      if (likely(__pyx_t_2)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
        __Pyx_INCREF(__pyx_t_2);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_4, function);
      }
    }
    __pyx_t_1 = (__pyx_t_2) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __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_1)) __PYX_ERR(0, 424, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_XDECREF_SET(__pyx_v_tot_ll, __pyx_t_1);
    __pyx_t_1 = 0;
+425:         if output:
    __pyx_t_23 = __Pyx_PyObject_IsTrue(__pyx_v_output); if (unlikely(__pyx_t_23 < 0)) __PYX_ERR(0, 425, __pyx_L1_error)
    if (__pyx_t_23) {
/* … */
    }
+426:             print(f"Total Log likelihood: {tot_ll: .3f}")
      __pyx_t_1 = __Pyx_PyObject_Format(__pyx_v_tot_ll, __pyx_kp_u_3f); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 426, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Total_Log_likelihood, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 426, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 426, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+427:         return post, fwd1, bwd1, tot_ll
    __Pyx_XDECREF(__pyx_r);
    __pyx_t_1 = PyTuple_New(4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 427, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_INCREF(__pyx_v_post);
    __Pyx_GIVEREF(__pyx_v_post);
    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_post);
    __Pyx_INCREF(__pyx_v_fwd1);
    __Pyx_GIVEREF(__pyx_v_fwd1);
    PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_fwd1);
    __Pyx_INCREF(__pyx_v_bwd1);
    __Pyx_GIVEREF(__pyx_v_bwd1);
    PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_bwd1);
    __Pyx_INCREF(__pyx_v_tot_ll);
    __Pyx_GIVEREF(__pyx_v_tot_ll);
    PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_v_tot_ll);
    __pyx_r = __pyx_t_1;
    __pyx_t_1 = 0;
    goto __pyx_L0;
 428: 
 429:     else:
+430:         return post
  /*else*/ {
    __Pyx_XDECREF(__pyx_r);
    __Pyx_INCREF(__pyx_v_post);
    __pyx_r = __pyx_v_post;
    goto __pyx_L0;
  }
 431: 
 432: 
+433: def fwd_bkwd_scaled_lowmem(double[:, :] e_mat, double[:, :, :] t_mat,
/* Python wrapper */
static PyObject *__pyx_pw_8hapsburg_5cfunc_9fwd_bkwd_scaled_lowmem(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_8hapsburg_5cfunc_8fwd_bkwd_scaled_lowmem[] = "\n    Uses speed-up specific for Genotype data (pooling same transition rates)\n    Uses rescaling of fwd and bwd calculations - NOT LOGSPACE\n    Low-Mem: Do no save the full FWD BWD and Posterior but use temporary\n    arrays for saving only last vectors. Saves only 0-state posterior long term.\n    e_mat: Emission probabilities: [k x l]  (normal space)\n    t_mat: Transition Matrix:  [l x 3 x 3]  (normal space)\n    in_val: Intitial probability of single symmetric state (normal space)\n    full: Boolean whether to return (post, fwd1, bwd1, tot_ll)\n    else only return post\n    output: Whether to print output useful for monitoring.\n    Otherwise only posterior mat [kxl] of post is returned\n    ";
static PyMethodDef __pyx_mdef_8hapsburg_5cfunc_9fwd_bkwd_scaled_lowmem = {"fwd_bkwd_scaled_lowmem", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_8hapsburg_5cfunc_9fwd_bkwd_scaled_lowmem, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8hapsburg_5cfunc_8fwd_bkwd_scaled_lowmem};
static PyObject *__pyx_pw_8hapsburg_5cfunc_9fwd_bkwd_scaled_lowmem(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  __Pyx_memviewslice __pyx_v_e_mat = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_t_mat = { 0, 0, { 0 }, { 0 }, { 0 } };
  double __pyx_v_in_val;
  PyObject *__pyx_v_full = 0;
  PyObject *__pyx_v_output = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("fwd_bkwd_scaled_lowmem (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_e_mat,&__pyx_n_s_t_mat,&__pyx_n_s_in_val,&__pyx_n_s_full,&__pyx_n_s_output,0};
    PyObject* values[5] = {0,0,0,0,0};
/* … */
  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_8hapsburg_5cfunc_8fwd_bkwd_scaled_lowmem(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_e_mat, __Pyx_memviewslice __pyx_v_t_mat, double __pyx_v_in_val, PyObject *__pyx_v_full, PyObject *__pyx_v_output) {
  int __pyx_v_n_states;
  int __pyx_v_n_loci;
  Py_ssize_t __pyx_v_i;
  Py_ssize_t __pyx_v_j;
  Py_ssize_t __pyx_v_k;
  double __pyx_v_stay;
  double __pyx_v_x1;
  double __pyx_v_x2;
  double __pyx_v_x3;
  PyObject *__pyx_v_post = NULL;
  __Pyx_memviewslice __pyx_v_post_view = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_temp = NULL;
  __Pyx_memviewslice __pyx_v_temp_v = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_temp1 = NULL;
  __Pyx_memviewslice __pyx_v_temp1_v = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_t = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_c = NULL;
  __Pyx_memviewslice __pyx_v_c_view = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_fwd0 = NULL;
  __Pyx_memviewslice __pyx_v_fwd = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_bwd0 = NULL;
  __Pyx_memviewslice __pyx_v_bwd = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_tmp0 = NULL;
  CYTHON_UNUSED __Pyx_memviewslice __pyx_v_tmp = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_f_l = NULL;
  PyObject *__pyx_v_tot_ll = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("fwd_bkwd_scaled_lowmem", 0);
/* … */
  /* 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_22);
  __Pyx_AddTraceback("hapsburg.cfunc.fwd_bkwd_scaled_lowmem", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_post);
  __PYX_XDEC_MEMVIEW(&__pyx_v_post_view, 1);
  __Pyx_XDECREF(__pyx_v_temp);
  __PYX_XDEC_MEMVIEW(&__pyx_v_temp_v, 1);
  __Pyx_XDECREF(__pyx_v_temp1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_temp1_v, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_t, 1);
  __Pyx_XDECREF(__pyx_v_c);
  __PYX_XDEC_MEMVIEW(&__pyx_v_c_view, 1);
  __Pyx_XDECREF(__pyx_v_fwd0);
  __PYX_XDEC_MEMVIEW(&__pyx_v_fwd, 1);
  __Pyx_XDECREF(__pyx_v_bwd0);
  __PYX_XDEC_MEMVIEW(&__pyx_v_bwd, 1);
  __Pyx_XDECREF(__pyx_v_tmp0);
  __PYX_XDEC_MEMVIEW(&__pyx_v_tmp, 1);
  __Pyx_XDECREF(__pyx_v_f_l);
  __Pyx_XDECREF(__pyx_v_tot_ll);
  __PYX_XDEC_MEMVIEW(&__pyx_v_e_mat, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_t_mat, 1);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__36 = PyTuple_Pack(31, __pyx_n_s_e_mat, __pyx_n_s_t_mat, __pyx_n_s_in_val, __pyx_n_s_full, __pyx_n_s_output, __pyx_n_s_n_states, __pyx_n_s_n_loci, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_k, __pyx_n_s_stay, __pyx_n_s_x1, __pyx_n_s_x2, __pyx_n_s_x3, __pyx_n_s_post, __pyx_n_s_post_view, __pyx_n_s_temp, __pyx_n_s_temp_v, __pyx_n_s_temp1, __pyx_n_s_temp1_v, __pyx_n_s_t, __pyx_n_s_c, __pyx_n_s_c_view, __pyx_n_s_fwd0, __pyx_n_s_fwd, __pyx_n_s_bwd0, __pyx_n_s_bwd, __pyx_n_s_tmp0, __pyx_n_s_tmp, __pyx_n_s_f_l, __pyx_n_s_tot_ll); if (unlikely(!__pyx_tuple__36)) __PYX_ERR(0, 433, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__36);
  __Pyx_GIVEREF(__pyx_tuple__36);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_8hapsburg_5cfunc_9fwd_bkwd_scaled_lowmem, NULL, __pyx_n_s_hapsburg_cfunc); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 433, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_fwd_bkwd_scaled_lowmem, __pyx_t_2) < 0) __PYX_ERR(0, 433, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__37 = (PyObject*)__Pyx_PyCode_New(5, 0, 31, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__36, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_hapsburg_cfunc_pyx, __pyx_n_s_fwd_bkwd_scaled_lowmem, 433, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__37)) __PYX_ERR(0, 433, __pyx_L1_error)
+434:                            double in_val = 1e-4, full=False, output=True):
    values[3] = ((PyObject *)Py_False);
    values[4] = ((PyObject *)Py_True);
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        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_e_mat)) != 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_t_mat)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("fwd_bkwd_scaled_lowmem", 0, 2, 5, 1); __PYX_ERR(0, 433, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_in_val);
          if (value) { values[2] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_full);
          if (value) { values[3] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  4:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_output);
          if (value) { values[4] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "fwd_bkwd_scaled_lowmem") < 0)) __PYX_ERR(0, 433, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        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);
        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_e_mat = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(values[0], PyBUF_WRITABLE); if (unlikely(!__pyx_v_e_mat.memview)) __PYX_ERR(0, 433, __pyx_L3_error)
    __pyx_v_t_mat = __Pyx_PyObject_to_MemoryviewSlice_dsdsds_double(values[1], PyBUF_WRITABLE); if (unlikely(!__pyx_v_t_mat.memview)) __PYX_ERR(0, 433, __pyx_L3_error)
    if (values[2]) {
      __pyx_v_in_val = __pyx_PyFloat_AsDouble(values[2]); if (unlikely((__pyx_v_in_val == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 434, __pyx_L3_error)
    } else {
      __pyx_v_in_val = ((double)1e-4);
    }
    __pyx_v_full = values[3];
    __pyx_v_output = values[4];
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("fwd_bkwd_scaled_lowmem", 0, 2, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 433, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("hapsburg.cfunc.fwd_bkwd_scaled_lowmem", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_8hapsburg_5cfunc_8fwd_bkwd_scaled_lowmem(__pyx_self, __pyx_v_e_mat, __pyx_v_t_mat, __pyx_v_in_val, __pyx_v_full, __pyx_v_output);
 435:     """
 436:     Uses speed-up specific for Genotype data (pooling same transition rates)
 437:     Uses rescaling of fwd and bwd calculations - NOT LOGSPACE
 438:     Low-Mem: Do no save the full FWD BWD and Posterior but use temporary
 439:     arrays for saving only last vectors. Saves only 0-state posterior long term.
 440:     e_mat: Emission probabilities: [k x l]  (normal space)
 441:     t_mat: Transition Matrix:  [l x 3 x 3]  (normal space)
 442:     in_val: Intitial probability of single symmetric state (normal space)
 443:     full: Boolean whether to return (post, fwd1, bwd1, tot_ll)
 444:     else only return post
 445:     output: Whether to print output useful for monitoring.
 446:     Otherwise only posterior mat [kxl] of post is returned
 447:     """
+448:     cdef int n_states = e_mat.shape[0]
  __pyx_v_n_states = (__pyx_v_e_mat.shape[0]);
+449:     cdef int n_loci = e_mat.shape[1]
  __pyx_v_n_loci = (__pyx_v_e_mat.shape[1]);
 450:     cdef Py_ssize_t i, j, k    # The Array and Iteration Indices
 451:     cdef double stay           # The Probablility of Staying
 452:     cdef double x1, x2, x3     # Place holder variables [make code readable]
 453: 
 454:     # Initialize Posterior and Transition Probabilities
+455:     post = np.empty(n_loci, dtype=DTYPE) # Array of 0 State Posterior
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 455, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 455, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_n_loci); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 455, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 455, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
  __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 455, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 455, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_4) < 0) __PYX_ERR(0, 455, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 455, __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_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_post = __pyx_t_4;
  __pyx_t_4 = 0;
+456:     cdef double[:] post_view = post
  __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_post, PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 456, __pyx_L1_error)
  __pyx_v_post_view = __pyx_t_5;
  __pyx_t_5.memview = NULL;
  __pyx_t_5.data = NULL;
 457: 
+458:     temp = np.empty(n_states, dtype=DTYPE) # l Array for calculations
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 458, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_empty); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 458, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_n_states); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 458, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 458, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
  __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 458, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 458, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_2) < 0) __PYX_ERR(0, 458, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 458, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_v_temp = __pyx_t_2;
  __pyx_t_2 = 0;
+459:     cdef double[:] temp_v = temp
  __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_temp, PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 459, __pyx_L1_error)
  __pyx_v_temp_v = __pyx_t_5;
  __pyx_t_5.memview = NULL;
  __pyx_t_5.data = NULL;
 460: 
+461:     temp1 = np.empty(n_states-1, dtype=DTYPE) # l-1 Array for calculatons
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 461, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 461, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyInt_From_long((__pyx_v_n_states - 1)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 461, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 461, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_2);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
  __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 461, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 461, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_1) < 0) __PYX_ERR(0, 461, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 461, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_temp1 = __pyx_t_1;
  __pyx_t_1 = 0;
+462:     cdef double[:] temp1_v = temp1
  __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_temp1, PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 462, __pyx_L1_error)
  __pyx_v_temp1_v = __pyx_t_5;
  __pyx_t_5.memview = NULL;
  __pyx_t_5.data = NULL;
 463: 
+464:     cdef double[:,:,:] t = t_mat   # C View of transition matrix
  __PYX_INC_MEMVIEW(&__pyx_v_t_mat, 0);
  __pyx_v_t = __pyx_v_t_mat;
 465: 
+466:     c = np.empty(n_loci, dtype=DTYPE) # Array of normalization constants
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 466, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 466, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_n_loci); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 466, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 466, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
  __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 466, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 466, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_4) < 0) __PYX_ERR(0, 466, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 466, __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_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_c = __pyx_t_4;
  __pyx_t_4 = 0;
+467:     cdef double[:] c_view = c
  __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_c, PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 467, __pyx_L1_error)
  __pyx_v_c_view = __pyx_t_5;
  __pyx_t_5.memview = NULL;
  __pyx_t_5.data = NULL;
+468:     c_view[0] = 1 # Set the first normalization constant
  __pyx_t_6 = 0;
  __pyx_t_7 = -1;
  if (__pyx_t_6 < 0) {
    __pyx_t_7 = 0;
  } else if (unlikely(__pyx_t_6 >= __pyx_v_c_view.shape[0])) __pyx_t_7 = 0;
  if (unlikely(__pyx_t_7 != -1)) {
    __Pyx_RaiseBufferIndexError(__pyx_t_7);
    __PYX_ERR(0, 468, __pyx_L1_error)
  }
  *((double *) ( /* dim=0 */ (__pyx_v_c_view.data + __pyx_t_6 * __pyx_v_c_view.strides[0]) )) = 1.0;
 469: 
 470:     #############################
 471:     ### Initialize FWD BWD Arrays
+472:     fwd0 = np.zeros(n_states, dtype=DTYPE)
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 472, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_zeros); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 472, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_n_states); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 472, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 472, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
  __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 472, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 472, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_2) < 0) __PYX_ERR(0, 472, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 472, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_v_fwd0 = __pyx_t_2;
  __pyx_t_2 = 0;
+473:     fwd0[:] = in_val  # Initial Probabilities
  __pyx_t_2 = PyFloat_FromDouble(__pyx_v_in_val); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 473, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (__Pyx_PyObject_SetSlice(__pyx_v_fwd0, __pyx_t_2, 0, 0, NULL, NULL, &__pyx_slice__3, 0, 0, 0) < 0) __PYX_ERR(0, 473, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+474:     fwd0[0] = 1 - (n_states - 1) * in_val
  __pyx_t_2 = PyFloat_FromDouble((1.0 - ((__pyx_v_n_states - 1) * __pyx_v_in_val))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 474, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (unlikely(__Pyx_SetItemInt(__pyx_v_fwd0, 0, __pyx_t_2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1) < 0)) __PYX_ERR(0, 474, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+475:     cdef double[:] fwd = fwd0
  __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_fwd0, PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 475, __pyx_L1_error)
  __pyx_v_fwd = __pyx_t_5;
  __pyx_t_5.memview = NULL;
  __pyx_t_5.data = NULL;
 476: 
+477:     bwd0 = np.zeros(n_states, dtype=DTYPE)
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 477, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_zeros); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 477, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_n_states); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 477, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 477, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_2);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
  __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 477, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 477, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_1) < 0) __PYX_ERR(0, 477, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 477, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_bwd0 = __pyx_t_1;
  __pyx_t_1 = 0;
+478:     bwd0[:] = 1
  if (__Pyx_PyObject_SetSlice(__pyx_v_bwd0, __pyx_int_1, 0, 0, NULL, NULL, &__pyx_slice__3, 0, 0, 0) < 0) __PYX_ERR(0, 478, __pyx_L1_error)
+479:     cdef double[:] bwd = bwd0
  __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_bwd0, PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 479, __pyx_L1_error)
  __pyx_v_bwd = __pyx_t_5;
  __pyx_t_5.memview = NULL;
  __pyx_t_5.data = NULL;
 480: 
+481:     tmp0 = np.zeros(n_states, dtype=DTYPE)
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 481, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_zeros); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 481, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_n_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 481, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 481, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
  __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 481, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 481, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_4) < 0) __PYX_ERR(0, 481, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 481, __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_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_tmp0 = __pyx_t_4;
  __pyx_t_4 = 0;
+482:     cdef double[:] tmp = tmp0
  __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_tmp0, PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 482, __pyx_L1_error)
  __pyx_v_tmp = __pyx_t_5;
  __pyx_t_5.memview = NULL;
  __pyx_t_5.data = NULL;
 483: 
 484:     #############################
 485:     ### Do the Forward Algorithm
+486:     post_view[0] = fwd[0]  # Add to 0-State Posterior
  __pyx_t_6 = 0;
  __pyx_t_7 = -1;
  if (__pyx_t_6 < 0) {
    __pyx_t_7 = 0;
  } else if (unlikely(__pyx_t_6 >= __pyx_v_fwd.shape[0])) __pyx_t_7 = 0;
  if (unlikely(__pyx_t_7 != -1)) {
    __Pyx_RaiseBufferIndexError(__pyx_t_7);
    __PYX_ERR(0, 486, __pyx_L1_error)
  }
  __pyx_t_8 = 0;
  __pyx_t_7 = -1;
  if (__pyx_t_8 < 0) {
    __pyx_t_7 = 0;
  } else if (unlikely(__pyx_t_8 >= __pyx_v_post_view.shape[0])) __pyx_t_7 = 0;
  if (unlikely(__pyx_t_7 != -1)) {
    __Pyx_RaiseBufferIndexError(__pyx_t_7);
    __PYX_ERR(0, 486, __pyx_L1_error)
  }
  *((double *) ( /* dim=0 */ (__pyx_v_post_view.data + __pyx_t_8 * __pyx_v_post_view.strides[0]) )) = (*((double *) ( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_6 * __pyx_v_fwd.strides[0]) )));
 487: 
+488:     for i in range(1, n_loci):  # Run forward recursion
  __pyx_t_7 = __pyx_v_n_loci;
  __pyx_t_9 = __pyx_t_7;
  for (__pyx_t_10 = 1; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
    __pyx_v_i = __pyx_t_10;
+489:         stay = t[i, 1, 1] - t[i, 1, 2]  # Do the log of the Stay term
    __pyx_t_6 = __pyx_v_i;
    __pyx_t_8 = 1;
    __pyx_t_11 = 1;
    __pyx_t_12 = -1;
    if (__pyx_t_6 < 0) {
      __pyx_t_12 = 0;
    } else if (unlikely(__pyx_t_6 >= __pyx_v_t.shape[0])) __pyx_t_12 = 0;
    if (__pyx_t_8 < 0) {
      __pyx_t_12 = 1;
    } else if (unlikely(__pyx_t_8 >= __pyx_v_t.shape[1])) __pyx_t_12 = 1;
    if (__pyx_t_11 < 0) {
      __pyx_t_12 = 2;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_t.shape[2])) __pyx_t_12 = 2;
    if (unlikely(__pyx_t_12 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_12);
      __PYX_ERR(0, 489, __pyx_L1_error)
    }
    __pyx_t_13 = __pyx_v_i;
    __pyx_t_14 = 1;
    __pyx_t_15 = 2;
    __pyx_t_12 = -1;
    if (__pyx_t_13 < 0) {
      __pyx_t_12 = 0;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_t.shape[0])) __pyx_t_12 = 0;
    if (__pyx_t_14 < 0) {
      __pyx_t_12 = 1;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_t.shape[1])) __pyx_t_12 = 1;
    if (__pyx_t_15 < 0) {
      __pyx_t_12 = 2;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t.shape[2])) __pyx_t_12 = 2;
    if (unlikely(__pyx_t_12 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_12);
      __PYX_ERR(0, 489, __pyx_L1_error)
    }
    __pyx_v_stay = ((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_6 * __pyx_v_t.strides[0]) ) + __pyx_t_8 * __pyx_v_t.strides[1]) ) + __pyx_t_11 * __pyx_v_t.strides[2]) ))) - (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_13 * __pyx_v_t.strides[0]) ) + __pyx_t_14 * __pyx_v_t.strides[1]) ) + __pyx_t_15 * __pyx_v_t.strides[2]) ))));
 490: 
 491:         #for k in range(1, n_states): # Calculate Sum of ROH states. 
+492:         f_l = 1 - fwd[0]  ### Assume they are normalized!!!
    __pyx_t_15 = 0;
    __pyx_t_12 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_12 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_fwd.shape[0])) __pyx_t_12 = 0;
    if (unlikely(__pyx_t_12 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_12);
      __PYX_ERR(0, 492, __pyx_L1_error)
    }
    __pyx_t_4 = PyFloat_FromDouble((1.0 - (*((double *) ( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_15 * __pyx_v_fwd.strides[0]) ))))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 492, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_XDECREF_SET(__pyx_v_f_l, __pyx_t_4);
    __pyx_t_4 = 0;
 493: 
 494:         ### Do the 0 State:
+495:         x1 = fwd[0] * t[i, 0, 0]    # Staying in 0 State
    __pyx_t_15 = 0;
    __pyx_t_12 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_12 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_fwd.shape[0])) __pyx_t_12 = 0;
    if (unlikely(__pyx_t_12 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_12);
      __PYX_ERR(0, 495, __pyx_L1_error)
    }
    __pyx_t_14 = __pyx_v_i;
    __pyx_t_13 = 0;
    __pyx_t_11 = 0;
    __pyx_t_12 = -1;
    if (__pyx_t_14 < 0) {
      __pyx_t_12 = 0;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_t.shape[0])) __pyx_t_12 = 0;
    if (__pyx_t_13 < 0) {
      __pyx_t_12 = 1;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_t.shape[1])) __pyx_t_12 = 1;
    if (__pyx_t_11 < 0) {
      __pyx_t_12 = 2;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_t.shape[2])) __pyx_t_12 = 2;
    if (unlikely(__pyx_t_12 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_12);
      __PYX_ERR(0, 495, __pyx_L1_error)
    }
    __pyx_v_x1 = ((*((double *) ( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_15 * __pyx_v_fwd.strides[0]) ))) * (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_14 * __pyx_v_t.strides[0]) ) + __pyx_t_13 * __pyx_v_t.strides[1]) ) + __pyx_t_11 * __pyx_v_t.strides[2]) ))));
+496:         x2 = f_l * t[i, 1, 0]               # Going into 0 State from any other
    __pyx_t_11 = __pyx_v_i;
    __pyx_t_13 = 1;
    __pyx_t_14 = 0;
    __pyx_t_12 = -1;
    if (__pyx_t_11 < 0) {
      __pyx_t_12 = 0;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_t.shape[0])) __pyx_t_12 = 0;
    if (__pyx_t_13 < 0) {
      __pyx_t_12 = 1;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_t.shape[1])) __pyx_t_12 = 1;
    if (__pyx_t_14 < 0) {
      __pyx_t_12 = 2;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_t.shape[2])) __pyx_t_12 = 2;
    if (unlikely(__pyx_t_12 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_12);
      __PYX_ERR(0, 496, __pyx_L1_error)
    }
    __pyx_t_4 = PyFloat_FromDouble((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_11 * __pyx_v_t.strides[0]) ) + __pyx_t_13 * __pyx_v_t.strides[1]) ) + __pyx_t_14 * __pyx_v_t.strides[2]) )))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 496, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_1 = PyNumber_Multiply(__pyx_v_f_l, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 496, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_t_16 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_16 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 496, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_v_x2 = __pyx_t_16;
+497:         temp_v[0] = e_mat[0, i] * (x1 + x2) # Set the unnorm. 0 forward variable
    __pyx_t_14 = 0;
    __pyx_t_13 = __pyx_v_i;
    __pyx_t_12 = -1;
    if (__pyx_t_14 < 0) {
      __pyx_t_12 = 0;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_e_mat.shape[0])) __pyx_t_12 = 0;
    if (__pyx_t_13 < 0) {
      __pyx_t_12 = 1;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_e_mat.shape[1])) __pyx_t_12 = 1;
    if (unlikely(__pyx_t_12 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_12);
      __PYX_ERR(0, 497, __pyx_L1_error)
    }
    __pyx_t_11 = 0;
    __pyx_t_12 = -1;
    if (__pyx_t_11 < 0) {
      __pyx_t_12 = 0;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_temp_v.shape[0])) __pyx_t_12 = 0;
    if (unlikely(__pyx_t_12 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_12);
      __PYX_ERR(0, 497, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_temp_v.data + __pyx_t_11 * __pyx_v_temp_v.strides[0]) )) = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat.data + __pyx_t_14 * __pyx_v_e_mat.strides[0]) ) + __pyx_t_13 * __pyx_v_e_mat.strides[1]) ))) * (__pyx_v_x1 + __pyx_v_x2));
 498: 
 499:         ### Do the other states
 500:         # Preprocessing:
+501:         x1 = fwd[0] * t[i, 0, 1]   # Coming from 0 State
    __pyx_t_13 = 0;
    __pyx_t_12 = -1;
    if (__pyx_t_13 < 0) {
      __pyx_t_12 = 0;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_fwd.shape[0])) __pyx_t_12 = 0;
    if (unlikely(__pyx_t_12 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_12);
      __PYX_ERR(0, 501, __pyx_L1_error)
    }
    __pyx_t_14 = __pyx_v_i;
    __pyx_t_11 = 0;
    __pyx_t_15 = 1;
    __pyx_t_12 = -1;
    if (__pyx_t_14 < 0) {
      __pyx_t_12 = 0;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_t.shape[0])) __pyx_t_12 = 0;
    if (__pyx_t_11 < 0) {
      __pyx_t_12 = 1;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_t.shape[1])) __pyx_t_12 = 1;
    if (__pyx_t_15 < 0) {
      __pyx_t_12 = 2;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t.shape[2])) __pyx_t_12 = 2;
    if (unlikely(__pyx_t_12 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_12);
      __PYX_ERR(0, 501, __pyx_L1_error)
    }
    __pyx_v_x1 = ((*((double *) ( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_13 * __pyx_v_fwd.strides[0]) ))) * (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_14 * __pyx_v_t.strides[0]) ) + __pyx_t_11 * __pyx_v_t.strides[1]) ) + __pyx_t_15 * __pyx_v_t.strides[2]) ))));
+502:         x2 = f_l * t[i, 1, 2]             # Coming from other ROH State
    __pyx_t_15 = __pyx_v_i;
    __pyx_t_11 = 1;
    __pyx_t_14 = 2;
    __pyx_t_12 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_12 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t.shape[0])) __pyx_t_12 = 0;
    if (__pyx_t_11 < 0) {
      __pyx_t_12 = 1;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_t.shape[1])) __pyx_t_12 = 1;
    if (__pyx_t_14 < 0) {
      __pyx_t_12 = 2;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_t.shape[2])) __pyx_t_12 = 2;
    if (unlikely(__pyx_t_12 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_12);
      __PYX_ERR(0, 502, __pyx_L1_error)
    }
    __pyx_t_1 = PyFloat_FromDouble((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_15 * __pyx_v_t.strides[0]) ) + __pyx_t_11 * __pyx_v_t.strides[1]) ) + __pyx_t_14 * __pyx_v_t.strides[2]) )))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 502, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_4 = PyNumber_Multiply(__pyx_v_f_l, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 502, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_16 = __pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_16 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 502, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_v_x2 = __pyx_t_16;
 503: 
+504:         for j in range(1, n_states):  # Do the final run over all states
    __pyx_t_12 = __pyx_v_n_states;
    __pyx_t_17 = __pyx_t_12;
    for (__pyx_t_18 = 1; __pyx_t_18 < __pyx_t_17; __pyx_t_18+=1) {
      __pyx_v_j = __pyx_t_18;
+505:             x3 = fwd[j] *  stay # Staying in state
      __pyx_t_14 = __pyx_v_j;
      __pyx_t_19 = -1;
      if (__pyx_t_14 < 0) {
        __pyx_t_19 = 0;
      } else if (unlikely(__pyx_t_14 >= __pyx_v_fwd.shape[0])) __pyx_t_19 = 0;
      if (unlikely(__pyx_t_19 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_19);
        __PYX_ERR(0, 505, __pyx_L1_error)
      }
      __pyx_v_x3 = ((*((double *) ( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_14 * __pyx_v_fwd.strides[0]) ))) * __pyx_v_stay);
+506:             temp_v[j] = e_mat[j, i] * (x1 + x2 + x3)
      __pyx_t_14 = __pyx_v_j;
      __pyx_t_11 = __pyx_v_i;
      __pyx_t_19 = -1;
      if (__pyx_t_14 < 0) {
        __pyx_t_19 = 0;
      } else if (unlikely(__pyx_t_14 >= __pyx_v_e_mat.shape[0])) __pyx_t_19 = 0;
      if (__pyx_t_11 < 0) {
        __pyx_t_19 = 1;
      } else if (unlikely(__pyx_t_11 >= __pyx_v_e_mat.shape[1])) __pyx_t_19 = 1;
      if (unlikely(__pyx_t_19 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_19);
        __PYX_ERR(0, 506, __pyx_L1_error)
      }
      __pyx_t_15 = __pyx_v_j;
      __pyx_t_19 = -1;
      if (__pyx_t_15 < 0) {
        __pyx_t_19 = 0;
      } else if (unlikely(__pyx_t_15 >= __pyx_v_temp_v.shape[0])) __pyx_t_19 = 0;
      if (unlikely(__pyx_t_19 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_19);
        __PYX_ERR(0, 506, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_temp_v.data + __pyx_t_15 * __pyx_v_temp_v.strides[0]) )) = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat.data + __pyx_t_14 * __pyx_v_e_mat.strides[0]) ) + __pyx_t_11 * __pyx_v_e_mat.strides[1]) ))) * ((__pyx_v_x1 + __pyx_v_x2) + __pyx_v_x3));
    }
 507: 
 508:         ### Do the normalization and set up the forward array for next step
+509:         c_view[i] = sum_array(temp_v, n_states)
    __pyx_t_11 = __pyx_v_i;
    __pyx_t_12 = -1;
    if (__pyx_t_11 < 0) {
      __pyx_t_12 = 0;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_c_view.shape[0])) __pyx_t_12 = 0;
    if (unlikely(__pyx_t_12 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_12);
      __PYX_ERR(0, 509, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_c_view.data + __pyx_t_11 * __pyx_v_c_view.strides[0]) )) = __pyx_f_8hapsburg_5cfunc_sum_array(__pyx_v_temp_v, __pyx_v_n_states);
+510:         for j in range(n_states):
    __pyx_t_12 = __pyx_v_n_states;
    __pyx_t_17 = __pyx_t_12;
    for (__pyx_t_18 = 0; __pyx_t_18 < __pyx_t_17; __pyx_t_18+=1) {
      __pyx_v_j = __pyx_t_18;
+511:             fwd[j] = temp_v[j] / c_view[i] # Rescale to prob. distribution
      __pyx_t_11 = __pyx_v_j;
      __pyx_t_19 = -1;
      if (__pyx_t_11 < 0) {
        __pyx_t_19 = 0;
      } else if (unlikely(__pyx_t_11 >= __pyx_v_temp_v.shape[0])) __pyx_t_19 = 0;
      if (unlikely(__pyx_t_19 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_19);
        __PYX_ERR(0, 511, __pyx_L1_error)
      }
      __pyx_t_16 = (*((double *) ( /* dim=0 */ (__pyx_v_temp_v.data + __pyx_t_11 * __pyx_v_temp_v.strides[0]) )));
      __pyx_t_11 = __pyx_v_i;
      __pyx_t_19 = -1;
      if (__pyx_t_11 < 0) {
        __pyx_t_19 = 0;
      } else if (unlikely(__pyx_t_11 >= __pyx_v_c_view.shape[0])) __pyx_t_19 = 0;
      if (unlikely(__pyx_t_19 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_19);
        __PYX_ERR(0, 511, __pyx_L1_error)
      }
      __pyx_t_20 = (*((double *) ( /* dim=0 */ (__pyx_v_c_view.data + __pyx_t_11 * __pyx_v_c_view.strides[0]) )));
      if (unlikely(__pyx_t_20 == 0)) {
        PyErr_SetString(PyExc_ZeroDivisionError, "float division");
        __PYX_ERR(0, 511, __pyx_L1_error)
      }
      __pyx_t_11 = __pyx_v_j;
      __pyx_t_19 = -1;
      if (__pyx_t_11 < 0) {
        __pyx_t_19 = 0;
      } else if (unlikely(__pyx_t_11 >= __pyx_v_fwd.shape[0])) __pyx_t_19 = 0;
      if (unlikely(__pyx_t_19 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_19);
        __PYX_ERR(0, 511, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_11 * __pyx_v_fwd.strides[0]) )) = (__pyx_t_16 / __pyx_t_20);
    }
+512:         post_view[i] = fwd[0]  # Add to 0-State Posterior
    __pyx_t_11 = 0;
    __pyx_t_12 = -1;
    if (__pyx_t_11 < 0) {
      __pyx_t_12 = 0;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_fwd.shape[0])) __pyx_t_12 = 0;
    if (unlikely(__pyx_t_12 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_12);
      __PYX_ERR(0, 512, __pyx_L1_error)
    }
    __pyx_t_14 = __pyx_v_i;
    __pyx_t_12 = -1;
    if (__pyx_t_14 < 0) {
      __pyx_t_12 = 0;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_post_view.shape[0])) __pyx_t_12 = 0;
    if (unlikely(__pyx_t_12 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_12);
      __PYX_ERR(0, 512, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_post_view.data + __pyx_t_14 * __pyx_v_post_view.strides[0]) )) = (*((double *) ( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_11 * __pyx_v_fwd.strides[0]) )));
  }
 513: 
 514:     #############################
 515:     ### Do the Backward Algorithm
+516:     post_view[n_loci-1] = post_view[n_loci-1] * bwd[0] # The lat one
  __pyx_t_11 = (__pyx_v_n_loci - 1);
  __pyx_t_7 = -1;
  if (__pyx_t_11 < 0) {
    __pyx_t_7 = 0;
  } else if (unlikely(__pyx_t_11 >= __pyx_v_post_view.shape[0])) __pyx_t_7 = 0;
  if (unlikely(__pyx_t_7 != -1)) {
    __Pyx_RaiseBufferIndexError(__pyx_t_7);
    __PYX_ERR(0, 516, __pyx_L1_error)
  }
  __pyx_t_14 = 0;
  __pyx_t_7 = -1;
  if (__pyx_t_14 < 0) {
    __pyx_t_7 = 0;
  } else if (unlikely(__pyx_t_14 >= __pyx_v_bwd.shape[0])) __pyx_t_7 = 0;
  if (unlikely(__pyx_t_7 != -1)) {
    __Pyx_RaiseBufferIndexError(__pyx_t_7);
    __PYX_ERR(0, 516, __pyx_L1_error)
  }
  __pyx_t_15 = (__pyx_v_n_loci - 1);
  __pyx_t_7 = -1;
  if (__pyx_t_15 < 0) {
    __pyx_t_7 = 0;
  } else if (unlikely(__pyx_t_15 >= __pyx_v_post_view.shape[0])) __pyx_t_7 = 0;
  if (unlikely(__pyx_t_7 != -1)) {
    __Pyx_RaiseBufferIndexError(__pyx_t_7);
    __PYX_ERR(0, 516, __pyx_L1_error)
  }
  *((double *) ( /* dim=0 */ (__pyx_v_post_view.data + __pyx_t_15 * __pyx_v_post_view.strides[0]) )) = ((*((double *) ( /* dim=0 */ (__pyx_v_post_view.data + __pyx_t_11 * __pyx_v_post_view.strides[0]) ))) * (*((double *) ( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_14 * __pyx_v_bwd.strides[0]) ))));
 517: 
+518:     for i in range(n_loci-1, 0, -1):  # Run backward recursion
  for (__pyx_t_10 = (__pyx_v_n_loci - 1); __pyx_t_10 > 0; __pyx_t_10-=1) {
    __pyx_v_i = __pyx_t_10;
+519:         stay = t[i, 1, 1] - t[i, 1, 2]
    __pyx_t_14 = __pyx_v_i;
    __pyx_t_11 = 1;
    __pyx_t_15 = 1;
    __pyx_t_7 = -1;
    if (__pyx_t_14 < 0) {
      __pyx_t_7 = 0;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_t.shape[0])) __pyx_t_7 = 0;
    if (__pyx_t_11 < 0) {
      __pyx_t_7 = 1;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_t.shape[1])) __pyx_t_7 = 1;
    if (__pyx_t_15 < 0) {
      __pyx_t_7 = 2;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t.shape[2])) __pyx_t_7 = 2;
    if (unlikely(__pyx_t_7 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_7);
      __PYX_ERR(0, 519, __pyx_L1_error)
    }
    __pyx_t_13 = __pyx_v_i;
    __pyx_t_8 = 1;
    __pyx_t_6 = 2;
    __pyx_t_7 = -1;
    if (__pyx_t_13 < 0) {
      __pyx_t_7 = 0;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_t.shape[0])) __pyx_t_7 = 0;
    if (__pyx_t_8 < 0) {
      __pyx_t_7 = 1;
    } else if (unlikely(__pyx_t_8 >= __pyx_v_t.shape[1])) __pyx_t_7 = 1;
    if (__pyx_t_6 < 0) {
      __pyx_t_7 = 2;
    } else if (unlikely(__pyx_t_6 >= __pyx_v_t.shape[2])) __pyx_t_7 = 2;
    if (unlikely(__pyx_t_7 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_7);
      __PYX_ERR(0, 519, __pyx_L1_error)
    }
    __pyx_v_stay = ((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_14 * __pyx_v_t.strides[0]) ) + __pyx_t_11 * __pyx_v_t.strides[1]) ) + __pyx_t_15 * __pyx_v_t.strides[2]) ))) - (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_13 * __pyx_v_t.strides[0]) ) + __pyx_t_8 * __pyx_v_t.strides[1]) ) + __pyx_t_6 * __pyx_v_t.strides[2]) ))));
 520: 
+521:         for k in range(1, n_states): # Calculate logsum of ROH states:
    __pyx_t_7 = __pyx_v_n_states;
    __pyx_t_9 = __pyx_t_7;
    for (__pyx_t_18 = 1; __pyx_t_18 < __pyx_t_9; __pyx_t_18+=1) {
      __pyx_v_k = __pyx_t_18;
+522:             temp1_v[k-1] = bwd[k] * e_mat[k, i]
      __pyx_t_6 = __pyx_v_k;
      __pyx_t_12 = -1;
      if (__pyx_t_6 < 0) {
        __pyx_t_12 = 0;
      } else if (unlikely(__pyx_t_6 >= __pyx_v_bwd.shape[0])) __pyx_t_12 = 0;
      if (unlikely(__pyx_t_12 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_12);
        __PYX_ERR(0, 522, __pyx_L1_error)
      }
      __pyx_t_8 = __pyx_v_k;
      __pyx_t_13 = __pyx_v_i;
      __pyx_t_12 = -1;
      if (__pyx_t_8 < 0) {
        __pyx_t_12 = 0;
      } else if (unlikely(__pyx_t_8 >= __pyx_v_e_mat.shape[0])) __pyx_t_12 = 0;
      if (__pyx_t_13 < 0) {
        __pyx_t_12 = 1;
      } else if (unlikely(__pyx_t_13 >= __pyx_v_e_mat.shape[1])) __pyx_t_12 = 1;
      if (unlikely(__pyx_t_12 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_12);
        __PYX_ERR(0, 522, __pyx_L1_error)
      }
      __pyx_t_15 = (__pyx_v_k - 1);
      __pyx_t_12 = -1;
      if (__pyx_t_15 < 0) {
        __pyx_t_12 = 0;
      } else if (unlikely(__pyx_t_15 >= __pyx_v_temp1_v.shape[0])) __pyx_t_12 = 0;
      if (unlikely(__pyx_t_12 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_12);
        __PYX_ERR(0, 522, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_temp1_v.data + __pyx_t_15 * __pyx_v_temp1_v.strides[0]) )) = ((*((double *) ( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_6 * __pyx_v_bwd.strides[0]) ))) * (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat.data + __pyx_t_8 * __pyx_v_e_mat.strides[0]) ) + __pyx_t_13 * __pyx_v_e_mat.strides[1]) ))));
    }
+523:         f_l = sum_array(temp1_v, n_states-1) # Logsum of ROH States
    __pyx_t_4 = PyFloat_FromDouble(__pyx_f_8hapsburg_5cfunc_sum_array(__pyx_v_temp1_v, (__pyx_v_n_states - 1))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 523, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_XDECREF_SET(__pyx_v_f_l, __pyx_t_4);
    __pyx_t_4 = 0;
 524: 
 525:       # Do the 0 State:
+526:         x1 = bwd[0] * t[i, 0, 0] * e_mat[0, i]   # Staying in 0 State
    __pyx_t_13 = 0;
    __pyx_t_7 = -1;
    if (__pyx_t_13 < 0) {
      __pyx_t_7 = 0;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_bwd.shape[0])) __pyx_t_7 = 0;
    if (unlikely(__pyx_t_7 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_7);
      __PYX_ERR(0, 526, __pyx_L1_error)
    }
    __pyx_t_8 = __pyx_v_i;
    __pyx_t_6 = 0;
    __pyx_t_15 = 0;
    __pyx_t_7 = -1;
    if (__pyx_t_8 < 0) {
      __pyx_t_7 = 0;
    } else if (unlikely(__pyx_t_8 >= __pyx_v_t.shape[0])) __pyx_t_7 = 0;
    if (__pyx_t_6 < 0) {
      __pyx_t_7 = 1;
    } else if (unlikely(__pyx_t_6 >= __pyx_v_t.shape[1])) __pyx_t_7 = 1;
    if (__pyx_t_15 < 0) {
      __pyx_t_7 = 2;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t.shape[2])) __pyx_t_7 = 2;
    if (unlikely(__pyx_t_7 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_7);
      __PYX_ERR(0, 526, __pyx_L1_error)
    }
    __pyx_t_11 = 0;
    __pyx_t_14 = __pyx_v_i;
    __pyx_t_7 = -1;
    if (__pyx_t_11 < 0) {
      __pyx_t_7 = 0;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_e_mat.shape[0])) __pyx_t_7 = 0;
    if (__pyx_t_14 < 0) {
      __pyx_t_7 = 1;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_e_mat.shape[1])) __pyx_t_7 = 1;
    if (unlikely(__pyx_t_7 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_7);
      __PYX_ERR(0, 526, __pyx_L1_error)
    }
    __pyx_v_x1 = (((*((double *) ( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_13 * __pyx_v_bwd.strides[0]) ))) * (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_8 * __pyx_v_t.strides[0]) ) + __pyx_t_6 * __pyx_v_t.strides[1]) ) + __pyx_t_15 * __pyx_v_t.strides[2]) )))) * (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat.data + __pyx_t_11 * __pyx_v_e_mat.strides[0]) ) + __pyx_t_14 * __pyx_v_e_mat.strides[1]) ))));
+527:         x2 = f_l * t[i, 0, 1]                         # Going into 0 State
    __pyx_t_14 = __pyx_v_i;
    __pyx_t_11 = 0;
    __pyx_t_15 = 1;
    __pyx_t_7 = -1;
    if (__pyx_t_14 < 0) {
      __pyx_t_7 = 0;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_t.shape[0])) __pyx_t_7 = 0;
    if (__pyx_t_11 < 0) {
      __pyx_t_7 = 1;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_t.shape[1])) __pyx_t_7 = 1;
    if (__pyx_t_15 < 0) {
      __pyx_t_7 = 2;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t.shape[2])) __pyx_t_7 = 2;
    if (unlikely(__pyx_t_7 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_7);
      __PYX_ERR(0, 527, __pyx_L1_error)
    }
    __pyx_t_4 = PyFloat_FromDouble((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_14 * __pyx_v_t.strides[0]) ) + __pyx_t_11 * __pyx_v_t.strides[1]) ) + __pyx_t_15 * __pyx_v_t.strides[2]) )))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 527, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_1 = PyNumber_Multiply(__pyx_v_f_l, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 527, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_t_20 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_20 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 527, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_v_x2 = __pyx_t_20;
+528:         temp_v[0] = x1 + x2
    __pyx_t_15 = 0;
    __pyx_t_7 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_7 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_temp_v.shape[0])) __pyx_t_7 = 0;
    if (unlikely(__pyx_t_7 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_7);
      __PYX_ERR(0, 528, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_temp_v.data + __pyx_t_15 * __pyx_v_temp_v.strides[0]) )) = (__pyx_v_x1 + __pyx_v_x2);
 529: 
 530:       ### Do the other states
 531:       # Preprocessing:
+532:         x1 = e_mat[0, i] * bwd[0] * t[i, 1, 0]
    __pyx_t_15 = 0;
    __pyx_t_11 = __pyx_v_i;
    __pyx_t_7 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_7 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_e_mat.shape[0])) __pyx_t_7 = 0;
    if (__pyx_t_11 < 0) {
      __pyx_t_7 = 1;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_e_mat.shape[1])) __pyx_t_7 = 1;
    if (unlikely(__pyx_t_7 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_7);
      __PYX_ERR(0, 532, __pyx_L1_error)
    }
    __pyx_t_14 = 0;
    __pyx_t_7 = -1;
    if (__pyx_t_14 < 0) {
      __pyx_t_7 = 0;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_bwd.shape[0])) __pyx_t_7 = 0;
    if (unlikely(__pyx_t_7 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_7);
      __PYX_ERR(0, 532, __pyx_L1_error)
    }
    __pyx_t_6 = __pyx_v_i;
    __pyx_t_8 = 1;
    __pyx_t_13 = 0;
    __pyx_t_7 = -1;
    if (__pyx_t_6 < 0) {
      __pyx_t_7 = 0;
    } else if (unlikely(__pyx_t_6 >= __pyx_v_t.shape[0])) __pyx_t_7 = 0;
    if (__pyx_t_8 < 0) {
      __pyx_t_7 = 1;
    } else if (unlikely(__pyx_t_8 >= __pyx_v_t.shape[1])) __pyx_t_7 = 1;
    if (__pyx_t_13 < 0) {
      __pyx_t_7 = 2;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_t.shape[2])) __pyx_t_7 = 2;
    if (unlikely(__pyx_t_7 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_7);
      __PYX_ERR(0, 532, __pyx_L1_error)
    }
    __pyx_v_x1 = (((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat.data + __pyx_t_15 * __pyx_v_e_mat.strides[0]) ) + __pyx_t_11 * __pyx_v_e_mat.strides[1]) ))) * (*((double *) ( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_14 * __pyx_v_bwd.strides[0]) )))) * (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_6 * __pyx_v_t.strides[0]) ) + __pyx_t_8 * __pyx_v_t.strides[1]) ) + __pyx_t_13 * __pyx_v_t.strides[2]) ))));
+533:         x2 = f_l * t[i, 1, 2]    # Coming from other ROH State
    __pyx_t_13 = __pyx_v_i;
    __pyx_t_8 = 1;
    __pyx_t_6 = 2;
    __pyx_t_7 = -1;
    if (__pyx_t_13 < 0) {
      __pyx_t_7 = 0;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_t.shape[0])) __pyx_t_7 = 0;
    if (__pyx_t_8 < 0) {
      __pyx_t_7 = 1;
    } else if (unlikely(__pyx_t_8 >= __pyx_v_t.shape[1])) __pyx_t_7 = 1;
    if (__pyx_t_6 < 0) {
      __pyx_t_7 = 2;
    } else if (unlikely(__pyx_t_6 >= __pyx_v_t.shape[2])) __pyx_t_7 = 2;
    if (unlikely(__pyx_t_7 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_7);
      __PYX_ERR(0, 533, __pyx_L1_error)
    }
    __pyx_t_1 = PyFloat_FromDouble((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_13 * __pyx_v_t.strides[0]) ) + __pyx_t_8 * __pyx_v_t.strides[1]) ) + __pyx_t_6 * __pyx_v_t.strides[2]) )))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 533, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_4 = PyNumber_Multiply(__pyx_v_f_l, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 533, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_20 = __pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_20 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 533, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_v_x2 = __pyx_t_20;
 534: 
+535:         for j in range(1, n_states):  # Do the final run over all states
    __pyx_t_7 = __pyx_v_n_states;
    __pyx_t_9 = __pyx_t_7;
    for (__pyx_t_18 = 1; __pyx_t_18 < __pyx_t_9; __pyx_t_18+=1) {
      __pyx_v_j = __pyx_t_18;
+536:             x3 = e_mat[j, i] * bwd[j] *  stay
      __pyx_t_6 = __pyx_v_j;
      __pyx_t_8 = __pyx_v_i;
      __pyx_t_12 = -1;
      if (__pyx_t_6 < 0) {
        __pyx_t_12 = 0;
      } else if (unlikely(__pyx_t_6 >= __pyx_v_e_mat.shape[0])) __pyx_t_12 = 0;
      if (__pyx_t_8 < 0) {
        __pyx_t_12 = 1;
      } else if (unlikely(__pyx_t_8 >= __pyx_v_e_mat.shape[1])) __pyx_t_12 = 1;
      if (unlikely(__pyx_t_12 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_12);
        __PYX_ERR(0, 536, __pyx_L1_error)
      }
      __pyx_t_13 = __pyx_v_j;
      __pyx_t_12 = -1;
      if (__pyx_t_13 < 0) {
        __pyx_t_12 = 0;
      } else if (unlikely(__pyx_t_13 >= __pyx_v_bwd.shape[0])) __pyx_t_12 = 0;
      if (unlikely(__pyx_t_12 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_12);
        __PYX_ERR(0, 536, __pyx_L1_error)
      }
      __pyx_v_x3 = (((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat.data + __pyx_t_6 * __pyx_v_e_mat.strides[0]) ) + __pyx_t_8 * __pyx_v_e_mat.strides[1]) ))) * (*((double *) ( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_13 * __pyx_v_bwd.strides[0]) )))) * __pyx_v_stay);
+537:             temp_v[j] = x1 + x2 + x3  # Fill in the backward Probability
      __pyx_t_13 = __pyx_v_j;
      __pyx_t_12 = -1;
      if (__pyx_t_13 < 0) {
        __pyx_t_12 = 0;
      } else if (unlikely(__pyx_t_13 >= __pyx_v_temp_v.shape[0])) __pyx_t_12 = 0;
      if (unlikely(__pyx_t_12 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_12);
        __PYX_ERR(0, 537, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_temp_v.data + __pyx_t_13 * __pyx_v_temp_v.strides[0]) )) = ((__pyx_v_x1 + __pyx_v_x2) + __pyx_v_x3);
    }
 538: 
 539:         ### Do the normalization
+540:         for j in range(n_states):
    __pyx_t_7 = __pyx_v_n_states;
    __pyx_t_9 = __pyx_t_7;
    for (__pyx_t_18 = 0; __pyx_t_18 < __pyx_t_9; __pyx_t_18+=1) {
      __pyx_v_j = __pyx_t_18;
+541:             bwd[j] = temp_v[j] / c_view[i] # Rescale to prob. distribution
      __pyx_t_13 = __pyx_v_j;
      __pyx_t_12 = -1;
      if (__pyx_t_13 < 0) {
        __pyx_t_12 = 0;
      } else if (unlikely(__pyx_t_13 >= __pyx_v_temp_v.shape[0])) __pyx_t_12 = 0;
      if (unlikely(__pyx_t_12 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_12);
        __PYX_ERR(0, 541, __pyx_L1_error)
      }
      __pyx_t_20 = (*((double *) ( /* dim=0 */ (__pyx_v_temp_v.data + __pyx_t_13 * __pyx_v_temp_v.strides[0]) )));
      __pyx_t_13 = __pyx_v_i;
      __pyx_t_12 = -1;
      if (__pyx_t_13 < 0) {
        __pyx_t_12 = 0;
      } else if (unlikely(__pyx_t_13 >= __pyx_v_c_view.shape[0])) __pyx_t_12 = 0;
      if (unlikely(__pyx_t_12 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_12);
        __PYX_ERR(0, 541, __pyx_L1_error)
      }
      __pyx_t_16 = (*((double *) ( /* dim=0 */ (__pyx_v_c_view.data + __pyx_t_13 * __pyx_v_c_view.strides[0]) )));
      if (unlikely(__pyx_t_16 == 0)) {
        PyErr_SetString(PyExc_ZeroDivisionError, "float division");
        __PYX_ERR(0, 541, __pyx_L1_error)
      }
      __pyx_t_13 = __pyx_v_j;
      __pyx_t_12 = -1;
      if (__pyx_t_13 < 0) {
        __pyx_t_12 = 0;
      } else if (unlikely(__pyx_t_13 >= __pyx_v_bwd.shape[0])) __pyx_t_12 = 0;
      if (unlikely(__pyx_t_12 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_12);
        __PYX_ERR(0, 541, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_13 * __pyx_v_bwd.strides[0]) )) = (__pyx_t_20 / __pyx_t_16);
    }
 542: 
+543:         post_view[i-1] = post_view[i-1] * bwd[0]
    __pyx_t_13 = (__pyx_v_i - 1);
    __pyx_t_7 = -1;
    if (__pyx_t_13 < 0) {
      __pyx_t_7 = 0;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_post_view.shape[0])) __pyx_t_7 = 0;
    if (unlikely(__pyx_t_7 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_7);
      __PYX_ERR(0, 543, __pyx_L1_error)
    }
    __pyx_t_8 = 0;
    __pyx_t_7 = -1;
    if (__pyx_t_8 < 0) {
      __pyx_t_7 = 0;
    } else if (unlikely(__pyx_t_8 >= __pyx_v_bwd.shape[0])) __pyx_t_7 = 0;
    if (unlikely(__pyx_t_7 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_7);
      __PYX_ERR(0, 543, __pyx_L1_error)
    }
    __pyx_t_6 = (__pyx_v_i - 1);
    __pyx_t_7 = -1;
    if (__pyx_t_6 < 0) {
      __pyx_t_7 = 0;
    } else if (unlikely(__pyx_t_6 >= __pyx_v_post_view.shape[0])) __pyx_t_7 = 0;
    if (unlikely(__pyx_t_7 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_7);
      __PYX_ERR(0, 543, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_post_view.data + __pyx_t_6 * __pyx_v_post_view.strides[0]) )) = ((*((double *) ( /* dim=0 */ (__pyx_v_post_view.data + __pyx_t_13 * __pyx_v_post_view.strides[0]) ))) * (*((double *) ( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_8 * __pyx_v_bwd.strides[0]) ))));
  }
 544: 
 545:     ### Combine the forward and backward calculations for posterior
 546:     #post = fwd1 * bwd1
 547: 
+548:     if output:
  __pyx_t_21 = __Pyx_PyObject_IsTrue(__pyx_v_output); if (unlikely(__pyx_t_21 < 0)) __PYX_ERR(0, 548, __pyx_L1_error)
  if (__pyx_t_21) {
/* … */
  }
+549:         print("Memory Usage at end of HMM:")
    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_print, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 549, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+550:         print_memory_usage()   ## For MEMORY_BENCH
    __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_print_memory_usage); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 550, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_3 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_1))) {
      __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1);
      if (likely(__pyx_t_3)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
        __Pyx_INCREF(__pyx_t_3);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_1, function);
      }
    }
    __pyx_t_4 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_1);
    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 550, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+551:         tot_ll = np.sum(np.log(c)) # Tot Likelihood is product over all c.
    __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 551, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_sum); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 551, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 551, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_22 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_log); if (unlikely(!__pyx_t_22)) __PYX_ERR(0, 551, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_22);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_2 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_22))) {
      __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_22);
      if (likely(__pyx_t_2)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_22);
        __Pyx_INCREF(__pyx_t_2);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_22, function);
      }
    }
    __pyx_t_1 = (__pyx_t_2) ? __Pyx_PyObject_Call2Args(__pyx_t_22, __pyx_t_2, __pyx_v_c) : __Pyx_PyObject_CallOneArg(__pyx_t_22, __pyx_v_c);
    __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 551, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_22); __pyx_t_22 = 0;
    __pyx_t_22 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
      __pyx_t_22 = PyMethod_GET_SELF(__pyx_t_3);
      if (likely(__pyx_t_22)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
        __Pyx_INCREF(__pyx_t_22);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_3, function);
      }
    }
    __pyx_t_4 = (__pyx_t_22) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_22, __pyx_t_1) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_1);
    __Pyx_XDECREF(__pyx_t_22); __pyx_t_22 = 0;
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 551, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __pyx_v_tot_ll = __pyx_t_4;
    __pyx_t_4 = 0;
+552:         print(f"Total Log likelihood: {tot_ll: .3f}")
    __pyx_t_4 = __Pyx_PyObject_Format(__pyx_v_tot_ll, __pyx_kp_u_3f); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 552, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_3 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Total_Log_likelihood, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 552, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 552, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 553: 
+554:     if full:   # Return everything
  __pyx_t_21 = __Pyx_PyObject_IsTrue(__pyx_v_full); if (unlikely(__pyx_t_21 < 0)) __PYX_ERR(0, 554, __pyx_L1_error)
  if (__pyx_t_21) {
/* … */
  }
+555:         tot_ll = np.sum(np.log(c)) # Tot Likelihood is product over all c. 
    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 555, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_sum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 555, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_GetModuleGlobalName(__pyx_t_22, __pyx_n_s_np); if (unlikely(!__pyx_t_22)) __PYX_ERR(0, 555, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_22);
    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_22, __pyx_n_s_log); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 555, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_22); __pyx_t_22 = 0;
    __pyx_t_22 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
      __pyx_t_22 = PyMethod_GET_SELF(__pyx_t_2);
      if (likely(__pyx_t_22)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
        __Pyx_INCREF(__pyx_t_22);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_2, function);
      }
    }
    __pyx_t_3 = (__pyx_t_22) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_22, __pyx_v_c) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_c);
    __Pyx_XDECREF(__pyx_t_22); __pyx_t_22 = 0;
    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 555, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_2 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_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, 555, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __Pyx_XDECREF_SET(__pyx_v_tot_ll, __pyx_t_4);
    __pyx_t_4 = 0;
+556:         if output:
    __pyx_t_21 = __Pyx_PyObject_IsTrue(__pyx_v_output); if (unlikely(__pyx_t_21 < 0)) __PYX_ERR(0, 556, __pyx_L1_error)
    if (__pyx_t_21) {
/* … */
    }
+557:             print(f"Total Log likelihood: {tot_ll: .3f}")
      __pyx_t_4 = __Pyx_PyObject_Format(__pyx_v_tot_ll, __pyx_kp_u_3f); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 557, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __pyx_t_1 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Total_Log_likelihood, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 557, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 557, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+558:         return post[None,:], fwd0, bwd0, tot_ll
    __Pyx_XDECREF(__pyx_r);
    __pyx_t_4 = __Pyx_PyObject_GetItem(__pyx_v_post, __pyx_tuple__9); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 558, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_1 = PyTuple_New(4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 558, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_GIVEREF(__pyx_t_4);
    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_4);
    __Pyx_INCREF(__pyx_v_fwd0);
    __Pyx_GIVEREF(__pyx_v_fwd0);
    PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_fwd0);
    __Pyx_INCREF(__pyx_v_bwd0);
    __Pyx_GIVEREF(__pyx_v_bwd0);
    PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_bwd0);
    __Pyx_INCREF(__pyx_v_tot_ll);
    __Pyx_GIVEREF(__pyx_v_tot_ll);
    PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_v_tot_ll);
    __pyx_t_4 = 0;
    __pyx_r = __pyx_t_1;
    __pyx_t_1 = 0;
    goto __pyx_L0;
 559: 
 560:     else:
+561:         return post[None,:]
  /*else*/ {
    __Pyx_XDECREF(__pyx_r);
    __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_post, __pyx_tuple__9); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 561, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_r = __pyx_t_1;
    __pyx_t_1 = 0;
    goto __pyx_L0;
  }
 562: 
 563: 
 564: ######################### Yilei  ##############################
 565: # returns total loglikelihood, copied from fwd_bkwd_scaled_lowmem but without the backward iteration
+566: def fwd(double[:, :] e_mat, double[:, :, :] t_mat, double in_val = 1e-4):
/* Python wrapper */
static PyObject *__pyx_pw_8hapsburg_5cfunc_11fwd(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_8hapsburg_5cfunc_11fwd = {"fwd", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_8hapsburg_5cfunc_11fwd, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_8hapsburg_5cfunc_11fwd(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  __Pyx_memviewslice __pyx_v_e_mat = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_t_mat = { 0, 0, { 0 }, { 0 }, { 0 } };
  CYTHON_UNUSED double __pyx_v_in_val;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("fwd (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_e_mat,&__pyx_n_s_t_mat,&__pyx_n_s_in_val,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_e_mat)) != 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_t_mat)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("fwd", 0, 2, 3, 1); __PYX_ERR(0, 566, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_in_val);
          if (value) { values[2] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "fwd") < 0)) __PYX_ERR(0, 566, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_e_mat = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(values[0], PyBUF_WRITABLE); if (unlikely(!__pyx_v_e_mat.memview)) __PYX_ERR(0, 566, __pyx_L3_error)
    __pyx_v_t_mat = __Pyx_PyObject_to_MemoryviewSlice_dsdsds_double(values[1], PyBUF_WRITABLE); if (unlikely(!__pyx_v_t_mat.memview)) __PYX_ERR(0, 566, __pyx_L3_error)
    if (values[2]) {
      __pyx_v_in_val = __pyx_PyFloat_AsDouble(values[2]); if (unlikely((__pyx_v_in_val == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 566, __pyx_L3_error)
    } else {
      __pyx_v_in_val = ((double)1e-4);
    }
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("fwd", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 566, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("hapsburg.cfunc.fwd", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_8hapsburg_5cfunc_10fwd(__pyx_self, __pyx_v_e_mat, __pyx_v_t_mat, __pyx_v_in_val);
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;

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

static PyObject *__pyx_pf_8hapsburg_5cfunc_10fwd(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_e_mat, __Pyx_memviewslice __pyx_v_t_mat, CYTHON_UNUSED double __pyx_v_in_val) {
  int __pyx_v_n_states;
  int __pyx_v_n_loci;
  Py_ssize_t __pyx_v_i;
  Py_ssize_t __pyx_v_j;
  double __pyx_v_stay;
  double __pyx_v_x1;
  double __pyx_v_x2;
  double __pyx_v_x3;
  PyObject *__pyx_v_temp = NULL;
  __Pyx_memviewslice __pyx_v_temp_v = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_temp1 = NULL;
  CYTHON_UNUSED __Pyx_memviewslice __pyx_v_temp1_v = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_t = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_c = NULL;
  __Pyx_memviewslice __pyx_v_c_view = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_fwd0 = NULL;
  __Pyx_memviewslice __pyx_v_fwd = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_tmp0 = NULL;
  CYTHON_UNUSED __Pyx_memviewslice __pyx_v_tmp = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_f_l = NULL;
  PyObject *__pyx_v_tot_ll = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("fwd", 0);
/* … */
  /* 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_22);
  __Pyx_AddTraceback("hapsburg.cfunc.fwd", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_temp);
  __PYX_XDEC_MEMVIEW(&__pyx_v_temp_v, 1);
  __Pyx_XDECREF(__pyx_v_temp1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_temp1_v, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_t, 1);
  __Pyx_XDECREF(__pyx_v_c);
  __PYX_XDEC_MEMVIEW(&__pyx_v_c_view, 1);
  __Pyx_XDECREF(__pyx_v_fwd0);
  __PYX_XDEC_MEMVIEW(&__pyx_v_fwd, 1);
  __Pyx_XDECREF(__pyx_v_tmp0);
  __PYX_XDEC_MEMVIEW(&__pyx_v_tmp, 1);
  __Pyx_XDECREF(__pyx_v_f_l);
  __Pyx_XDECREF(__pyx_v_tot_ll);
  __PYX_XDEC_MEMVIEW(&__pyx_v_e_mat, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_t_mat, 1);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__38 = PyTuple_Pack(25, __pyx_n_s_e_mat, __pyx_n_s_t_mat, __pyx_n_s_in_val, __pyx_n_s_n_states, __pyx_n_s_n_loci, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_k, __pyx_n_s_stay, __pyx_n_s_x1, __pyx_n_s_x2, __pyx_n_s_x3, __pyx_n_s_temp, __pyx_n_s_temp_v, __pyx_n_s_temp1, __pyx_n_s_temp1_v, __pyx_n_s_t, __pyx_n_s_c, __pyx_n_s_c_view, __pyx_n_s_fwd0, __pyx_n_s_fwd, __pyx_n_s_tmp0, __pyx_n_s_tmp, __pyx_n_s_f_l, __pyx_n_s_tot_ll); if (unlikely(!__pyx_tuple__38)) __PYX_ERR(0, 566, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__38);
  __Pyx_GIVEREF(__pyx_tuple__38);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_8hapsburg_5cfunc_11fwd, NULL, __pyx_n_s_hapsburg_cfunc); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 566, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_fwd, __pyx_t_2) < 0) __PYX_ERR(0, 566, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__39 = (PyObject*)__Pyx_PyCode_New(3, 0, 25, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__38, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_hapsburg_cfunc_pyx, __pyx_n_s_fwd, 566, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__39)) __PYX_ERR(0, 566, __pyx_L1_error)
+567:     cdef int n_states = e_mat.shape[0]
  __pyx_v_n_states = (__pyx_v_e_mat.shape[0]);
+568:     cdef int n_loci = e_mat.shape[1]
  __pyx_v_n_loci = (__pyx_v_e_mat.shape[1]);
 569:     cdef Py_ssize_t i, j, k    # The Array and Iteration Indices
 570:     cdef double stay           # The Probablility of Staying
 571:     cdef double x1, x2, x3     # Place holder variables [make code readable]
 572: 
 573:     # Initialize Posterior and Transition Probabilities
+574:     temp = np.empty(n_states, dtype=DTYPE) # l Array for calculations
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 574, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 574, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_n_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 574, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 574, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
  __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 574, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 574, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_4) < 0) __PYX_ERR(0, 574, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 574, __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_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_temp = __pyx_t_4;
  __pyx_t_4 = 0;
+575:     cdef double[:] temp_v = temp
  __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_temp, PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 575, __pyx_L1_error)
  __pyx_v_temp_v = __pyx_t_5;
  __pyx_t_5.memview = NULL;
  __pyx_t_5.data = NULL;
 576: 
+577:     temp1 = np.empty(n_states-1, dtype=DTYPE) # l-1 Array for calculatons
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 577, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_empty); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 577, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyInt_From_long((__pyx_v_n_states - 1)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 577, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 577, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
  __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 577, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 577, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_2) < 0) __PYX_ERR(0, 577, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 577, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_v_temp1 = __pyx_t_2;
  __pyx_t_2 = 0;
+578:     cdef double[:] temp1_v = temp1
  __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_temp1, PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 578, __pyx_L1_error)
  __pyx_v_temp1_v = __pyx_t_5;
  __pyx_t_5.memview = NULL;
  __pyx_t_5.data = NULL;
 579: 
+580:     cdef double[:,:,:] t = t_mat   # C View of transition matrix
  __PYX_INC_MEMVIEW(&__pyx_v_t_mat, 0);
  __pyx_v_t = __pyx_v_t_mat;
 581: 
+582:     c = np.empty(n_loci, dtype=DTYPE) # Array of normalization constants
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 582, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 582, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_n_loci); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 582, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 582, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_2);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
  __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 582, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 582, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_1) < 0) __PYX_ERR(0, 582, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 582, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_c = __pyx_t_1;
  __pyx_t_1 = 0;
+583:     cdef double[:] c_view = c
  __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_c, PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 583, __pyx_L1_error)
  __pyx_v_c_view = __pyx_t_5;
  __pyx_t_5.memview = NULL;
  __pyx_t_5.data = NULL;
+584:     c_view[0] = 1 # Set the first normalization constant
  __pyx_t_6 = 0;
  __pyx_t_7 = -1;
  if (__pyx_t_6 < 0) {
    __pyx_t_7 = 0;
  } else if (unlikely(__pyx_t_6 >= __pyx_v_c_view.shape[0])) __pyx_t_7 = 0;
  if (unlikely(__pyx_t_7 != -1)) {
    __Pyx_RaiseBufferIndexError(__pyx_t_7);
    __PYX_ERR(0, 584, __pyx_L1_error)
  }
  *((double *) ( /* dim=0 */ (__pyx_v_c_view.data + __pyx_t_6 * __pyx_v_c_view.strides[0]) )) = 1.0;
 585: 
 586:     #############################
 587:     ### Initialize FWD Arrays
+588:     fwd0 = np.zeros(n_states, dtype=DTYPE)
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 588, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_zeros); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 588, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_n_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 588, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 588, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
  __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 588, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 588, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_4) < 0) __PYX_ERR(0, 588, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 588, __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_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_fwd0 = __pyx_t_4;
  __pyx_t_4 = 0;
 589:     #fwd0[:] = in_val  # Initial Probabilities
 590:     #fwd0[0] = 1 - (n_states - 1) * in_val
+591:     fwd0[:] = 1/(n_states - 1)
  __pyx_t_8 = (__pyx_v_n_states - 1);
  if (unlikely(__pyx_t_8 == 0)) {
    PyErr_SetString(PyExc_ZeroDivisionError, "float division");
    __PYX_ERR(0, 591, __pyx_L1_error)
  }
  __pyx_t_4 = PyFloat_FromDouble((1.0 / ((double)__pyx_t_8))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 591, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (__Pyx_PyObject_SetSlice(__pyx_v_fwd0, __pyx_t_4, 0, 0, NULL, NULL, &__pyx_slice__3, 0, 0, 0) < 0) __PYX_ERR(0, 591, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+592:     fwd0[0] = 0
  if (unlikely(__Pyx_SetItemInt(__pyx_v_fwd0, 0, __pyx_int_0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1) < 0)) __PYX_ERR(0, 592, __pyx_L1_error)
+593:     cdef double[:] fwd = fwd0
  __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_fwd0, PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 593, __pyx_L1_error)
  __pyx_v_fwd = __pyx_t_5;
  __pyx_t_5.memview = NULL;
  __pyx_t_5.data = NULL;
 594: 
+595:     tmp0 = np.zeros(n_states, dtype=DTYPE)
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 595, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_zeros); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 595, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_n_states); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 595, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 595, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
  __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 595, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 595, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_2) < 0) __PYX_ERR(0, 595, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 595, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_v_tmp0 = __pyx_t_2;
  __pyx_t_2 = 0;
+596:     cdef double[:] tmp = tmp0
  __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_tmp0, PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 596, __pyx_L1_error)
  __pyx_v_tmp = __pyx_t_5;
  __pyx_t_5.memview = NULL;
  __pyx_t_5.data = NULL;
 597: 
 598:     #############################
 599:     ### Do the Forward Algorithm    
+600:     for i in range(1, n_loci):  # Run forward recursion
  __pyx_t_7 = __pyx_v_n_loci;
  __pyx_t_9 = __pyx_t_7;
  for (__pyx_t_10 = 1; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
    __pyx_v_i = __pyx_t_10;
+601:         stay = t[i, 1, 1] - t[i, 1, 2]  # Do the log of the Stay term
    __pyx_t_6 = __pyx_v_i;
    __pyx_t_11 = 1;
    __pyx_t_12 = 1;
    __pyx_t_13 = -1;
    if (__pyx_t_6 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_6 >= __pyx_v_t.shape[0])) __pyx_t_13 = 0;
    if (__pyx_t_11 < 0) {
      __pyx_t_13 = 1;
    } else if (unlikely(__pyx_t_11 >= __pyx_v_t.shape[1])) __pyx_t_13 = 1;
    if (__pyx_t_12 < 0) {
      __pyx_t_13 = 2;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_t.shape[2])) __pyx_t_13 = 2;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 601, __pyx_L1_error)
    }
    __pyx_t_14 = __pyx_v_i;
    __pyx_t_15 = 1;
    __pyx_t_16 = 2;
    __pyx_t_13 = -1;
    if (__pyx_t_14 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_t.shape[0])) __pyx_t_13 = 0;
    if (__pyx_t_15 < 0) {
      __pyx_t_13 = 1;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t.shape[1])) __pyx_t_13 = 1;
    if (__pyx_t_16 < 0) {
      __pyx_t_13 = 2;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t.shape[2])) __pyx_t_13 = 2;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 601, __pyx_L1_error)
    }
    __pyx_v_stay = ((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_6 * __pyx_v_t.strides[0]) ) + __pyx_t_11 * __pyx_v_t.strides[1]) ) + __pyx_t_12 * __pyx_v_t.strides[2]) ))) - (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_14 * __pyx_v_t.strides[0]) ) + __pyx_t_15 * __pyx_v_t.strides[1]) ) + __pyx_t_16 * __pyx_v_t.strides[2]) ))));
 602: 
 603:         #for k in range(1, n_states): # Calculate Sum of ROH states. 
+604:         f_l = 1 - fwd[0]  ### Assume they are normalized!!!
    __pyx_t_16 = 0;
    __pyx_t_13 = -1;
    if (__pyx_t_16 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_fwd.shape[0])) __pyx_t_13 = 0;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 604, __pyx_L1_error)
    }
    __pyx_t_2 = PyFloat_FromDouble((1.0 - (*((double *) ( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_16 * __pyx_v_fwd.strides[0]) ))))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 604, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_XDECREF_SET(__pyx_v_f_l, __pyx_t_2);
    __pyx_t_2 = 0;
 605: 
 606:         ### Do the 0 State:
+607:         x1 = fwd[0] * t[i, 0, 0]    # Staying in 0 State
    __pyx_t_16 = 0;
    __pyx_t_13 = -1;
    if (__pyx_t_16 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_fwd.shape[0])) __pyx_t_13 = 0;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 607, __pyx_L1_error)
    }
    __pyx_t_15 = __pyx_v_i;
    __pyx_t_14 = 0;
    __pyx_t_12 = 0;
    __pyx_t_13 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t.shape[0])) __pyx_t_13 = 0;
    if (__pyx_t_14 < 0) {
      __pyx_t_13 = 1;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_t.shape[1])) __pyx_t_13 = 1;
    if (__pyx_t_12 < 0) {
      __pyx_t_13 = 2;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_t.shape[2])) __pyx_t_13 = 2;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 607, __pyx_L1_error)
    }
    __pyx_v_x1 = ((*((double *) ( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_16 * __pyx_v_fwd.strides[0]) ))) * (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_15 * __pyx_v_t.strides[0]) ) + __pyx_t_14 * __pyx_v_t.strides[1]) ) + __pyx_t_12 * __pyx_v_t.strides[2]) ))));
+608:         x2 = f_l * t[i, 1, 0]               # Going into 0 State from any other
    __pyx_t_12 = __pyx_v_i;
    __pyx_t_14 = 1;
    __pyx_t_15 = 0;
    __pyx_t_13 = -1;
    if (__pyx_t_12 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_t.shape[0])) __pyx_t_13 = 0;
    if (__pyx_t_14 < 0) {
      __pyx_t_13 = 1;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_t.shape[1])) __pyx_t_13 = 1;
    if (__pyx_t_15 < 0) {
      __pyx_t_13 = 2;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t.shape[2])) __pyx_t_13 = 2;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 608, __pyx_L1_error)
    }
    __pyx_t_2 = PyFloat_FromDouble((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_12 * __pyx_v_t.strides[0]) ) + __pyx_t_14 * __pyx_v_t.strides[1]) ) + __pyx_t_15 * __pyx_v_t.strides[2]) )))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 608, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_4 = PyNumber_Multiply(__pyx_v_f_l, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 608, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_17 = __pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_17 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 608, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_v_x2 = __pyx_t_17;
+609:         temp_v[0] = e_mat[0, i] * (x1 + x2) # Set the unnorm. 0 forward variable
    __pyx_t_15 = 0;
    __pyx_t_14 = __pyx_v_i;
    __pyx_t_13 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_e_mat.shape[0])) __pyx_t_13 = 0;
    if (__pyx_t_14 < 0) {
      __pyx_t_13 = 1;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_e_mat.shape[1])) __pyx_t_13 = 1;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 609, __pyx_L1_error)
    }
    __pyx_t_12 = 0;
    __pyx_t_13 = -1;
    if (__pyx_t_12 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_temp_v.shape[0])) __pyx_t_13 = 0;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 609, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_temp_v.data + __pyx_t_12 * __pyx_v_temp_v.strides[0]) )) = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat.data + __pyx_t_15 * __pyx_v_e_mat.strides[0]) ) + __pyx_t_14 * __pyx_v_e_mat.strides[1]) ))) * (__pyx_v_x1 + __pyx_v_x2));
 610: 
 611:         ### Do the other states
 612:         # Preprocessing:
+613:         x1 = fwd[0] * t[i, 0, 1]   # Coming from 0 State
    __pyx_t_14 = 0;
    __pyx_t_13 = -1;
    if (__pyx_t_14 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_14 >= __pyx_v_fwd.shape[0])) __pyx_t_13 = 0;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 613, __pyx_L1_error)
    }
    __pyx_t_15 = __pyx_v_i;
    __pyx_t_12 = 0;
    __pyx_t_16 = 1;
    __pyx_t_13 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t.shape[0])) __pyx_t_13 = 0;
    if (__pyx_t_12 < 0) {
      __pyx_t_13 = 1;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_t.shape[1])) __pyx_t_13 = 1;
    if (__pyx_t_16 < 0) {
      __pyx_t_13 = 2;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t.shape[2])) __pyx_t_13 = 2;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 613, __pyx_L1_error)
    }
    __pyx_v_x1 = ((*((double *) ( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_14 * __pyx_v_fwd.strides[0]) ))) * (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_15 * __pyx_v_t.strides[0]) ) + __pyx_t_12 * __pyx_v_t.strides[1]) ) + __pyx_t_16 * __pyx_v_t.strides[2]) ))));
+614:         x2 = f_l * t[i, 1, 2]             # Coming from other ROH State
    __pyx_t_16 = __pyx_v_i;
    __pyx_t_12 = 1;
    __pyx_t_15 = 2;
    __pyx_t_13 = -1;
    if (__pyx_t_16 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t.shape[0])) __pyx_t_13 = 0;
    if (__pyx_t_12 < 0) {
      __pyx_t_13 = 1;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_t.shape[1])) __pyx_t_13 = 1;
    if (__pyx_t_15 < 0) {
      __pyx_t_13 = 2;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t.shape[2])) __pyx_t_13 = 2;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 614, __pyx_L1_error)
    }
    __pyx_t_4 = PyFloat_FromDouble((*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t.data + __pyx_t_16 * __pyx_v_t.strides[0]) ) + __pyx_t_12 * __pyx_v_t.strides[1]) ) + __pyx_t_15 * __pyx_v_t.strides[2]) )))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 614, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_2 = PyNumber_Multiply(__pyx_v_f_l, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 614, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_t_17 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_17 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 614, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_v_x2 = __pyx_t_17;
 615: 
+616:         for j in range(1, n_states):  # Do the final run over all states
    __pyx_t_13 = __pyx_v_n_states;
    __pyx_t_18 = __pyx_t_13;
    for (__pyx_t_19 = 1; __pyx_t_19 < __pyx_t_18; __pyx_t_19+=1) {
      __pyx_v_j = __pyx_t_19;
+617:             x3 = fwd[j] *  stay # Staying in state
      __pyx_t_15 = __pyx_v_j;
      __pyx_t_20 = -1;
      if (__pyx_t_15 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_15 >= __pyx_v_fwd.shape[0])) __pyx_t_20 = 0;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 617, __pyx_L1_error)
      }
      __pyx_v_x3 = ((*((double *) ( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_15 * __pyx_v_fwd.strides[0]) ))) * __pyx_v_stay);
+618:             temp_v[j] = e_mat[j, i] * (x1 + x2 + x3)
      __pyx_t_15 = __pyx_v_j;
      __pyx_t_12 = __pyx_v_i;
      __pyx_t_20 = -1;
      if (__pyx_t_15 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_15 >= __pyx_v_e_mat.shape[0])) __pyx_t_20 = 0;
      if (__pyx_t_12 < 0) {
        __pyx_t_20 = 1;
      } else if (unlikely(__pyx_t_12 >= __pyx_v_e_mat.shape[1])) __pyx_t_20 = 1;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 618, __pyx_L1_error)
      }
      __pyx_t_16 = __pyx_v_j;
      __pyx_t_20 = -1;
      if (__pyx_t_16 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_16 >= __pyx_v_temp_v.shape[0])) __pyx_t_20 = 0;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 618, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_temp_v.data + __pyx_t_16 * __pyx_v_temp_v.strides[0]) )) = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_mat.data + __pyx_t_15 * __pyx_v_e_mat.strides[0]) ) + __pyx_t_12 * __pyx_v_e_mat.strides[1]) ))) * ((__pyx_v_x1 + __pyx_v_x2) + __pyx_v_x3));
    }
 619: 
 620:         ### Do the normalization and set up the forward array for next step
+621:         c_view[i] = sum_array(temp_v, n_states)
    __pyx_t_12 = __pyx_v_i;
    __pyx_t_13 = -1;
    if (__pyx_t_12 < 0) {
      __pyx_t_13 = 0;
    } else if (unlikely(__pyx_t_12 >= __pyx_v_c_view.shape[0])) __pyx_t_13 = 0;
    if (unlikely(__pyx_t_13 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_13);
      __PYX_ERR(0, 621, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_c_view.data + __pyx_t_12 * __pyx_v_c_view.strides[0]) )) = __pyx_f_8hapsburg_5cfunc_sum_array(__pyx_v_temp_v, __pyx_v_n_states);
+622:         for j in range(n_states):
    __pyx_t_13 = __pyx_v_n_states;
    __pyx_t_18 = __pyx_t_13;
    for (__pyx_t_19 = 0; __pyx_t_19 < __pyx_t_18; __pyx_t_19+=1) {
      __pyx_v_j = __pyx_t_19;
+623:             fwd[j] = temp_v[j] / c_view[i] # Rescale to prob. distribution
      __pyx_t_12 = __pyx_v_j;
      __pyx_t_20 = -1;
      if (__pyx_t_12 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_12 >= __pyx_v_temp_v.shape[0])) __pyx_t_20 = 0;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 623, __pyx_L1_error)
      }
      __pyx_t_17 = (*((double *) ( /* dim=0 */ (__pyx_v_temp_v.data + __pyx_t_12 * __pyx_v_temp_v.strides[0]) )));
      __pyx_t_12 = __pyx_v_i;
      __pyx_t_20 = -1;
      if (__pyx_t_12 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_12 >= __pyx_v_c_view.shape[0])) __pyx_t_20 = 0;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 623, __pyx_L1_error)
      }
      __pyx_t_21 = (*((double *) ( /* dim=0 */ (__pyx_v_c_view.data + __pyx_t_12 * __pyx_v_c_view.strides[0]) )));
      if (unlikely(__pyx_t_21 == 0)) {
        PyErr_SetString(PyExc_ZeroDivisionError, "float division");
        __PYX_ERR(0, 623, __pyx_L1_error)
      }
      __pyx_t_12 = __pyx_v_j;
      __pyx_t_20 = -1;
      if (__pyx_t_12 < 0) {
        __pyx_t_20 = 0;
      } else if (unlikely(__pyx_t_12 >= __pyx_v_fwd.shape[0])) __pyx_t_20 = 0;
      if (unlikely(__pyx_t_20 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_20);
        __PYX_ERR(0, 623, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_12 * __pyx_v_fwd.strides[0]) )) = (__pyx_t_17 / __pyx_t_21);
    }
  }
 624: 
+625:     tot_ll = np.sum(np.log(c)) # Tot Likelihood is product over all c.
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 625, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_sum); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 625, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 625, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_22 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_log); if (unlikely(!__pyx_t_22)) __PYX_ERR(0, 625, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_22);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_22))) {
    __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_22);
    if (likely(__pyx_t_1)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_22);
      __Pyx_INCREF(__pyx_t_1);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_22, function);
    }
  }
  __pyx_t_4 = (__pyx_t_1) ? __Pyx_PyObject_Call2Args(__pyx_t_22, __pyx_t_1, __pyx_v_c) : __Pyx_PyObject_CallOneArg(__pyx_t_22, __pyx_v_c);
  __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 625, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_22); __pyx_t_22 = 0;
  __pyx_t_22 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
    __pyx_t_22 = PyMethod_GET_SELF(__pyx_t_3);
    if (likely(__pyx_t_22)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
      __Pyx_INCREF(__pyx_t_22);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_3, function);
    }
  }
  __pyx_t_2 = (__pyx_t_22) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_22, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4);
  __Pyx_XDECREF(__pyx_t_22); __pyx_t_22 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 625, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_v_tot_ll = __pyx_t_2;
  __pyx_t_2 = 0;
+626:     return tot_ll
  __Pyx_XDECREF(__pyx_r);
  __Pyx_INCREF(__pyx_v_tot_ll);
  __pyx_r = __pyx_v_tot_ll;
  goto __pyx_L0;
 627: 
 628: ####################### End of Yilei ##########################
 629: 
 630: 
 631: 
 632: 
 633: 
 634: ###################################################################################
 635: ###################################################################################
 636: #### LEGACY FUNCTIONS [NOT INT PRODUCTION ANYMORE]
 637: 
+638: def fwd_bkwd(double[:, :] e_prob0, double[:, :] t_mat,
/* Python wrapper */
static PyObject *__pyx_pw_8hapsburg_5cfunc_13fwd_bkwd(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_8hapsburg_5cfunc_12fwd_bkwd[] = "Takes emission and transition probabilities, and calculates posteriors.\n    Input: kxl matrices of emission, transition\n    and initialized fwd and bwd probabilities. Given in log Space\n    full: Boolean whether to return everything.\n    LEGACY: This was the first implementation, using the full algorithm. SLOW!!";
static PyMethodDef __pyx_mdef_8hapsburg_5cfunc_13fwd_bkwd = {"fwd_bkwd", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_8hapsburg_5cfunc_13fwd_bkwd, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8hapsburg_5cfunc_12fwd_bkwd};
static PyObject *__pyx_pw_8hapsburg_5cfunc_13fwd_bkwd(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  __Pyx_memviewslice __pyx_v_e_prob0 = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_t_mat = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_fwd = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_bwd = { 0, 0, { 0 }, { 0 }, { 0 } };
  CYTHON_UNUSED __Pyx_memviewslice __pyx_v_t = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_full = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("fwd_bkwd (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_e_prob0,&__pyx_n_s_t_mat,&__pyx_n_s_fwd,&__pyx_n_s_bwd,&__pyx_n_s_t,&__pyx_n_s_full,0};
    PyObject* values[6] = {0,0,0,0,0,0};
/* … */
  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_8hapsburg_5cfunc_12fwd_bkwd(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_e_prob0, __Pyx_memviewslice __pyx_v_t_mat, __Pyx_memviewslice __pyx_v_fwd, __Pyx_memviewslice __pyx_v_bwd, CYTHON_UNUSED __Pyx_memviewslice __pyx_v_t, PyObject *__pyx_v_full) {
  int __pyx_v_n_states;
  int __pyx_v_n_loci;
  Py_ssize_t __pyx_v_i;
  Py_ssize_t __pyx_v_j;
  Py_ssize_t __pyx_v_k;
  PyObject *__pyx_v_post = NULL;
  PyObject *__pyx_v_trans_ll = NULL;
  __Pyx_memviewslice __pyx_v_trans_ll_view = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_t_mat0 = { 0, 0, { 0 }, { 0 }, { 0 } };
  double __pyx_v_tot_ll;
  PyObject *__pyx_v_fwd1 = NULL;
  PyObject *__pyx_v_bwd1 = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("fwd_bkwd", 0);
/* … */
  /* function exit code */
  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  goto __pyx_L0;
  __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_6);
  __Pyx_XDECREF(__pyx_t_7);
  __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);
  __Pyx_AddTraceback("hapsburg.cfunc.fwd_bkwd", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_post);
  __Pyx_XDECREF(__pyx_v_trans_ll);
  __PYX_XDEC_MEMVIEW(&__pyx_v_trans_ll_view, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_t_mat0, 1);
  __Pyx_XDECREF(__pyx_v_fwd1);
  __Pyx_XDECREF(__pyx_v_bwd1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_e_prob0, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_t_mat, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_fwd, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_bwd, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_t, 1);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__40 = PyTuple_Pack(18, __pyx_n_s_e_prob0, __pyx_n_s_t_mat, __pyx_n_s_fwd, __pyx_n_s_bwd, __pyx_n_s_t, __pyx_n_s_full, __pyx_n_s_n_states, __pyx_n_s_n_loci, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_k, __pyx_n_s_post, __pyx_n_s_trans_ll, __pyx_n_s_trans_ll_view, __pyx_n_s_t_mat0, __pyx_n_s_tot_ll, __pyx_n_s_fwd1, __pyx_n_s_bwd1); if (unlikely(!__pyx_tuple__40)) __PYX_ERR(0, 638, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__40);
  __Pyx_GIVEREF(__pyx_tuple__40);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_8hapsburg_5cfunc_13fwd_bkwd, NULL, __pyx_n_s_hapsburg_cfunc); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 638, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_fwd_bkwd, __pyx_t_2) < 0) __PYX_ERR(0, 638, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__41 = (PyObject*)__Pyx_PyCode_New(6, 0, 18, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__40, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_hapsburg_cfunc_pyx, __pyx_n_s_fwd_bkwd, 638, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__41)) __PYX_ERR(0, 638, __pyx_L1_error)
+639:     double[:, :] fwd, double[:, :] bwd, double[:,:,:] t, full=False):
    values[5] = ((PyObject *)Py_False);
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        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_e_prob0)) != 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_t_mat)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("fwd_bkwd", 0, 5, 6, 1); __PYX_ERR(0, 638, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_fwd)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("fwd_bkwd", 0, 5, 6, 2); __PYX_ERR(0, 638, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_bwd)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("fwd_bkwd", 0, 5, 6, 3); __PYX_ERR(0, 638, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  4:
        if (likely((values[4] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_t)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("fwd_bkwd", 0, 5, 6, 4); __PYX_ERR(0, 638, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  5:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_full);
          if (value) { values[5] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "fwd_bkwd") < 0)) __PYX_ERR(0, 638, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
        CYTHON_FALLTHROUGH;
        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
        values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_e_prob0 = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(values[0], PyBUF_WRITABLE); if (unlikely(!__pyx_v_e_prob0.memview)) __PYX_ERR(0, 638, __pyx_L3_error)
    __pyx_v_t_mat = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(values[1], PyBUF_WRITABLE); if (unlikely(!__pyx_v_t_mat.memview)) __PYX_ERR(0, 638, __pyx_L3_error)
    __pyx_v_fwd = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(values[2], PyBUF_WRITABLE); if (unlikely(!__pyx_v_fwd.memview)) __PYX_ERR(0, 639, __pyx_L3_error)
    __pyx_v_bwd = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(values[3], PyBUF_WRITABLE); if (unlikely(!__pyx_v_bwd.memview)) __PYX_ERR(0, 639, __pyx_L3_error)
    __pyx_v_t = __Pyx_PyObject_to_MemoryviewSlice_dsdsds_double(values[4], PyBUF_WRITABLE); if (unlikely(!__pyx_v_t.memview)) __PYX_ERR(0, 639, __pyx_L3_error)
    __pyx_v_full = values[5];
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("fwd_bkwd", 0, 5, 6, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 638, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("hapsburg.cfunc.fwd_bkwd", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_8hapsburg_5cfunc_12fwd_bkwd(__pyx_self, __pyx_v_e_prob0, __pyx_v_t_mat, __pyx_v_fwd, __pyx_v_bwd, __pyx_v_t, __pyx_v_full);
 640:     """Takes emission and transition probabilities, and calculates posteriors.
 641:     Input: kxl matrices of emission, transition
 642:     and initialized fwd and bwd probabilities. Given in log Space
 643:     full: Boolean whether to return everything.
 644:     LEGACY: This was the first implementation, using the full algorithm. SLOW!!"""
+645:     cdef int n_states = e_prob0.shape[0]
  __pyx_v_n_states = (__pyx_v_e_prob0.shape[0]);
+646:     cdef int n_loci = e_prob0.shape[1]
  __pyx_v_n_loci = (__pyx_v_e_prob0.shape[1]);
 647:     cdef Py_ssize_t i, j, k # The Array Indices
 648: 
 649:     # Initialize Posterior and Transition Probabilities
+650:     post = np.empty([n_states, n_loci], dtype=DTYPE)
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 650, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 650, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_n_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 650, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_n_loci); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 650, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = PyList_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 650, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_1);
  PyList_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
  __Pyx_GIVEREF(__pyx_t_3);
  PyList_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
  __pyx_t_1 = 0;
  __pyx_t_3 = 0;
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 650, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
  __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 650, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 650, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_1) < 0) __PYX_ERR(0, 650, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 650, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_v_post = __pyx_t_1;
  __pyx_t_1 = 0;
 651: 
+652:     trans_ll = np.empty(n_states, dtype=DTYPE)
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 652, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 652, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_n_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 652, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 652, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
  __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 652, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 652, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_2) < 0) __PYX_ERR(0, 652, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 652, __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_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_trans_ll = __pyx_t_2;
  __pyx_t_2 = 0;
+653:     cdef double[:] trans_ll_view = trans_ll
  __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_trans_ll, PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 653, __pyx_L1_error)
  __pyx_v_trans_ll_view = __pyx_t_5;
  __pyx_t_5.memview = NULL;
  __pyx_t_5.data = NULL;
 654: 
 655:     ### Transform to Log space
+656:     cdef double[:, :] t_mat0 = np.log(np.eye(n_states) + t_mat[:,:])  # Do log of (relevant) transition Matrix
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 656, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_log); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 656, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 656, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_eye); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 656, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_n_states); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 656, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_7 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_6))) {
    __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
    if (likely(__pyx_t_7)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
      __Pyx_INCREF(__pyx_t_7);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_6, function);
    }
  }
  __pyx_t_1 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_t_4);
  __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 656, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __pyx_t_6 = __pyx_memoryview_fromslice(__pyx_v_t_mat, 2, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 656, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __pyx_t_4 = PyNumber_Add(__pyx_t_1, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 656, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __pyx_t_6 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3);
    if (likely(__pyx_t_6)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
      __Pyx_INCREF(__pyx_t_6);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_3, function);
    }
  }
  __pyx_t_2 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_6, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4);
  __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 656, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(__pyx_t_2, PyBUF_WRITABLE); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 656, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_t_mat0 = __pyx_t_8;
  __pyx_t_8.memview = NULL;
  __pyx_t_8.data = NULL;
 657: 
+658:     for i in range(1, n_loci):  # Do the forward recursion
  __pyx_t_9 = __pyx_v_n_loci;
  __pyx_t_10 = __pyx_t_9;
  for (__pyx_t_11 = 1; __pyx_t_11 < __pyx_t_10; __pyx_t_11+=1) {
    __pyx_v_i = __pyx_t_11;
+659:         for j in range(n_states):
    __pyx_t_12 = __pyx_v_n_states;
    __pyx_t_13 = __pyx_t_12;
    for (__pyx_t_14 = 0; __pyx_t_14 < __pyx_t_13; __pyx_t_14+=1) {
      __pyx_v_j = __pyx_t_14;
+660:           for k in range(n_states):
      __pyx_t_15 = __pyx_v_n_states;
      __pyx_t_16 = __pyx_t_15;
      for (__pyx_t_17 = 0; __pyx_t_17 < __pyx_t_16; __pyx_t_17+=1) {
        __pyx_v_k = __pyx_t_17;
+661:             trans_ll_view[k] = fwd[k, i - 1] + t_mat0[k, j]
        __pyx_t_18 = __pyx_v_k;
        __pyx_t_19 = (__pyx_v_i - 1);
        __pyx_t_20 = -1;
        if (__pyx_t_18 < 0) {
          __pyx_t_20 = 0;
        } else if (unlikely(__pyx_t_18 >= __pyx_v_fwd.shape[0])) __pyx_t_20 = 0;
        if (__pyx_t_19 < 0) {
          __pyx_t_20 = 1;
        } else if (unlikely(__pyx_t_19 >= __pyx_v_fwd.shape[1])) __pyx_t_20 = 1;
        if (unlikely(__pyx_t_20 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_20);
          __PYX_ERR(0, 661, __pyx_L1_error)
        }
        __pyx_t_21 = __pyx_v_k;
        __pyx_t_22 = __pyx_v_j;
        __pyx_t_20 = -1;
        if (__pyx_t_21 < 0) {
          __pyx_t_20 = 0;
        } else if (unlikely(__pyx_t_21 >= __pyx_v_t_mat0.shape[0])) __pyx_t_20 = 0;
        if (__pyx_t_22 < 0) {
          __pyx_t_20 = 1;
        } else if (unlikely(__pyx_t_22 >= __pyx_v_t_mat0.shape[1])) __pyx_t_20 = 1;
        if (unlikely(__pyx_t_20 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_20);
          __PYX_ERR(0, 661, __pyx_L1_error)
        }
        __pyx_t_23 = __pyx_v_k;
        __pyx_t_20 = -1;
        if (__pyx_t_23 < 0) {
          __pyx_t_20 = 0;
        } else if (unlikely(__pyx_t_23 >= __pyx_v_trans_ll_view.shape[0])) __pyx_t_20 = 0;
        if (unlikely(__pyx_t_20 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_20);
          __PYX_ERR(0, 661, __pyx_L1_error)
        }
        *((double *) ( /* dim=0 */ (__pyx_v_trans_ll_view.data + __pyx_t_23 * __pyx_v_trans_ll_view.strides[0]) )) = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_18 * __pyx_v_fwd.strides[0]) ) + __pyx_t_19 * __pyx_v_fwd.strides[1]) ))) + (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t_mat0.data + __pyx_t_21 * __pyx_v_t_mat0.strides[0]) ) + __pyx_t_22 * __pyx_v_t_mat0.strides[1]) ))));
      }
 662: 
+663:           fwd[j, i] = e_prob0[j, i] + logsumexp(trans_ll_view)
      __pyx_t_22 = __pyx_v_j;
      __pyx_t_21 = __pyx_v_i;
      __pyx_t_15 = -1;
      if (__pyx_t_22 < 0) {
        __pyx_t_15 = 0;
      } else if (unlikely(__pyx_t_22 >= __pyx_v_e_prob0.shape[0])) __pyx_t_15 = 0;
      if (__pyx_t_21 < 0) {
        __pyx_t_15 = 1;
      } else if (unlikely(__pyx_t_21 >= __pyx_v_e_prob0.shape[1])) __pyx_t_15 = 1;
      if (unlikely(__pyx_t_15 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_15);
        __PYX_ERR(0, 663, __pyx_L1_error)
      }
      __pyx_t_19 = __pyx_v_j;
      __pyx_t_18 = __pyx_v_i;
      __pyx_t_15 = -1;
      if (__pyx_t_19 < 0) {
        __pyx_t_15 = 0;
      } else if (unlikely(__pyx_t_19 >= __pyx_v_fwd.shape[0])) __pyx_t_15 = 0;
      if (__pyx_t_18 < 0) {
        __pyx_t_15 = 1;
      } else if (unlikely(__pyx_t_18 >= __pyx_v_fwd.shape[1])) __pyx_t_15 = 1;
      if (unlikely(__pyx_t_15 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_15);
        __PYX_ERR(0, 663, __pyx_L1_error)
      }
      *((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_19 * __pyx_v_fwd.strides[0]) ) + __pyx_t_18 * __pyx_v_fwd.strides[1]) )) = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_prob0.data + __pyx_t_22 * __pyx_v_e_prob0.strides[0]) ) + __pyx_t_21 * __pyx_v_e_prob0.strides[1]) ))) + __pyx_f_8hapsburg_5cfunc_logsumexp(__pyx_v_trans_ll_view));
    }
  }
 664: 
+665:     for i in range(n_loci-1, 0, -1):  # Do the backward recursion
  for (__pyx_t_11 = (__pyx_v_n_loci - 1); __pyx_t_11 > 0; __pyx_t_11-=1) {
    __pyx_v_i = __pyx_t_11;
+666:       for j in range(n_states):
    __pyx_t_9 = __pyx_v_n_states;
    __pyx_t_10 = __pyx_t_9;
    for (__pyx_t_14 = 0; __pyx_t_14 < __pyx_t_10; __pyx_t_14+=1) {
      __pyx_v_j = __pyx_t_14;
+667:         for k in range(n_states):
      __pyx_t_12 = __pyx_v_n_states;
      __pyx_t_13 = __pyx_t_12;
      for (__pyx_t_17 = 0; __pyx_t_17 < __pyx_t_13; __pyx_t_17+=1) {
        __pyx_v_k = __pyx_t_17;
+668:           trans_ll_view[k] = t_mat0[j, k] + e_prob0[k, i] + bwd[k, i]
        __pyx_t_21 = __pyx_v_j;
        __pyx_t_22 = __pyx_v_k;
        __pyx_t_15 = -1;
        if (__pyx_t_21 < 0) {
          __pyx_t_15 = 0;
        } else if (unlikely(__pyx_t_21 >= __pyx_v_t_mat0.shape[0])) __pyx_t_15 = 0;
        if (__pyx_t_22 < 0) {
          __pyx_t_15 = 1;
        } else if (unlikely(__pyx_t_22 >= __pyx_v_t_mat0.shape[1])) __pyx_t_15 = 1;
        if (unlikely(__pyx_t_15 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_15);
          __PYX_ERR(0, 668, __pyx_L1_error)
        }
        __pyx_t_18 = __pyx_v_k;
        __pyx_t_19 = __pyx_v_i;
        __pyx_t_15 = -1;
        if (__pyx_t_18 < 0) {
          __pyx_t_15 = 0;
        } else if (unlikely(__pyx_t_18 >= __pyx_v_e_prob0.shape[0])) __pyx_t_15 = 0;
        if (__pyx_t_19 < 0) {
          __pyx_t_15 = 1;
        } else if (unlikely(__pyx_t_19 >= __pyx_v_e_prob0.shape[1])) __pyx_t_15 = 1;
        if (unlikely(__pyx_t_15 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_15);
          __PYX_ERR(0, 668, __pyx_L1_error)
        }
        __pyx_t_23 = __pyx_v_k;
        __pyx_t_24 = __pyx_v_i;
        __pyx_t_15 = -1;
        if (__pyx_t_23 < 0) {
          __pyx_t_15 = 0;
        } else if (unlikely(__pyx_t_23 >= __pyx_v_bwd.shape[0])) __pyx_t_15 = 0;
        if (__pyx_t_24 < 0) {
          __pyx_t_15 = 1;
        } else if (unlikely(__pyx_t_24 >= __pyx_v_bwd.shape[1])) __pyx_t_15 = 1;
        if (unlikely(__pyx_t_15 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_15);
          __PYX_ERR(0, 668, __pyx_L1_error)
        }
        __pyx_t_25 = __pyx_v_k;
        __pyx_t_15 = -1;
        if (__pyx_t_25 < 0) {
          __pyx_t_15 = 0;
        } else if (unlikely(__pyx_t_25 >= __pyx_v_trans_ll_view.shape[0])) __pyx_t_15 = 0;
        if (unlikely(__pyx_t_15 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_15);
          __PYX_ERR(0, 668, __pyx_L1_error)
        }
        *((double *) ( /* dim=0 */ (__pyx_v_trans_ll_view.data + __pyx_t_25 * __pyx_v_trans_ll_view.strides[0]) )) = (((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t_mat0.data + __pyx_t_21 * __pyx_v_t_mat0.strides[0]) ) + __pyx_t_22 * __pyx_v_t_mat0.strides[1]) ))) + (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_prob0.data + __pyx_t_18 * __pyx_v_e_prob0.strides[0]) ) + __pyx_t_19 * __pyx_v_e_prob0.strides[1]) )))) + (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_23 * __pyx_v_bwd.strides[0]) ) + __pyx_t_24 * __pyx_v_bwd.strides[1]) ))));
      }
+669:         bwd[j, i - 1] = logsumexp(trans_ll_view)
      __pyx_t_24 = __pyx_v_j;
      __pyx_t_23 = (__pyx_v_i - 1);
      __pyx_t_12 = -1;
      if (__pyx_t_24 < 0) {
        __pyx_t_12 = 0;
      } else if (unlikely(__pyx_t_24 >= __pyx_v_bwd.shape[0])) __pyx_t_12 = 0;
      if (__pyx_t_23 < 0) {
        __pyx_t_12 = 1;
      } else if (unlikely(__pyx_t_23 >= __pyx_v_bwd.shape[1])) __pyx_t_12 = 1;
      if (unlikely(__pyx_t_12 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_12);
        __PYX_ERR(0, 669, __pyx_L1_error)
      }
      *((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_24 * __pyx_v_bwd.strides[0]) ) + __pyx_t_23 * __pyx_v_bwd.strides[1]) )) = __pyx_f_8hapsburg_5cfunc_logsumexp(__pyx_v_trans_ll_view);
    }
  }
 670: 
 671:     # Get total log likelihood
+672:     for k in range(n_states):  # Simply sum the two 1D arrays
  __pyx_t_9 = __pyx_v_n_states;
  __pyx_t_10 = __pyx_t_9;
  for (__pyx_t_11 = 0; __pyx_t_11 < __pyx_t_10; __pyx_t_11+=1) {
    __pyx_v_k = __pyx_t_11;
+673:       trans_ll_view[k] = fwd[k, n_loci-1] + bwd[k, n_loci-1]
    __pyx_t_23 = __pyx_v_k;
    __pyx_t_24 = (__pyx_v_n_loci - 1);
    __pyx_t_12 = -1;
    if (__pyx_t_23 < 0) {
      __pyx_t_12 = 0;
    } else if (unlikely(__pyx_t_23 >= __pyx_v_fwd.shape[0])) __pyx_t_12 = 0;
    if (__pyx_t_24 < 0) {
      __pyx_t_12 = 1;
    } else if (unlikely(__pyx_t_24 >= __pyx_v_fwd.shape[1])) __pyx_t_12 = 1;
    if (unlikely(__pyx_t_12 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_12);
      __PYX_ERR(0, 673, __pyx_L1_error)
    }
    __pyx_t_19 = __pyx_v_k;
    __pyx_t_18 = (__pyx_v_n_loci - 1);
    __pyx_t_12 = -1;
    if (__pyx_t_19 < 0) {
      __pyx_t_12 = 0;
    } else if (unlikely(__pyx_t_19 >= __pyx_v_bwd.shape[0])) __pyx_t_12 = 0;
    if (__pyx_t_18 < 0) {
      __pyx_t_12 = 1;
    } else if (unlikely(__pyx_t_18 >= __pyx_v_bwd.shape[1])) __pyx_t_12 = 1;
    if (unlikely(__pyx_t_12 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_12);
      __PYX_ERR(0, 673, __pyx_L1_error)
    }
    __pyx_t_22 = __pyx_v_k;
    __pyx_t_12 = -1;
    if (__pyx_t_22 < 0) {
      __pyx_t_12 = 0;
    } else if (unlikely(__pyx_t_22 >= __pyx_v_trans_ll_view.shape[0])) __pyx_t_12 = 0;
    if (unlikely(__pyx_t_12 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_12);
      __PYX_ERR(0, 673, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_trans_ll_view.data + __pyx_t_22 * __pyx_v_trans_ll_view.strides[0]) )) = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_fwd.data + __pyx_t_23 * __pyx_v_fwd.strides[0]) ) + __pyx_t_24 * __pyx_v_fwd.strides[1]) ))) + (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_bwd.data + __pyx_t_19 * __pyx_v_bwd.strides[0]) ) + __pyx_t_18 * __pyx_v_bwd.strides[1]) ))));
  }
+674:     tot_ll = logsumexp(trans_ll_view)
  __pyx_v_tot_ll = __pyx_f_8hapsburg_5cfunc_logsumexp(__pyx_v_trans_ll_view);
 675: 
+676:     print(f"Total Log likelihood: {tot_ll: .3f}")
  __pyx_t_2 = PyFloat_FromDouble(__pyx_v_tot_ll); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 676, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_Format(__pyx_t_2, __pyx_kp_u_3f); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 676, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Total_Log_likelihood, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 676, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 676, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 677: 
 678:     # Combine the forward and backward calculations
+679:     fwd1 = np.asarray(fwd)  # Transform
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 679, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_asarray); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 679, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __pyx_memoryview_fromslice(__pyx_v_fwd, 2, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 679, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_6 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
    if (likely(__pyx_t_6)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
      __Pyx_INCREF(__pyx_t_6);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_4, function);
    }
  }
  __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_2) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_2);
  __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 679, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_v_fwd1 = __pyx_t_3;
  __pyx_t_3 = 0;
+680:     bwd1 = np.asarray(bwd)
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 680, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_asarray); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 680, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __pyx_memoryview_fromslice(__pyx_v_bwd, 2, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 680, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_6 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_2);
    if (likely(__pyx_t_6)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
      __Pyx_INCREF(__pyx_t_6);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_2, function);
    }
  }
  __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_6, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4);
  __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 680, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_bwd1 = __pyx_t_3;
  __pyx_t_3 = 0;
+681:     post = fwd1 + bwd1 - tot_ll
  __pyx_t_3 = PyNumber_Add(__pyx_v_fwd1, __pyx_v_bwd1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 681, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_2 = PyFloat_FromDouble(__pyx_v_tot_ll); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 681, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_4 = PyNumber_Subtract(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 681, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF_SET(__pyx_v_post, __pyx_t_4);
  __pyx_t_4 = 0;
 682: 
+683:     if full==False:
  __pyx_t_4 = PyObject_RichCompare(__pyx_v_full, Py_False, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 683, __pyx_L1_error)
  __pyx_t_26 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_26 < 0)) __PYX_ERR(0, 683, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (__pyx_t_26) {
/* … */
  }
+684:       return post
    __Pyx_XDECREF(__pyx_r);
    __Pyx_INCREF(__pyx_v_post);
    __pyx_r = __pyx_v_post;
    goto __pyx_L0;
 685: 
+686:     elif full==True:   # Return everything
  __pyx_t_4 = PyObject_RichCompare(__pyx_v_full, Py_True, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 686, __pyx_L1_error)
  __pyx_t_26 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_26 < 0)) __PYX_ERR(0, 686, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (__pyx_t_26) {
/* … */
  }
+687:       return post, fwd1, bwd1, tot_ll
    __Pyx_XDECREF(__pyx_r);
    __pyx_t_4 = PyFloat_FromDouble(__pyx_v_tot_ll); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 687, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_2 = PyTuple_New(4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 687, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_INCREF(__pyx_v_post);
    __Pyx_GIVEREF(__pyx_v_post);
    PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_post);
    __Pyx_INCREF(__pyx_v_fwd1);
    __Pyx_GIVEREF(__pyx_v_fwd1);
    PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_fwd1);
    __Pyx_INCREF(__pyx_v_bwd1);
    __Pyx_GIVEREF(__pyx_v_bwd1);
    PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_v_bwd1);
    __Pyx_GIVEREF(__pyx_t_4);
    PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_4);
    __pyx_t_4 = 0;
    __pyx_r = __pyx_t_2;
    __pyx_t_2 = 0;
    goto __pyx_L0;
 688: 
 689: 
+690: def viterbi_path(double[:, :] e_prob0, double[:, :, :] t_mat0, double[:] end_p0):
/* Python wrapper */
static PyObject *__pyx_pw_8hapsburg_5cfunc_15viterbi_path(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_8hapsburg_5cfunc_14viterbi_path[] = "Implementation of a Viterbi Path.\n    e_prob0  Matrices with Emission Probabilities, [k,l] (log space)\n    t_mat: Transition Matrix: [l x 3 x 3]  (normal space)\n    end_p: probability to begin/end in states [k]";
static PyMethodDef __pyx_mdef_8hapsburg_5cfunc_15viterbi_path = {"viterbi_path", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_8hapsburg_5cfunc_15viterbi_path, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8hapsburg_5cfunc_14viterbi_path};
static PyObject *__pyx_pw_8hapsburg_5cfunc_15viterbi_path(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  __Pyx_memviewslice __pyx_v_e_prob0 = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_t_mat0 = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_end_p0 = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("viterbi_path (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_e_prob0,&__pyx_n_s_t_mat0,&__pyx_n_s_end_p0,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_e_prob0)) != 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_t_mat0)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("viterbi_path", 1, 3, 3, 1); __PYX_ERR(0, 690, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_end_p0)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("viterbi_path", 1, 3, 3, 2); __PYX_ERR(0, 690, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "viterbi_path") < 0)) __PYX_ERR(0, 690, __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_e_prob0 = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(values[0], PyBUF_WRITABLE); if (unlikely(!__pyx_v_e_prob0.memview)) __PYX_ERR(0, 690, __pyx_L3_error)
    __pyx_v_t_mat0 = __Pyx_PyObject_to_MemoryviewSlice_dsdsds_double(values[1], PyBUF_WRITABLE); if (unlikely(!__pyx_v_t_mat0.memview)) __PYX_ERR(0, 690, __pyx_L3_error)
    __pyx_v_end_p0 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(values[2], PyBUF_WRITABLE); if (unlikely(!__pyx_v_end_p0.memview)) __PYX_ERR(0, 690, __pyx_L3_error)
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("viterbi_path", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 690, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("hapsburg.cfunc.viterbi_path", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_8hapsburg_5cfunc_14viterbi_path(__pyx_self, __pyx_v_e_prob0, __pyx_v_t_mat0, __pyx_v_end_p0);
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;

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

static PyObject *__pyx_pf_8hapsburg_5cfunc_14viterbi_path(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_e_prob0, __Pyx_memviewslice __pyx_v_t_mat0, __Pyx_memviewslice __pyx_v_end_p0) {
  int __pyx_v_n_states;
  int __pyx_v_n_loci;
  Py_ssize_t __pyx_v_i;
  Py_ssize_t __pyx_v_k;
  int __pyx_v_m;
  double __pyx_v_v;
  __Pyx_memviewslice __pyx_v_mp = { 0, 0, { 0 }, { 0 }, { 0 } };
  CYTHON_UNUSED __Pyx_memviewslice __pyx_v_new_p = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_pt = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_trans_ll = NULL;
  CYTHON_UNUSED __Pyx_memviewslice __pyx_v_trans_ll_view = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_three_v = NULL;
  __Pyx_memviewslice __pyx_v_three_v_view = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_three_vi = NULL;
  __Pyx_memviewslice __pyx_v_three_vi_view = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_two_v = NULL;
  __Pyx_memviewslice __pyx_v_two_v_view = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_two_vi = NULL;
  __Pyx_memviewslice __pyx_v_two_vi_view = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_path = { 0, 0, { 0 }, { 0 }, { 0 } };
  PyObject *__pyx_v_x = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("viterbi_path", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __PYX_XDEC_MEMVIEW(&__pyx_t_6, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_t_7, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
  __Pyx_AddTraceback("hapsburg.cfunc.viterbi_path", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __PYX_XDEC_MEMVIEW(&__pyx_v_mp, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_new_p, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_pt, 1);
  __Pyx_XDECREF(__pyx_v_trans_ll);
  __PYX_XDEC_MEMVIEW(&__pyx_v_trans_ll_view, 1);
  __Pyx_XDECREF(__pyx_v_three_v);
  __PYX_XDEC_MEMVIEW(&__pyx_v_three_v_view, 1);
  __Pyx_XDECREF(__pyx_v_three_vi);
  __PYX_XDEC_MEMVIEW(&__pyx_v_three_vi_view, 1);
  __Pyx_XDECREF(__pyx_v_two_v);
  __PYX_XDEC_MEMVIEW(&__pyx_v_two_v_view, 1);
  __Pyx_XDECREF(__pyx_v_two_vi);
  __PYX_XDEC_MEMVIEW(&__pyx_v_two_vi_view, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_path, 1);
  __Pyx_XDECREF(__pyx_v_x);
  __PYX_XDEC_MEMVIEW(&__pyx_v_e_prob0, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_t_mat0, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_end_p0, 1);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__42 = PyTuple_Pack(25, __pyx_n_s_e_prob0, __pyx_n_s_t_mat0, __pyx_n_s_end_p0, __pyx_n_s_n_states, __pyx_n_s_n_loci, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_k, __pyx_n_s_m, __pyx_n_s_v, __pyx_n_s_mp, __pyx_n_s_new_p, __pyx_n_s_pt, __pyx_n_s_trans_ll, __pyx_n_s_trans_ll_view, __pyx_n_s_three_v, __pyx_n_s_three_v_view, __pyx_n_s_three_vi, __pyx_n_s_three_vi_view, __pyx_n_s_two_v, __pyx_n_s_two_v_view, __pyx_n_s_two_vi, __pyx_n_s_two_vi_view, __pyx_n_s_path, __pyx_n_s_x); if (unlikely(!__pyx_tuple__42)) __PYX_ERR(0, 690, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__42);
  __Pyx_GIVEREF(__pyx_tuple__42);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_8hapsburg_5cfunc_15viterbi_path, NULL, __pyx_n_s_hapsburg_cfunc); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 690, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_viterbi_path, __pyx_t_2) < 0) __PYX_ERR(0, 690, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__43 = (PyObject*)__Pyx_PyCode_New(3, 0, 25, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__42, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_hapsburg_cfunc_pyx, __pyx_n_s_viterbi_path, 690, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__43)) __PYX_ERR(0, 690, __pyx_L1_error)
 691:     """Implementation of a Viterbi Path.
 692:     e_prob0  Matrices with Emission Probabilities, [k,l] (log space)
 693:     t_mat: Transition Matrix: [l x 3 x 3]  (normal space)
 694:     end_p: probability to begin/end in states [k]"""
+695:     cdef int n_states = e_prob0.shape[0]
  __pyx_v_n_states = (__pyx_v_e_prob0.shape[0]);
+696:     cdef int n_loci = e_prob0.shape[1]
  __pyx_v_n_loci = (__pyx_v_e_prob0.shape[1]);
 697:     cdef Py_ssize_t i, j, k # The Array Indices
 698:     cdef int m  # Placeholder for Maximum
 699:     cdef double v # Value to set
 700: 
 701:     # Do the actual optimization (with back-tracking)
 702:     # Initialize Views:
+703:     cdef double[:, :] mp = np.empty((n_states, n_loci), dtype=np.float)
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 703, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 703, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_n_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 703, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_n_loci); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 703, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 703, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
  __Pyx_GIVEREF(__pyx_t_3);
  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
  __pyx_t_1 = 0;
  __pyx_t_3 = 0;
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 703, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
  __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 703, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 703, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_float); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 703, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_5) < 0) __PYX_ERR(0, 703, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 703, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(__pyx_t_5, PyBUF_WRITABLE); if (unlikely(!__pyx_t_6.memview)) __PYX_ERR(0, 703, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_v_mp = __pyx_t_6;
  __pyx_t_6.memview = NULL;
  __pyx_t_6.data = NULL;
+704:     cdef double[:] new_p = np.empty(n_states, dtype = np.float) # Temporary Array
  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 704, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_empty); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 704, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_n_states); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 704, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 704, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_5);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5);
  __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 704, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 704, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_float); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 704, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_1) < 0) __PYX_ERR(0, 704, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 704, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_t_1, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 704, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_new_p = __pyx_t_7;
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
+705:     cdef long[:,:] pt = np.empty((n_states, n_loci), dtype = np.int)  # Previous State Pointer
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 705, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 705, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_n_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 705, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_n_loci); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 705, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 705, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
  __Pyx_GIVEREF(__pyx_t_3);
  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
  __pyx_t_1 = 0;
  __pyx_t_3 = 0;
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 705, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
  __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 705, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 705, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_int); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 705, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_2) < 0) __PYX_ERR(0, 705, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 705, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dsds_long(__pyx_t_2, PyBUF_WRITABLE); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 705, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_pt = __pyx_t_8;
  __pyx_t_8.memview = NULL;
  __pyx_t_8.data = NULL;
 706: 
+707:     trans_ll = np.empty(n_states-1, dtype=DTYPE) # Array for pre-calculations
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 707, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 707, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyInt_From_long((__pyx_v_n_states - 1)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 707, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 707, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_2);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
  __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 707, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 707, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_5) < 0) __PYX_ERR(0, 707, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 707, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_trans_ll = __pyx_t_5;
  __pyx_t_5 = 0;
+708:     cdef double[:] trans_ll_view = trans_ll
  __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_trans_ll, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 708, __pyx_L1_error)
  __pyx_v_trans_ll_view = __pyx_t_7;
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
 709: 
+710:     three_v = np.empty(3, dtype=DTYPE)     # Array of size three
  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 710, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 710, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 710, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 710, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_3) < 0) __PYX_ERR(0, 710, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple_, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 710, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_v_three_v = __pyx_t_3;
  __pyx_t_3 = 0;
+711:     cdef double[:] three_v_view = three_v
  __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_three_v, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 711, __pyx_L1_error)
  __pyx_v_three_v_view = __pyx_t_7;
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
 712: 
+713:     three_vi = np.empty(3, dtype=int)       # Int Array of size three
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 713, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_empty); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 713, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 713, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, ((PyObject *)(&PyInt_Type))) < 0) __PYX_ERR(0, 713, __pyx_L1_error)
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple_, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 713, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_v_three_vi = __pyx_t_2;
  __pyx_t_2 = 0;
+714:     cdef long[:] three_vi_view = three_vi
  __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_ds_long(__pyx_v_three_vi, PyBUF_WRITABLE); if (unlikely(!__pyx_t_9.memview)) __PYX_ERR(0, 714, __pyx_L1_error)
  __pyx_v_three_vi_view = __pyx_t_9;
  __pyx_t_9.memview = NULL;
  __pyx_t_9.data = NULL;
 715: 
+716:     two_v = np.empty(2, dtype=DTYPE)       # Array of size two
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 716, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 716, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 716, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_DTYPE); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 716, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_5) < 0) __PYX_ERR(0, 716, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__2, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 716, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_two_v = __pyx_t_5;
  __pyx_t_5 = 0;
+717:     cdef double[:] two_v_view = two_v
  __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_two_v, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 717, __pyx_L1_error)
  __pyx_v_two_v_view = __pyx_t_7;
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
 718: 
+719:     two_vi = np.empty(2, dtype=int)       # Int Array of size two
  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 719, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 719, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 719, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, ((PyObject *)(&PyInt_Type))) < 0) __PYX_ERR(0, 719, __pyx_L1_error)
  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__2, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 719, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_v_two_vi = __pyx_t_3;
  __pyx_t_3 = 0;
+720:     cdef long[:] two_vi_view = two_vi
  __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_ds_long(__pyx_v_two_vi, PyBUF_WRITABLE); if (unlikely(!__pyx_t_9.memview)) __PYX_ERR(0, 720, __pyx_L1_error)
  __pyx_v_two_vi_view = __pyx_t_9;
  __pyx_t_9.memview = NULL;
  __pyx_t_9.data = NULL;
 721: 
+722:     for k in range(n_states):
  __pyx_t_10 = __pyx_v_n_states;
  __pyx_t_11 = __pyx_t_10;
  for (__pyx_t_12 = 0; __pyx_t_12 < __pyx_t_11; __pyx_t_12+=1) {
    __pyx_v_k = __pyx_t_12;
+723:       mp[k, 0] = end_p0[k]  # Initialize with Ending Probabilities
    __pyx_t_13 = __pyx_v_k;
    __pyx_t_14 = -1;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_end_p0.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 723, __pyx_L1_error)
    }
    __pyx_t_15 = __pyx_v_k;
    __pyx_t_16 = 0;
    __pyx_t_14 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_mp.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_16 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_mp.shape[1])) __pyx_t_14 = 1;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 723, __pyx_L1_error)
    }
    *((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_mp.data + __pyx_t_15 * __pyx_v_mp.strides[0]) ) + __pyx_t_16 * __pyx_v_mp.strides[1]) )) = (*((double *) ( /* dim=0 */ (__pyx_v_end_p0.data + __pyx_t_13 * __pyx_v_end_p0.strides[0]) )));
 724: 
+725:       two_vi_view[0] = 0
    __pyx_t_13 = 0;
    __pyx_t_14 = -1;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_two_vi_view.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 725, __pyx_L1_error)
    }
    *((long *) ( /* dim=0 */ (__pyx_v_two_vi_view.data + __pyx_t_13 * __pyx_v_two_vi_view.strides[0]) )) = 0;
+726:       three_vi_view[0] = 0
    __pyx_t_13 = 0;
    __pyx_t_14 = -1;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_three_vi_view.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 726, __pyx_L1_error)
    }
    *((long *) ( /* dim=0 */ (__pyx_v_three_vi_view.data + __pyx_t_13 * __pyx_v_three_vi_view.strides[0]) )) = 0;
  }
 727: 
+728:     for i in range(1, n_loci):  # Do the Viterbi-Iteration
  __pyx_t_10 = __pyx_v_n_loci;
  __pyx_t_11 = __pyx_t_10;
  for (__pyx_t_12 = 1; __pyx_t_12 < __pyx_t_11; __pyx_t_12+=1) {
    __pyx_v_i = __pyx_t_12;
 729:         ### Precomputation:
 730:         # Do the maximal log probability of 1, ...k State:
+731:         m = argmax(mp[1:, i - 1])
    __pyx_t_7.data = __pyx_v_mp.data;
    __pyx_t_7.memview = __pyx_v_mp.memview;
    __PYX_INC_MEMVIEW(&__pyx_t_7, 0);
    __pyx_t_14 = -1;
    if (unlikely(__pyx_memoryview_slice_memviewslice(
    &__pyx_t_7,
    __pyx_v_mp.shape[0], __pyx_v_mp.strides[0], __pyx_v_mp.suboffsets[0],
    0,
    0,
    &__pyx_t_14,
    1,
    0,
    0,
    1,
    0,
    0,
    1) < 0))
{
    __PYX_ERR(0, 731, __pyx_L1_error)
}

{
    Py_ssize_t __pyx_tmp_idx = (__pyx_v_i - 1);
        Py_ssize_t __pyx_tmp_shape = __pyx_v_mp.shape[1];
    Py_ssize_t __pyx_tmp_stride = __pyx_v_mp.strides[1];
        if (unlikely(!__Pyx_is_valid_index(__pyx_tmp_idx, __pyx_tmp_shape))) {
            PyErr_SetString(PyExc_IndexError,
                            "Index out of bounds (axis 1)");
            __PYX_ERR(0, 731, __pyx_L1_error)
        }
        __pyx_t_7.data += __pyx_tmp_idx * __pyx_tmp_stride;
}

__pyx_v_m = __pyx_f_8hapsburg_5cfunc_argmax(__pyx_t_7);
    __PYX_XDEC_MEMVIEW(&__pyx_t_7, 1);
    __pyx_t_7.memview = NULL;
    __pyx_t_7.data = NULL;
+732:         v = mp[m+1, i - 1]
    __pyx_t_13 = (__pyx_v_m + 1);
    __pyx_t_16 = (__pyx_v_i - 1);
    __pyx_t_14 = -1;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_mp.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_16 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_mp.shape[1])) __pyx_t_14 = 1;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 732, __pyx_L1_error)
    }
    __pyx_v_v = (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_mp.data + __pyx_t_13 * __pyx_v_mp.strides[0]) ) + __pyx_t_16 * __pyx_v_mp.strides[1]) )));
 733: 
 734:         # Do the States from collapsed states
+735:         two_vi_view[1] = m+1   # Set the Pointers
    __pyx_t_16 = 1;
    __pyx_t_14 = -1;
    if (__pyx_t_16 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_two_vi_view.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 735, __pyx_L1_error)
    }
    *((long *) ( /* dim=0 */ (__pyx_v_two_vi_view.data + __pyx_t_16 * __pyx_v_two_vi_view.strides[0]) )) = (__pyx_v_m + 1);
+736:         three_vi_view[1] = m+1
    __pyx_t_16 = 1;
    __pyx_t_14 = -1;
    if (__pyx_t_16 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_three_vi_view.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 736, __pyx_L1_error)
    }
    *((long *) ( /* dim=0 */ (__pyx_v_three_vi_view.data + __pyx_t_16 * __pyx_v_three_vi_view.strides[0]) )) = (__pyx_v_m + 1);
 737: 
+738:         two_v_view[1] = v + t_mat0[i, 1, 0]
    __pyx_t_16 = __pyx_v_i;
    __pyx_t_13 = 1;
    __pyx_t_15 = 0;
    __pyx_t_14 = -1;
    if (__pyx_t_16 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t_mat0.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_t_mat0.shape[1])) __pyx_t_14 = 1;
    if (__pyx_t_15 < 0) {
      __pyx_t_14 = 2;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t_mat0.shape[2])) __pyx_t_14 = 2;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 738, __pyx_L1_error)
    }
    __pyx_t_17 = 1;
    __pyx_t_14 = -1;
    if (__pyx_t_17 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_two_v_view.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 738, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_two_v_view.data + __pyx_t_17 * __pyx_v_two_v_view.strides[0]) )) = (__pyx_v_v + (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t_mat0.data + __pyx_t_16 * __pyx_v_t_mat0.strides[0]) ) + __pyx_t_13 * __pyx_v_t_mat0.strides[1]) ) + __pyx_t_15 * __pyx_v_t_mat0.strides[2]) ))));
+739:         three_v_view[1] = v + t_mat0[i, 1, 2] # Move in from other ROH
    __pyx_t_15 = __pyx_v_i;
    __pyx_t_13 = 1;
    __pyx_t_16 = 2;
    __pyx_t_14 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t_mat0.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_t_mat0.shape[1])) __pyx_t_14 = 1;
    if (__pyx_t_16 < 0) {
      __pyx_t_14 = 2;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t_mat0.shape[2])) __pyx_t_14 = 2;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 739, __pyx_L1_error)
    }
    __pyx_t_17 = 1;
    __pyx_t_14 = -1;
    if (__pyx_t_17 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_three_v_view.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 739, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_three_v_view.data + __pyx_t_17 * __pyx_v_three_v_view.strides[0]) )) = (__pyx_v_v + (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t_mat0.data + __pyx_t_15 * __pyx_v_t_mat0.strides[0]) ) + __pyx_t_13 * __pyx_v_t_mat0.strides[1]) ) + __pyx_t_16 * __pyx_v_t_mat0.strides[2]) ))));
 740: 
 741:         ### Do the zero State
+742:         two_v_view[0] = mp[0, i - 1] + t_mat0[i, 0, 0]
    __pyx_t_16 = 0;
    __pyx_t_13 = (__pyx_v_i - 1);
    __pyx_t_14 = -1;
    if (__pyx_t_16 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_mp.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_mp.shape[1])) __pyx_t_14 = 1;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 742, __pyx_L1_error)
    }
    __pyx_t_15 = __pyx_v_i;
    __pyx_t_17 = 0;
    __pyx_t_18 = 0;
    __pyx_t_14 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t_mat0.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_17 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_t_mat0.shape[1])) __pyx_t_14 = 1;
    if (__pyx_t_18 < 0) {
      __pyx_t_14 = 2;
    } else if (unlikely(__pyx_t_18 >= __pyx_v_t_mat0.shape[2])) __pyx_t_14 = 2;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 742, __pyx_L1_error)
    }
    __pyx_t_19 = 0;
    __pyx_t_14 = -1;
    if (__pyx_t_19 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_19 >= __pyx_v_two_v_view.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 742, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_two_v_view.data + __pyx_t_19 * __pyx_v_two_v_view.strides[0]) )) = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_mp.data + __pyx_t_16 * __pyx_v_mp.strides[0]) ) + __pyx_t_13 * __pyx_v_mp.strides[1]) ))) + (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t_mat0.data + __pyx_t_15 * __pyx_v_t_mat0.strides[0]) ) + __pyx_t_17 * __pyx_v_t_mat0.strides[1]) ) + __pyx_t_18 * __pyx_v_t_mat0.strides[2]) ))));
 743: 
+744:         m = argmax(two_v_view)      ### Do a Maximum
    __pyx_v_m = __pyx_f_8hapsburg_5cfunc_argmax(__pyx_v_two_v_view);
+745:         v = two_v_view[m]
    __pyx_t_18 = __pyx_v_m;
    __pyx_t_14 = -1;
    if (__pyx_t_18 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_18 >= __pyx_v_two_v_view.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 745, __pyx_L1_error)
    }
    __pyx_v_v = (*((double *) ( /* dim=0 */ (__pyx_v_two_v_view.data + __pyx_t_18 * __pyx_v_two_v_view.strides[0]) )));
+746:         mp[0, i] = v + e_prob0[0, i]   ### Set Max. Probability
    __pyx_t_18 = 0;
    __pyx_t_17 = __pyx_v_i;
    __pyx_t_14 = -1;
    if (__pyx_t_18 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_18 >= __pyx_v_e_prob0.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_17 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_e_prob0.shape[1])) __pyx_t_14 = 1;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 746, __pyx_L1_error)
    }
    __pyx_t_15 = 0;
    __pyx_t_13 = __pyx_v_i;
    __pyx_t_14 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_mp.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_mp.shape[1])) __pyx_t_14 = 1;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 746, __pyx_L1_error)
    }
    *((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_mp.data + __pyx_t_15 * __pyx_v_mp.strides[0]) ) + __pyx_t_13 * __pyx_v_mp.strides[1]) )) = (__pyx_v_v + (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_prob0.data + __pyx_t_18 * __pyx_v_e_prob0.strides[0]) ) + __pyx_t_17 * __pyx_v_e_prob0.strides[1]) ))));
+747:         pt[0, i] = two_vi_view[m]      ### Set Pointer for Backtrace
    __pyx_t_17 = __pyx_v_m;
    __pyx_t_14 = -1;
    if (__pyx_t_17 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_two_vi_view.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 747, __pyx_L1_error)
    }
    __pyx_t_18 = 0;
    __pyx_t_13 = __pyx_v_i;
    __pyx_t_14 = -1;
    if (__pyx_t_18 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_18 >= __pyx_v_pt.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_pt.shape[1])) __pyx_t_14 = 1;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 747, __pyx_L1_error)
    }
    *((long *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_pt.data + __pyx_t_18 * __pyx_v_pt.strides[0]) ) + __pyx_t_13 * __pyx_v_pt.strides[1]) )) = (*((long *) ( /* dim=0 */ (__pyx_v_two_vi_view.data + __pyx_t_17 * __pyx_v_two_vi_view.strides[0]) )));
 748: 
 749:         ### Do the other States
+750:         three_v_view[0] = mp[0, i - 1] + t_mat0[i, 0, 1] # Move from 0 State
    __pyx_t_17 = 0;
    __pyx_t_13 = (__pyx_v_i - 1);
    __pyx_t_14 = -1;
    if (__pyx_t_17 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_mp.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_13 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_mp.shape[1])) __pyx_t_14 = 1;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 750, __pyx_L1_error)
    }
    __pyx_t_18 = __pyx_v_i;
    __pyx_t_15 = 0;
    __pyx_t_16 = 1;
    __pyx_t_14 = -1;
    if (__pyx_t_18 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_18 >= __pyx_v_t_mat0.shape[0])) __pyx_t_14 = 0;
    if (__pyx_t_15 < 0) {
      __pyx_t_14 = 1;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_t_mat0.shape[1])) __pyx_t_14 = 1;
    if (__pyx_t_16 < 0) {
      __pyx_t_14 = 2;
    } else if (unlikely(__pyx_t_16 >= __pyx_v_t_mat0.shape[2])) __pyx_t_14 = 2;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 750, __pyx_L1_error)
    }
    __pyx_t_19 = 0;
    __pyx_t_14 = -1;
    if (__pyx_t_19 < 0) {
      __pyx_t_14 = 0;
    } else if (unlikely(__pyx_t_19 >= __pyx_v_three_v_view.shape[0])) __pyx_t_14 = 0;
    if (unlikely(__pyx_t_14 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_14);
      __PYX_ERR(0, 750, __pyx_L1_error)
    }
    *((double *) ( /* dim=0 */ (__pyx_v_three_v_view.data + __pyx_t_19 * __pyx_v_three_v_view.strides[0]) )) = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_mp.data + __pyx_t_17 * __pyx_v_mp.strides[0]) ) + __pyx_t_13 * __pyx_v_mp.strides[1]) ))) + (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t_mat0.data + __pyx_t_18 * __pyx_v_t_mat0.strides[0]) ) + __pyx_t_15 * __pyx_v_t_mat0.strides[1]) ) + __pyx_t_16 * __pyx_v_t_mat0.strides[2]) ))));
 751: 
+752:         for k in range(1, n_states):   # Find Maximum
    __pyx_t_14 = __pyx_v_n_states;
    __pyx_t_20 = __pyx_t_14;
    for (__pyx_t_21 = 1; __pyx_t_21 < __pyx_t_20; __pyx_t_21+=1) {
      __pyx_v_k = __pyx_t_21;
+753:           three_v_view[2] = mp[k, i - 1] + t_mat0[i, 1, 1] # The Stay State
      __pyx_t_16 = __pyx_v_k;
      __pyx_t_15 = (__pyx_v_i - 1);
      __pyx_t_22 = -1;
      if (__pyx_t_16 < 0) {
        __pyx_t_22 = 0;
      } else if (unlikely(__pyx_t_16 >= __pyx_v_mp.shape[0])) __pyx_t_22 = 0;
      if (__pyx_t_15 < 0) {
        __pyx_t_22 = 1;
      } else if (unlikely(__pyx_t_15 >= __pyx_v_mp.shape[1])) __pyx_t_22 = 1;
      if (unlikely(__pyx_t_22 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_22);
        __PYX_ERR(0, 753, __pyx_L1_error)
      }
      __pyx_t_18 = __pyx_v_i;
      __pyx_t_13 = 1;
      __pyx_t_17 = 1;
      __pyx_t_22 = -1;
      if (__pyx_t_18 < 0) {
        __pyx_t_22 = 0;
      } else if (unlikely(__pyx_t_18 >= __pyx_v_t_mat0.shape[0])) __pyx_t_22 = 0;
      if (__pyx_t_13 < 0) {
        __pyx_t_22 = 1;
      } else if (unlikely(__pyx_t_13 >= __pyx_v_t_mat0.shape[1])) __pyx_t_22 = 1;
      if (__pyx_t_17 < 0) {
        __pyx_t_22 = 2;
      } else if (unlikely(__pyx_t_17 >= __pyx_v_t_mat0.shape[2])) __pyx_t_22 = 2;
      if (unlikely(__pyx_t_22 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_22);
        __PYX_ERR(0, 753, __pyx_L1_error)
      }
      __pyx_t_19 = 2;
      __pyx_t_22 = -1;
      if (__pyx_t_19 < 0) {
        __pyx_t_22 = 0;
      } else if (unlikely(__pyx_t_19 >= __pyx_v_three_v_view.shape[0])) __pyx_t_22 = 0;
      if (unlikely(__pyx_t_22 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_22);
        __PYX_ERR(0, 753, __pyx_L1_error)
      }
      *((double *) ( /* dim=0 */ (__pyx_v_three_v_view.data + __pyx_t_19 * __pyx_v_three_v_view.strides[0]) )) = ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_mp.data + __pyx_t_16 * __pyx_v_mp.strides[0]) ) + __pyx_t_15 * __pyx_v_mp.strides[1]) ))) + (*((double *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_t_mat0.data + __pyx_t_18 * __pyx_v_t_mat0.strides[0]) ) + __pyx_t_13 * __pyx_v_t_mat0.strides[1]) ) + __pyx_t_17 * __pyx_v_t_mat0.strides[2]) ))));
+754:           three_vi_view[2] = k
      __pyx_t_17 = 2;
      __pyx_t_22 = -1;
      if (__pyx_t_17 < 0) {
        __pyx_t_22 = 0;
      } else if (unlikely(__pyx_t_17 >= __pyx_v_three_vi_view.shape[0])) __pyx_t_22 = 0;
      if (unlikely(__pyx_t_22 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_22);
        __PYX_ERR(0, 754, __pyx_L1_error)
      }
      *((long *) ( /* dim=0 */ (__pyx_v_three_vi_view.data + __pyx_t_17 * __pyx_v_three_vi_view.strides[0]) )) = __pyx_v_k;
 755: 
+756:           m = argmax(three_v_view)      ### Do a Maximum
      __pyx_v_m = __pyx_f_8hapsburg_5cfunc_argmax(__pyx_v_three_v_view);
+757:           v = three_v_view[m]
      __pyx_t_17 = __pyx_v_m;
      __pyx_t_22 = -1;
      if (__pyx_t_17 < 0) {
        __pyx_t_22 = 0;
      } else if (unlikely(__pyx_t_17 >= __pyx_v_three_v_view.shape[0])) __pyx_t_22 = 0;
      if (unlikely(__pyx_t_22 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_22);
        __PYX_ERR(0, 757, __pyx_L1_error)
      }
      __pyx_v_v = (*((double *) ( /* dim=0 */ (__pyx_v_three_v_view.data + __pyx_t_17 * __pyx_v_three_v_view.strides[0]) )));
 758: 
+759:           mp[k, i] = v + e_prob0[k, i]   ### Set Max. Probability
      __pyx_t_17 = __pyx_v_k;
      __pyx_t_13 = __pyx_v_i;
      __pyx_t_22 = -1;
      if (__pyx_t_17 < 0) {
        __pyx_t_22 = 0;
      } else if (unlikely(__pyx_t_17 >= __pyx_v_e_prob0.shape[0])) __pyx_t_22 = 0;
      if (__pyx_t_13 < 0) {
        __pyx_t_22 = 1;
      } else if (unlikely(__pyx_t_13 >= __pyx_v_e_prob0.shape[1])) __pyx_t_22 = 1;
      if (unlikely(__pyx_t_22 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_22);
        __PYX_ERR(0, 759, __pyx_L1_error)
      }
      __pyx_t_18 = __pyx_v_k;
      __pyx_t_15 = __pyx_v_i;
      __pyx_t_22 = -1;
      if (__pyx_t_18 < 0) {
        __pyx_t_22 = 0;
      } else if (unlikely(__pyx_t_18 >= __pyx_v_mp.shape[0])) __pyx_t_22 = 0;
      if (__pyx_t_15 < 0) {
        __pyx_t_22 = 1;
      } else if (unlikely(__pyx_t_15 >= __pyx_v_mp.shape[1])) __pyx_t_22 = 1;
      if (unlikely(__pyx_t_22 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_22);
        __PYX_ERR(0, 759, __pyx_L1_error)
      }
      *((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_mp.data + __pyx_t_18 * __pyx_v_mp.strides[0]) ) + __pyx_t_15 * __pyx_v_mp.strides[1]) )) = (__pyx_v_v + (*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_e_prob0.data + __pyx_t_17 * __pyx_v_e_prob0.strides[0]) ) + __pyx_t_13 * __pyx_v_e_prob0.strides[1]) ))));
+760:           pt[k, i] = three_vi_view[m]      ### Set Pointer for Backtrace
      __pyx_t_13 = __pyx_v_m;
      __pyx_t_22 = -1;
      if (__pyx_t_13 < 0) {
        __pyx_t_22 = 0;
      } else if (unlikely(__pyx_t_13 >= __pyx_v_three_vi_view.shape[0])) __pyx_t_22 = 0;
      if (unlikely(__pyx_t_22 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_22);
        __PYX_ERR(0, 760, __pyx_L1_error)
      }
      __pyx_t_17 = __pyx_v_k;
      __pyx_t_15 = __pyx_v_i;
      __pyx_t_22 = -1;
      if (__pyx_t_17 < 0) {
        __pyx_t_22 = 0;
      } else if (unlikely(__pyx_t_17 >= __pyx_v_pt.shape[0])) __pyx_t_22 = 0;
      if (__pyx_t_15 < 0) {
        __pyx_t_22 = 1;
      } else if (unlikely(__pyx_t_15 >= __pyx_v_pt.shape[1])) __pyx_t_22 = 1;
      if (unlikely(__pyx_t_22 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_22);
        __PYX_ERR(0, 760, __pyx_L1_error)
      }
      *((long *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_pt.data + __pyx_t_17 * __pyx_v_pt.strides[0]) ) + __pyx_t_15 * __pyx_v_pt.strides[1]) )) = (*((long *) ( /* dim=0 */ (__pyx_v_three_vi_view.data + __pyx_t_13 * __pyx_v_three_vi_view.strides[0]) )));
    }
  }
 761: 
 762:     ### Do the trace back
+763:     cdef long[:] path = -np.ones(n_loci, dtype=np.int)  # Initialize
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 763, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_ones); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 763, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_n_loci); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 763, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 763, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_GIVEREF(__pyx_t_3);
  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3);
  __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 763, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 763, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_int); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 763, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_1) < 0) __PYX_ERR(0, 763, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 763, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = PyNumber_Negative(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 763, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_ds_long(__pyx_t_3, PyBUF_WRITABLE); if (unlikely(!__pyx_t_9.memview)) __PYX_ERR(0, 763, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_v_path = __pyx_t_9;
  __pyx_t_9.memview = NULL;
  __pyx_t_9.data = NULL;
 764: 
+765:     x = np.argmax(mp[:, n_loci-1])  # The highest probability
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 765, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_argmax); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 765, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_7.data = __pyx_v_mp.data;
  __pyx_t_7.memview = __pyx_v_mp.memview;
  __PYX_INC_MEMVIEW(&__pyx_t_7, 0);
  __pyx_t_7.shape[0] = __pyx_v_mp.shape[0];
__pyx_t_7.strides[0] = __pyx_v_mp.strides[0];
    __pyx_t_7.suboffsets[0] = -1;

{
    Py_ssize_t __pyx_tmp_idx = (__pyx_v_n_loci - 1);
        Py_ssize_t __pyx_tmp_shape = __pyx_v_mp.shape[1];
    Py_ssize_t __pyx_tmp_stride = __pyx_v_mp.strides[1];
        if (unlikely(!__Pyx_is_valid_index(__pyx_tmp_idx, __pyx_tmp_shape))) {
            PyErr_SetString(PyExc_IndexError,
                            "Index out of bounds (axis 1)");
            __PYX_ERR(0, 765, __pyx_L1_error)
        }
        __pyx_t_7.data += __pyx_tmp_idx * __pyx_tmp_stride;
}

__pyx_t_1 = __pyx_memoryview_fromslice(__pyx_t_7, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 765, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __PYX_XDEC_MEMVIEW(&__pyx_t_7, 1);
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
  __pyx_t_5 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2);
    if (likely(__pyx_t_5)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
      __Pyx_INCREF(__pyx_t_5);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_2, function);
    }
  }
  __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_5, __pyx_t_1) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_1);
  __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 765, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_x = __pyx_t_3;
  __pyx_t_3 = 0;
+766:     path[n_loci-1] = x
  __pyx_t_23 = __Pyx_PyInt_As_long(__pyx_v_x); if (unlikely((__pyx_t_23 == (long)-1) && PyErr_Occurred())) __PYX_ERR(0, 766, __pyx_L1_error)
  __pyx_t_13 = (__pyx_v_n_loci - 1);
  __pyx_t_10 = -1;
  if (__pyx_t_13 < 0) {
    __pyx_t_10 = 0;
  } else if (unlikely(__pyx_t_13 >= __pyx_v_path.shape[0])) __pyx_t_10 = 0;
  if (unlikely(__pyx_t_10 != -1)) {
    __Pyx_RaiseBufferIndexError(__pyx_t_10);
    __PYX_ERR(0, 766, __pyx_L1_error)
  }
  *((long *) ( /* dim=0 */ (__pyx_v_path.data + __pyx_t_13 * __pyx_v_path.strides[0]) )) = __pyx_t_23;
 767: 
+768:     for i in range(n_loci - 1, 0, -1):
  for (__pyx_t_12 = (__pyx_v_n_loci - 1); __pyx_t_12 > 0; __pyx_t_12-=1) {
    __pyx_v_i = __pyx_t_12;
 769:         # Always th pointer to the previous path
+770:         path[i - 1] = pt[path[i], i]
    __pyx_t_13 = __pyx_v_i;
    __pyx_t_10 = -1;
    if (__pyx_t_13 < 0) {
      __pyx_t_10 = 0;
    } else if (unlikely(__pyx_t_13 >= __pyx_v_path.shape[0])) __pyx_t_10 = 0;
    if (unlikely(__pyx_t_10 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_10);
      __PYX_ERR(0, 770, __pyx_L1_error)
    }
    __pyx_t_15 = (*((long *) ( /* dim=0 */ (__pyx_v_path.data + __pyx_t_13 * __pyx_v_path.strides[0]) )));
    __pyx_t_17 = __pyx_v_i;
    __pyx_t_10 = -1;
    if (__pyx_t_15 < 0) {
      __pyx_t_10 = 0;
    } else if (unlikely(__pyx_t_15 >= __pyx_v_pt.shape[0])) __pyx_t_10 = 0;
    if (__pyx_t_17 < 0) {
      __pyx_t_10 = 1;
    } else if (unlikely(__pyx_t_17 >= __pyx_v_pt.shape[1])) __pyx_t_10 = 1;
    if (unlikely(__pyx_t_10 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_10);
      __PYX_ERR(0, 770, __pyx_L1_error)
    }
    __pyx_t_18 = (__pyx_v_i - 1);
    __pyx_t_10 = -1;
    if (__pyx_t_18 < 0) {
      __pyx_t_10 = 0;
    } else if (unlikely(__pyx_t_18 >= __pyx_v_path.shape[0])) __pyx_t_10 = 0;
    if (unlikely(__pyx_t_10 != -1)) {
      __Pyx_RaiseBufferIndexError(__pyx_t_10);
      __PYX_ERR(0, 770, __pyx_L1_error)
    }
    *((long *) ( /* dim=0 */ (__pyx_v_path.data + __pyx_t_18 * __pyx_v_path.strides[0]) )) = (*((long *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_pt.data + __pyx_t_15 * __pyx_v_pt.strides[0]) ) + __pyx_t_17 * __pyx_v_pt.strides[1]) )));
  }
 771: 
+772:     m = path[n_loci-1]
  __pyx_t_13 = (__pyx_v_n_loci - 1);
  __pyx_t_10 = -1;
  if (__pyx_t_13 < 0) {
    __pyx_t_10 = 0;
  } else if (unlikely(__pyx_t_13 >= __pyx_v_path.shape[0])) __pyx_t_10 = 0;
  if (unlikely(__pyx_t_10 != -1)) {
    __Pyx_RaiseBufferIndexError(__pyx_t_10);
    __PYX_ERR(0, 772, __pyx_L1_error)
  }
  __pyx_v_m = (*((long *) ( /* dim=0 */ (__pyx_v_path.data + __pyx_t_13 * __pyx_v_path.strides[0]) )));
+773:     print(f"Log likelihood Path: {mp[m,n_loci-1]:.3f}")
  __pyx_t_13 = __pyx_v_m;
  __pyx_t_17 = (__pyx_v_n_loci - 1);
  __pyx_t_10 = -1;
  if (__pyx_t_13 < 0) {
    __pyx_t_10 = 0;
  } else if (unlikely(__pyx_t_13 >= __pyx_v_mp.shape[0])) __pyx_t_10 = 0;
  if (__pyx_t_17 < 0) {
    __pyx_t_10 = 1;
  } else if (unlikely(__pyx_t_17 >= __pyx_v_mp.shape[1])) __pyx_t_10 = 1;
  if (unlikely(__pyx_t_10 != -1)) {
    __Pyx_RaiseBufferIndexError(__pyx_t_10);
    __PYX_ERR(0, 773, __pyx_L1_error)
  }
  __pyx_t_3 = PyFloat_FromDouble((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_mp.data + __pyx_t_13 * __pyx_v_mp.strides[0]) ) + __pyx_t_17 * __pyx_v_mp.strides[1]) )))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 773, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_2 = __Pyx_PyObject_Format(__pyx_t_3, __pyx_kp_u_3f_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 773, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Log_likelihood_Path, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 773, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 773, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+774:     assert(np.min(path)>=0) #Sanity check if everything was filled up
  #ifndef CYTHON_WITHOUT_ASSERTIONS
  if (unlikely(!Py_OptimizeFlag)) {
    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 774, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_min); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 774, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_path, 1, (PyObject *(*)(char *)) __pyx_memview_get_long, (int (*)(char *, PyObject *)) __pyx_memview_set_long, 0);; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 774, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_5 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_1))) {
      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_1);
      if (likely(__pyx_t_5)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
        __Pyx_INCREF(__pyx_t_5);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_1, function);
      }
    }
    __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_3);
    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 774, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_int_0, Py_GE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 774, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_24 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_24 < 0)) __PYX_ERR(0, 774, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    if (unlikely(!__pyx_t_24)) {
      PyErr_SetNone(PyExc_AssertionError);
      __PYX_ERR(0, 774, __pyx_L1_error)
    }
  }
  #endif
+775:     return np.asarray(path)
  __Pyx_XDECREF(__pyx_r);
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 775, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_asarray); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 775, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __pyx_memoryview_fromslice(__pyx_v_path, 1, (PyObject *(*)(char *)) __pyx_memview_get_long, (int (*)(char *, PyObject *)) __pyx_memview_set_long, 0);; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 775, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_5 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3);
    if (likely(__pyx_t_5)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
      __Pyx_INCREF(__pyx_t_5);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_3, function);
    }
  }
  __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_5, __pyx_t_2) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2);
  __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 775, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_r = __pyx_t_1;
  __pyx_t_1 = 0;
  goto __pyx_L0;