Commits

Janez Demšar  committed 19dd2b1

Added tests for 1d arrays for contingency; fixed a bug in indexing for contingency for 1d ints

  • Participants
  • Parent commits f7fa60b

Comments (0)

Files changed (4)

File bottleneck/src/func/32bit/func.c

-/* Generated by Cython 0.17.2 on Mon Dec 31 00:56:28 2012 */
+/* Generated by Cython 0.17.2 on Tue Jan  1 17:13:57 2013 */
 
 #define PY_SSIZE_T_CLEAN
 #include "Python.h"
   int __pyx_t_3;
   int __pyx_t_4;
   PyObject *__pyx_t_5 = NULL;
-  npy_intp __pyx_t_6[1];
+  npy_intp __pyx_t_6[2];
   PyArrayObject *__pyx_t_7 = NULL;
   npy_intp __pyx_t_8[1];
   PyArrayObject *__pyx_t_9 = NULL;
   PyObject *__pyx_t_13 = NULL;
   PyObject *__pyx_t_14 = NULL;
   Py_ssize_t __pyx_t_15;
-  Py_ssize_t __pyx_t_16;
-  Py_ssize_t __pyx_t_17;
+  int __pyx_t_16;
+  char __pyx_t_17;
   Py_ssize_t __pyx_t_18;
-  PyObject *__pyx_t_19 = NULL;
+  Py_ssize_t __pyx_t_19;
+  Py_ssize_t __pyx_t_20;
+  int __pyx_t_21;
+  char __pyx_t_22;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
   /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":123
  * 
  *     cdef:
- *         np.npy_intp *dims = [max_val+1]             # <<<<<<<<<<<<<<
- *         np.ndarray[np.float64_t, ndim=1] y = PyArray_ZEROS(1, dims, NPY_float64, 0)
- *         np.npy_intp *nandims = [max_val2+1]
+ *         np.npy_intp *dims = [max_val + 1, max_val2 + 1]             # <<<<<<<<<<<<<<
+ *         np.ndarray[np.float64_t, ndim=2] y = PyArray_ZEROS(2, dims, NPY_float64, 0)
+ *         np.npy_intp *nandims = [max_val2 + 1]
  */
   __pyx_t_6[0] = (__pyx_v_max_val + 1);
+  __pyx_t_6[1] = (__pyx_v_max_val2 + 1);
   __pyx_v_dims = __pyx_t_6;
 
   /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":124
  *     cdef:
- *         np.npy_intp *dims = [max_val+1]
- *         np.ndarray[np.float64_t, ndim=1] y = PyArray_ZEROS(1, dims, NPY_float64, 0)             # <<<<<<<<<<<<<<
- *         np.npy_intp *nandims = [max_val2+1]
+ *         np.npy_intp *dims = [max_val + 1, max_val2 + 1]
+ *         np.ndarray[np.float64_t, ndim=2] y = PyArray_ZEROS(2, dims, NPY_float64, 0)             # <<<<<<<<<<<<<<
+ *         np.npy_intp *nandims = [max_val2 + 1]
  *         np.ndarray[np.float_t, ndim=1] nans = PyArray_ZEROS(1, nandims, NPY_float64, 0)
  */
-  __pyx_t_5 = PyArray_ZEROS(1, __pyx_v_dims, NPY_FLOAT64, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyArray_ZEROS(2, __pyx_v_dims, NPY_FLOAT64, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
   if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_t_7 = ((PyArrayObject *)__pyx_t_5);
   {
     __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0, __pyx_stack) == -1)) {
       __pyx_v_y = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_y.rcbuffer->pybuffer.buf = NULL;
       {__pyx_filename = __pyx_f[22]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_y.diminfo[0].strides = __pyx_pybuffernd_y.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_y.diminfo[0].shape = __pyx_pybuffernd_y.rcbuffer->pybuffer.shape[0];
+    } else {__pyx_pybuffernd_y.diminfo[0].strides = __pyx_pybuffernd_y.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_y.diminfo[0].shape = __pyx_pybuffernd_y.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_y.diminfo[1].strides = __pyx_pybuffernd_y.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_y.diminfo[1].shape = __pyx_pybuffernd_y.rcbuffer->pybuffer.shape[1];
     }
   }
   __pyx_t_7 = 0;
   __pyx_t_5 = 0;
 
   /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":125
- *         np.npy_intp *dims = [max_val+1]
- *         np.ndarray[np.float64_t, ndim=1] y = PyArray_ZEROS(1, dims, NPY_float64, 0)
- *         np.npy_intp *nandims = [max_val2+1]             # <<<<<<<<<<<<<<
+ *         np.npy_intp *dims = [max_val + 1, max_val2 + 1]
+ *         np.ndarray[np.float64_t, ndim=2] y = PyArray_ZEROS(2, dims, NPY_float64, 0)
+ *         np.npy_intp *nandims = [max_val2 + 1]             # <<<<<<<<<<<<<<
  *         np.ndarray[np.float_t, ndim=1] nans = PyArray_ZEROS(1, nandims, NPY_float64, 0)
  *         int ai
  */
   __pyx_v_nandims = __pyx_t_8;
 
   /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":126
- *         np.ndarray[np.float64_t, ndim=1] y = PyArray_ZEROS(1, dims, NPY_float64, 0)
- *         np.npy_intp *nandims = [max_val2+1]
+ *         np.ndarray[np.float64_t, ndim=2] y = PyArray_ZEROS(2, dims, NPY_float64, 0)
+ *         np.npy_intp *nandims = [max_val2 + 1]
  *         np.ndarray[np.float_t, ndim=1] nans = PyArray_ZEROS(1, nandims, NPY_float64, 0)             # <<<<<<<<<<<<<<
  *         int ai
  *         char bin
  *     else:
  *         for i0 in range(n0):
  */
-      __pyx_t_14 = PyInt_FromLong(__pyx_v_ai); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_14);
-      __pyx_t_5 = PyInt_FromLong(__pyx_v_bin); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_14);
-      __Pyx_GIVEREF(__pyx_t_14);
-      PyTuple_SET_ITEM(__pyx_t_13, 1, __pyx_t_5);
-      __Pyx_GIVEREF(__pyx_t_5);
-      __pyx_t_14 = 0;
-      __pyx_t_5 = 0;
-      __pyx_t_5 = PyObject_GetItem(((PyObject *)__pyx_v_y), ((PyObject *)__pyx_t_13)); if (!__pyx_t_5) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_14 = PyNumber_InPlaceAdd(__pyx_t_5, __pyx_int_1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_14);
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      if (PyObject_SetItem(((PyObject *)__pyx_v_y), ((PyObject *)__pyx_t_13), __pyx_t_14) < 0) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-      __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
+      __pyx_t_16 = __pyx_v_ai;
+      __pyx_t_17 = __pyx_v_bin;
+      *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_y.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_y.diminfo[0].strides, __pyx_t_17, __pyx_pybuffernd_y.diminfo[1].strides) += 1.0;
     }
     goto __pyx_L5;
   }
  *             if ai < 0:
  *                 raise ValueError("negative value in contingency")
  */
-      __pyx_t_16 = __pyx_v_i0;
-      __pyx_v_ai = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int8_t *, __pyx_pybuffernd_a.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_a.diminfo[0].strides));
+      __pyx_t_18 = __pyx_v_i0;
+      __pyx_v_ai = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int8_t *, __pyx_pybuffernd_a.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_a.diminfo[0].strides));
 
       /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":147
  *         for i0 in range(n0):
  *             if ai > max_val:
  *                 raise ValueError("value %i is greater than max_val (%i)"
  */
-        __pyx_t_13 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_112), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_13);
-        __Pyx_Raise(__pyx_t_13, 0, 0, 0);
-        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+        __pyx_t_14 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_112), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_14);
+        __Pyx_Raise(__pyx_t_14, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
         {__pyx_filename = __pyx_f[22]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         goto __pyx_L13;
       }
  *             bin = b[i0]
  *             if bin > max_val2:
  */
-        __pyx_t_13 = PyInt_FromLong(__pyx_v_ai); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_13);
-        __pyx_t_14 = PyInt_FromLong(__pyx_v_max_val); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_14 = PyInt_FromLong(__pyx_v_ai); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_14);
-        __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyInt_FromLong(__pyx_v_max_val); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
-        PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_13);
-        __Pyx_GIVEREF(__pyx_t_13);
-        PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_14);
-        __Pyx_GIVEREF(__pyx_t_14);
-        __pyx_t_13 = 0;
-        __pyx_t_14 = 0;
-        __pyx_t_14 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_51), ((PyObject *)__pyx_t_5)); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(((PyObject *)__pyx_t_14));
-        __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
-        __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_5);
-        PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_t_14));
-        __Pyx_GIVEREF(((PyObject *)__pyx_t_14));
-        __pyx_t_14 = 0;
-        __pyx_t_14 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_14);
-        __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
-        __Pyx_Raise(__pyx_t_14, 0, 0, 0);
-        __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-        {__pyx_filename = __pyx_f[22]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        goto __pyx_L14;
-      }
-      __pyx_L14:;
-
-      /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":152
- *                 raise ValueError("value %i is greater than max_val (%i)"
- *                                  % (ai, max_val))
- *             bin = b[i0]             # <<<<<<<<<<<<<<
- *             if bin > max_val2:
- *                 raise ValueError("value %i is greater than max_val2 (%i)" %
- */
-      __pyx_t_17 = __pyx_v_i0;
-      __pyx_v_bin = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int8_t *, __pyx_pybuffernd_b.rcbuffer->pybuffer.buf, __pyx_t_17, __pyx_pybuffernd_b.diminfo[0].strides));
-
-      /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":153
- *                                  % (ai, max_val))
- *             bin = b[i0]
- *             if bin > max_val2:             # <<<<<<<<<<<<<<
- *                 raise ValueError("value %i is greater than max_val2 (%i)" %
- *                                  (bin, max_val2))
- */
-      __pyx_t_3 = (__pyx_v_bin > __pyx_v_max_val2);
-      if (__pyx_t_3) {
-
-        /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":155
- *             if bin > max_val2:
- *                 raise ValueError("value %i is greater than max_val2 (%i)" %
- *                                  (bin, max_val2))             # <<<<<<<<<<<<<<
- *             y[ai, bin] += w[i0]
- *     return y, nans
- */
-        __pyx_t_14 = PyInt_FromLong(__pyx_v_bin); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_14);
-        __pyx_t_5 = PyInt_FromLong(__pyx_v_max_val2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_5);
-        __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_13);
         PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_14);
         __Pyx_GIVEREF(__pyx_t_14);
         __Pyx_GIVEREF(__pyx_t_5);
         __pyx_t_14 = 0;
         __pyx_t_5 = 0;
-        __pyx_t_5 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_111), ((PyObject *)__pyx_t_13)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_51), ((PyObject *)__pyx_t_13)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(((PyObject *)__pyx_t_5));
         __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
-        __pyx_t_13 = PyTuple_New(1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_13 = PyTuple_New(1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_13);
         PyTuple_SET_ITEM(__pyx_t_13, 0, ((PyObject *)__pyx_t_5));
         __Pyx_GIVEREF(((PyObject *)__pyx_t_5));
         __pyx_t_5 = 0;
-        __pyx_t_5 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_13), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_13), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
         __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
         __Pyx_Raise(__pyx_t_5, 0, 0, 0);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        {__pyx_filename = __pyx_f[22]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        goto __pyx_L14;
+      }
+      __pyx_L14:;
+
+      /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":152
+ *                 raise ValueError("value %i is greater than max_val (%i)"
+ *                                  % (ai, max_val))
+ *             bin = b[i0]             # <<<<<<<<<<<<<<
+ *             if bin > max_val2:
+ *                 raise ValueError("value %i is greater than max_val2 (%i)" %
+ */
+      __pyx_t_19 = __pyx_v_i0;
+      __pyx_v_bin = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int8_t *, __pyx_pybuffernd_b.rcbuffer->pybuffer.buf, __pyx_t_19, __pyx_pybuffernd_b.diminfo[0].strides));
+
+      /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":153
+ *                                  % (ai, max_val))
+ *             bin = b[i0]
+ *             if bin > max_val2:             # <<<<<<<<<<<<<<
+ *                 raise ValueError("value %i is greater than max_val2 (%i)" %
+ *                                  (bin, max_val2))
+ */
+      __pyx_t_3 = (__pyx_v_bin > __pyx_v_max_val2);
+      if (__pyx_t_3) {
+
+        /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":155
+ *             if bin > max_val2:
+ *                 raise ValueError("value %i is greater than max_val2 (%i)" %
+ *                                  (bin, max_val2))             # <<<<<<<<<<<<<<
+ *             y[ai, bin] += w[i0]
+ *     return y, nans
+ */
+        __pyx_t_5 = PyInt_FromLong(__pyx_v_bin); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        __pyx_t_13 = PyInt_FromLong(__pyx_v_max_val2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_13);
+        __pyx_t_14 = PyTuple_New(2); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_14);
+        PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_5);
+        __Pyx_GIVEREF(__pyx_t_5);
+        PyTuple_SET_ITEM(__pyx_t_14, 1, __pyx_t_13);
+        __Pyx_GIVEREF(__pyx_t_13);
+        __pyx_t_5 = 0;
+        __pyx_t_13 = 0;
+        __pyx_t_13 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_111), ((PyObject *)__pyx_t_14)); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(((PyObject *)__pyx_t_13));
+        __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
+        __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_14);
+        PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_t_13));
+        __Pyx_GIVEREF(((PyObject *)__pyx_t_13));
+        __pyx_t_13 = 0;
+        __pyx_t_13 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_13);
+        __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
+        __Pyx_Raise(__pyx_t_13, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
         {__pyx_filename = __pyx_f[22]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         goto __pyx_L15;
       }
  *     return y, nans
  * 
  */
-      __pyx_t_5 = PyInt_FromLong(__pyx_v_ai); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_13 = PyInt_FromLong(__pyx_v_bin); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      __pyx_t_14 = PyTuple_New(2); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_14);
-      PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_5);
-      __Pyx_GIVEREF(__pyx_t_5);
-      PyTuple_SET_ITEM(__pyx_t_14, 1, __pyx_t_13);
-      __Pyx_GIVEREF(__pyx_t_13);
-      __pyx_t_5 = 0;
-      __pyx_t_13 = 0;
-      __pyx_t_13 = PyObject_GetItem(((PyObject *)__pyx_v_y), ((PyObject *)__pyx_t_14)); if (!__pyx_t_13) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      __pyx_t_18 = __pyx_v_i0;
-      __pyx_t_5 = PyFloat_FromDouble((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float_t *, __pyx_pybuffernd_w.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_w.diminfo[0].strides))); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_19 = PyNumber_InPlaceAdd(__pyx_t_13, __pyx_t_5); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_19);
-      __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      if (PyObject_SetItem(((PyObject *)__pyx_v_y), ((PyObject *)__pyx_t_14), __pyx_t_19) < 0) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
-      __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
+      __pyx_t_20 = __pyx_v_i0;
+      __pyx_t_21 = __pyx_v_ai;
+      __pyx_t_22 = __pyx_v_bin;
+      *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_y.rcbuffer->pybuffer.buf, __pyx_t_21, __pyx_pybuffernd_y.diminfo[0].strides, __pyx_t_22, __pyx_pybuffernd_y.diminfo[1].strides) += (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float_t *, __pyx_pybuffernd_w.rcbuffer->pybuffer.buf, __pyx_t_20, __pyx_pybuffernd_w.diminfo[0].strides));
     }
   }
   __pyx_L5:;
  * @cython.boundscheck(False)
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_14 = PyTuple_New(2); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_14);
+  __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_13);
   __Pyx_INCREF(((PyObject *)__pyx_v_y));
-  PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_v_y));
+  PyTuple_SET_ITEM(__pyx_t_13, 0, ((PyObject *)__pyx_v_y));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_y));
   __Pyx_INCREF(((PyObject *)__pyx_v_nans));
-  PyTuple_SET_ITEM(__pyx_t_14, 1, ((PyObject *)__pyx_v_nans));
+  PyTuple_SET_ITEM(__pyx_t_13, 1, ((PyObject *)__pyx_v_nans));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_nans));
-  __pyx_r = ((PyObject *)__pyx_t_14);
-  __pyx_t_14 = 0;
+  __pyx_r = ((PyObject *)__pyx_t_13);
+  __pyx_t_13 = 0;
   goto __pyx_L0;
 
   __pyx_r = Py_None; __Pyx_INCREF(Py_None);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_13);
   __Pyx_XDECREF(__pyx_t_14);
-  __Pyx_XDECREF(__pyx_t_19);
   { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
     __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
     __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_a.rcbuffer->pybuffer);
   int __pyx_t_3;
   int __pyx_t_4;
   PyObject *__pyx_t_5 = NULL;
-  npy_intp __pyx_t_6[1];
+  npy_intp __pyx_t_6[2];
   PyArrayObject *__pyx_t_7 = NULL;
   npy_intp __pyx_t_8[1];
   PyArrayObject *__pyx_t_9 = NULL;
   PyObject *__pyx_t_13 = NULL;
   PyObject *__pyx_t_14 = NULL;
   Py_ssize_t __pyx_t_15;
-  Py_ssize_t __pyx_t_16;
-  Py_ssize_t __pyx_t_17;
+  int __pyx_t_16;
+  char __pyx_t_17;
   Py_ssize_t __pyx_t_18;
-  PyObject *__pyx_t_19 = NULL;
+  Py_ssize_t __pyx_t_19;
+  Py_ssize_t __pyx_t_20;
+  int __pyx_t_21;
+  char __pyx_t_22;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
   /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":176
  * 
  *     cdef:
- *         np.npy_intp *dims = [max_val+1]             # <<<<<<<<<<<<<<
- *         np.ndarray[np.float64_t, ndim=1] y = PyArray_ZEROS(1, dims, NPY_float64, 0)
- *         np.npy_intp *nandims = [max_val2+1]
+ *         np.npy_intp *dims = [max_val + 1, max_val2 + 1]             # <<<<<<<<<<<<<<
+ *         np.ndarray[np.float64_t, ndim=2] y = PyArray_ZEROS(2, dims, NPY_float64, 0)
+ *         np.npy_intp *nandims = [max_val2 + 1]
  */
   __pyx_t_6[0] = (__pyx_v_max_val + 1);
+  __pyx_t_6[1] = (__pyx_v_max_val2 + 1);
   __pyx_v_dims = __pyx_t_6;
 
   /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":177
  *     cdef:
- *         np.npy_intp *dims = [max_val+1]
- *         np.ndarray[np.float64_t, ndim=1] y = PyArray_ZEROS(1, dims, NPY_float64, 0)             # <<<<<<<<<<<<<<
- *         np.npy_intp *nandims = [max_val2+1]
+ *         np.npy_intp *dims = [max_val + 1, max_val2 + 1]
+ *         np.ndarray[np.float64_t, ndim=2] y = PyArray_ZEROS(2, dims, NPY_float64, 0)             # <<<<<<<<<<<<<<
+ *         np.npy_intp *nandims = [max_val2 + 1]
  *         np.ndarray[np.float_t, ndim=1] nans = PyArray_ZEROS(1, nandims, NPY_float64, 0)
  */
-  __pyx_t_5 = PyArray_ZEROS(1, __pyx_v_dims, NPY_FLOAT64, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyArray_ZEROS(2, __pyx_v_dims, NPY_FLOAT64, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
   if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_t_7 = ((PyArrayObject *)__pyx_t_5);
   {
     __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0, __pyx_stack) == -1)) {
       __pyx_v_y = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_y.rcbuffer->pybuffer.buf = NULL;
       {__pyx_filename = __pyx_f[22]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_y.diminfo[0].strides = __pyx_pybuffernd_y.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_y.diminfo[0].shape = __pyx_pybuffernd_y.rcbuffer->pybuffer.shape[0];
+    } else {__pyx_pybuffernd_y.diminfo[0].strides = __pyx_pybuffernd_y.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_y.diminfo[0].shape = __pyx_pybuffernd_y.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_y.diminfo[1].strides = __pyx_pybuffernd_y.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_y.diminfo[1].shape = __pyx_pybuffernd_y.rcbuffer->pybuffer.shape[1];
     }
   }
   __pyx_t_7 = 0;
   __pyx_t_5 = 0;
 
   /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":178
- *         np.npy_intp *dims = [max_val+1]
- *         np.ndarray[np.float64_t, ndim=1] y = PyArray_ZEROS(1, dims, NPY_float64, 0)
- *         np.npy_intp *nandims = [max_val2+1]             # <<<<<<<<<<<<<<
+ *         np.npy_intp *dims = [max_val + 1, max_val2 + 1]
+ *         np.ndarray[np.float64_t, ndim=2] y = PyArray_ZEROS(2, dims, NPY_float64, 0)
+ *         np.npy_intp *nandims = [max_val2 + 1]             # <<<<<<<<<<<<<<
  *         np.ndarray[np.float_t, ndim=1] nans = PyArray_ZEROS(1, nandims, NPY_float64, 0)
  *         int ai
  */
   __pyx_v_nandims = __pyx_t_8;
 
   /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":179
- *         np.ndarray[np.float64_t, ndim=1] y = PyArray_ZEROS(1, dims, NPY_float64, 0)
- *         np.npy_intp *nandims = [max_val2+1]
+ *         np.ndarray[np.float64_t, ndim=2] y = PyArray_ZEROS(2, dims, NPY_float64, 0)
+ *         np.npy_intp *nandims = [max_val2 + 1]
  *         np.ndarray[np.float_t, ndim=1] nans = PyArray_ZEROS(1, nandims, NPY_float64, 0)             # <<<<<<<<<<<<<<
  *         int ai
  *         char bin
  *     else:
  *         for i0 in range(n0):
  */
-      __pyx_t_14 = PyInt_FromLong(__pyx_v_ai); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_14);
-      __pyx_t_5 = PyInt_FromLong(__pyx_v_bin); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_14);
-      __Pyx_GIVEREF(__pyx_t_14);
-      PyTuple_SET_ITEM(__pyx_t_13, 1, __pyx_t_5);
-      __Pyx_GIVEREF(__pyx_t_5);
-      __pyx_t_14 = 0;
-      __pyx_t_5 = 0;
-      __pyx_t_5 = PyObject_GetItem(((PyObject *)__pyx_v_y), ((PyObject *)__pyx_t_13)); if (!__pyx_t_5) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_14 = PyNumber_InPlaceAdd(__pyx_t_5, __pyx_int_1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_14);
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      if (PyObject_SetItem(((PyObject *)__pyx_v_y), ((PyObject *)__pyx_t_13), __pyx_t_14) < 0) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-      __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
+      __pyx_t_16 = __pyx_v_ai;
+      __pyx_t_17 = __pyx_v_bin;
+      *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_y.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_y.diminfo[0].strides, __pyx_t_17, __pyx_pybuffernd_y.diminfo[1].strides) += 1.0;
     }
     goto __pyx_L5;
   }
  *             if ai < 0:
  *                 raise ValueError("negative value in contingency")
  */
-      __pyx_t_16 = __pyx_v_i0;
-      __pyx_v_ai = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int32_t *, __pyx_pybuffernd_a.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_a.diminfo[0].strides));
+      __pyx_t_18 = __pyx_v_i0;
+      __pyx_v_ai = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int32_t *, __pyx_pybuffernd_a.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_a.diminfo[0].strides));
 
       /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":200
  *         for i0 in range(n0):
  *             if ai > max_val:
  *                 raise ValueError("value %i is greater than max_val (%i)"
  */
-        __pyx_t_13 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_115), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_13);
-        __Pyx_Raise(__pyx_t_13, 0, 0, 0);
-        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+        __pyx_t_14 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_115), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_14);
+        __Pyx_Raise(__pyx_t_14, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
         {__pyx_filename = __pyx_f[22]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         goto __pyx_L13;
       }
  *             bin = b[i0]
  *             if bin > max_val2:
  */
-        __pyx_t_13 = PyInt_FromLong(__pyx_v_ai); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_13);
-        __pyx_t_14 = PyInt_FromLong(__pyx_v_max_val); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_14 = PyInt_FromLong(__pyx_v_ai); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_14);
-        __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyInt_FromLong(__pyx_v_max_val); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
-        PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_13);
-        __Pyx_GIVEREF(__pyx_t_13);
-        PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_14);
-        __Pyx_GIVEREF(__pyx_t_14);
-        __pyx_t_13 = 0;
-        __pyx_t_14 = 0;
-        __pyx_t_14 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_51), ((PyObject *)__pyx_t_5)); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(((PyObject *)__pyx_t_14));
-        __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
-        __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_5);
-        PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_t_14));
-        __Pyx_GIVEREF(((PyObject *)__pyx_t_14));
-        __pyx_t_14 = 0;
-        __pyx_t_14 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_14);
-        __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
-        __Pyx_Raise(__pyx_t_14, 0, 0, 0);
-        __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-        {__pyx_filename = __pyx_f[22]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        goto __pyx_L14;
-      }
-      __pyx_L14:;
-
-      /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":205
- *                 raise ValueError("value %i is greater than max_val (%i)"
- *                                  % (ai, max_val))
- *             bin = b[i0]             # <<<<<<<<<<<<<<
- *             if bin > max_val2:
- *                 raise ValueError("value %i is greater than max_val2 (%i)" %
- */
-      __pyx_t_17 = __pyx_v_i0;
-      __pyx_v_bin = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int8_t *, __pyx_pybuffernd_b.rcbuffer->pybuffer.buf, __pyx_t_17, __pyx_pybuffernd_b.diminfo[0].strides));
-
-      /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":206
- *                                  % (ai, max_val))
- *             bin = b[i0]
- *             if bin > max_val2:             # <<<<<<<<<<<<<<
- *                 raise ValueError("value %i is greater than max_val2 (%i)" %
- *                                  (bin, max_val2))
- */
-      __pyx_t_3 = (__pyx_v_bin > __pyx_v_max_val2);
-      if (__pyx_t_3) {
-
-        /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":208
- *             if bin > max_val2:
- *                 raise ValueError("value %i is greater than max_val2 (%i)" %
- *                                  (bin, max_val2))             # <<<<<<<<<<<<<<
- *             y[ai, bin] += w[i0]
- *     return y, nans
- */
-        __pyx_t_14 = PyInt_FromLong(__pyx_v_bin); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_14);
-        __pyx_t_5 = PyInt_FromLong(__pyx_v_max_val2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_5);
-        __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_13);
         PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_14);
         __Pyx_GIVEREF(__pyx_t_14);
         __Pyx_GIVEREF(__pyx_t_5);
         __pyx_t_14 = 0;
         __pyx_t_5 = 0;
-        __pyx_t_5 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_111), ((PyObject *)__pyx_t_13)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_51), ((PyObject *)__pyx_t_13)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(((PyObject *)__pyx_t_5));
         __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
-        __pyx_t_13 = PyTuple_New(1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_13 = PyTuple_New(1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_13);
         PyTuple_SET_ITEM(__pyx_t_13, 0, ((PyObject *)__pyx_t_5));
         __Pyx_GIVEREF(((PyObject *)__pyx_t_5));
         __pyx_t_5 = 0;
-        __pyx_t_5 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_13), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_13), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
         __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
         __Pyx_Raise(__pyx_t_5, 0, 0, 0);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        {__pyx_filename = __pyx_f[22]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        goto __pyx_L14;
+      }
+      __pyx_L14:;
+
+      /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":205
+ *                 raise ValueError("value %i is greater than max_val (%i)"
+ *                                  % (ai, max_val))
+ *             bin = b[i0]             # <<<<<<<<<<<<<<
+ *             if bin > max_val2:
+ *                 raise ValueError("value %i is greater than max_val2 (%i)" %
+ */
+      __pyx_t_19 = __pyx_v_i0;
+      __pyx_v_bin = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int8_t *, __pyx_pybuffernd_b.rcbuffer->pybuffer.buf, __pyx_t_19, __pyx_pybuffernd_b.diminfo[0].strides));
+
+      /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":206
+ *                                  % (ai, max_val))
+ *             bin = b[i0]
+ *             if bin > max_val2:             # <<<<<<<<<<<<<<
+ *                 raise ValueError("value %i is greater than max_val2 (%i)" %
+ *                                  (bin, max_val2))
+ */
+      __pyx_t_3 = (__pyx_v_bin > __pyx_v_max_val2);
+      if (__pyx_t_3) {
+
+        /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":208
+ *             if bin > max_val2:
+ *                 raise ValueError("value %i is greater than max_val2 (%i)" %
+ *                                  (bin, max_val2))             # <<<<<<<<<<<<<<
+ *             y[ai, bin] += w[i0]
+ *     return y, nans
+ */
+        __pyx_t_5 = PyInt_FromLong(__pyx_v_bin); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        __pyx_t_13 = PyInt_FromLong(__pyx_v_max_val2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_13);
+        __pyx_t_14 = PyTuple_New(2); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_14);
+        PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_5);
+        __Pyx_GIVEREF(__pyx_t_5);
+        PyTuple_SET_ITEM(__pyx_t_14, 1, __pyx_t_13);
+        __Pyx_GIVEREF(__pyx_t_13);
+        __pyx_t_5 = 0;
+        __pyx_t_13 = 0;
+        __pyx_t_13 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_111), ((PyObject *)__pyx_t_14)); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(((PyObject *)__pyx_t_13));
+        __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
+        __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_14);
+        PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_t_13));
+        __Pyx_GIVEREF(((PyObject *)__pyx_t_13));
+        __pyx_t_13 = 0;
+        __pyx_t_13 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_13);
+        __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
+        __Pyx_Raise(__pyx_t_13, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
         {__pyx_filename = __pyx_f[22]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         goto __pyx_L15;
       }
  *     return y, nans
  * 
  */
-      __pyx_t_5 = PyInt_FromLong(__pyx_v_ai); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_13 = PyInt_FromLong(__pyx_v_bin); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      __pyx_t_14 = PyTuple_New(2); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_14);
-      PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_5);
-      __Pyx_GIVEREF(__pyx_t_5);
-      PyTuple_SET_ITEM(__pyx_t_14, 1, __pyx_t_13);
-      __Pyx_GIVEREF(__pyx_t_13);
-      __pyx_t_5 = 0;
-      __pyx_t_13 = 0;
-      __pyx_t_13 = PyObject_GetItem(((PyObject *)__pyx_v_y), ((PyObject *)__pyx_t_14)); if (!__pyx_t_13) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      __pyx_t_18 = __pyx_v_i0;
-      __pyx_t_5 = PyFloat_FromDouble((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float_t *, __pyx_pybuffernd_w.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_w.diminfo[0].strides))); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_19 = PyNumber_InPlaceAdd(__pyx_t_13, __pyx_t_5); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_19);
-      __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      if (PyObject_SetItem(((PyObject *)__pyx_v_y), ((PyObject *)__pyx_t_14), __pyx_t_19) < 0) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
-      __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
+      __pyx_t_20 = __pyx_v_i0;
+      __pyx_t_21 = __pyx_v_ai;
+      __pyx_t_22 = __pyx_v_bin;
+      *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_y.rcbuffer->pybuffer.buf, __pyx_t_21, __pyx_pybuffernd_y.diminfo[0].strides, __pyx_t_22, __pyx_pybuffernd_y.diminfo[1].strides) += (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float_t *, __pyx_pybuffernd_w.rcbuffer->pybuffer.buf, __pyx_t_20, __pyx_pybuffernd_w.diminfo[0].strides));
     }
   }
   __pyx_L5:;
  * @cython.boundscheck(False)
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_14 = PyTuple_New(2); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_14);
+  __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_13);
   __Pyx_INCREF(((PyObject *)__pyx_v_y));
-  PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_v_y));
+  PyTuple_SET_ITEM(__pyx_t_13, 0, ((PyObject *)__pyx_v_y));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_y));
   __Pyx_INCREF(((PyObject *)__pyx_v_nans));
-  PyTuple_SET_ITEM(__pyx_t_14, 1, ((PyObject *)__pyx_v_nans));
+  PyTuple_SET_ITEM(__pyx_t_13, 1, ((PyObject *)__pyx_v_nans));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_nans));
-  __pyx_r = ((PyObject *)__pyx_t_14);
-  __pyx_t_14 = 0;
+  __pyx_r = ((PyObject *)__pyx_t_13);
+  __pyx_t_13 = 0;
   goto __pyx_L0;
 
   __pyx_r = Py_None; __Pyx_INCREF(Py_None);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_13);
   __Pyx_XDECREF(__pyx_t_14);
-  __Pyx_XDECREF(__pyx_t_19);
   { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
     __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
     __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_a.rcbuffer->pybuffer);
   int __pyx_t_3;
   int __pyx_t_4;
   PyObject *__pyx_t_5 = NULL;
-  npy_intp __pyx_t_6[1];
+  npy_intp __pyx_t_6[2];
   PyArrayObject *__pyx_t_7 = NULL;
   npy_intp __pyx_t_8[1];
   PyArrayObject *__pyx_t_9 = NULL;
   PyObject *__pyx_t_13 = NULL;
   PyObject *__pyx_t_14 = NULL;
   Py_ssize_t __pyx_t_15;
-  Py_ssize_t __pyx_t_16;
-  Py_ssize_t __pyx_t_17;
+  int __pyx_t_16;
+  char __pyx_t_17;
   Py_ssize_t __pyx_t_18;
-  PyObject *__pyx_t_19 = NULL;
+  Py_ssize_t __pyx_t_19;
+  Py_ssize_t __pyx_t_20;
+  int __pyx_t_21;
+  char __pyx_t_22;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
   /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":229
  * 
  *     cdef:
- *         np.npy_intp *dims = [max_val+1]             # <<<<<<<<<<<<<<
- *         np.ndarray[np.float64_t, ndim=1] y = PyArray_ZEROS(1, dims, NPY_float64, 0)
- *         np.npy_intp *nandims = [max_val2+1]
+ *         np.npy_intp *dims = [max_val + 1, max_val2 + 1]             # <<<<<<<<<<<<<<
+ *         np.ndarray[np.float64_t, ndim=2] y = PyArray_ZEROS(2, dims, NPY_float64, 0)
+ *         np.npy_intp *nandims = [max_val2 + 1]
  */
   __pyx_t_6[0] = (__pyx_v_max_val + 1);
+  __pyx_t_6[1] = (__pyx_v_max_val2 + 1);
   __pyx_v_dims = __pyx_t_6;
 
   /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":230
  *     cdef:
- *         np.npy_intp *dims = [max_val+1]
- *         np.ndarray[np.float64_t, ndim=1] y = PyArray_ZEROS(1, dims, NPY_float64, 0)             # <<<<<<<<<<<<<<
- *         np.npy_intp *nandims = [max_val2+1]
+ *         np.npy_intp *dims = [max_val + 1, max_val2 + 1]
+ *         np.ndarray[np.float64_t, ndim=2] y = PyArray_ZEROS(2, dims, NPY_float64, 0)             # <<<<<<<<<<<<<<
+ *         np.npy_intp *nandims = [max_val2 + 1]
  *         np.ndarray[np.float_t, ndim=1] nans = PyArray_ZEROS(1, nandims, NPY_float64, 0)
  */
-  __pyx_t_5 = PyArray_ZEROS(1, __pyx_v_dims, NPY_FLOAT64, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyArray_ZEROS(2, __pyx_v_dims, NPY_FLOAT64, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
   if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_t_7 = ((PyArrayObject *)__pyx_t_5);
   {
     __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0, __pyx_stack) == -1)) {
       __pyx_v_y = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_y.rcbuffer->pybuffer.buf = NULL;
       {__pyx_filename = __pyx_f[22]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_y.diminfo[0].strides = __pyx_pybuffernd_y.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_y.diminfo[0].shape = __pyx_pybuffernd_y.rcbuffer->pybuffer.shape[0];
+    } else {__pyx_pybuffernd_y.diminfo[0].strides = __pyx_pybuffernd_y.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_y.diminfo[0].shape = __pyx_pybuffernd_y.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_y.diminfo[1].strides = __pyx_pybuffernd_y.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_y.diminfo[1].shape = __pyx_pybuffernd_y.rcbuffer->pybuffer.shape[1];
     }
   }
   __pyx_t_7 = 0;
   __pyx_t_5 = 0;
 
   /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":231
- *         np.npy_intp *dims = [max_val+1]
- *         np.ndarray[np.float64_t, ndim=1] y = PyArray_ZEROS(1, dims, NPY_float64, 0)
- *         np.npy_intp *nandims = [max_val2+1]             # <<<<<<<<<<<<<<
+ *         np.npy_intp *dims = [max_val + 1, max_val2 + 1]
+ *         np.ndarray[np.float64_t, ndim=2] y = PyArray_ZEROS(2, dims, NPY_float64, 0)
+ *         np.npy_intp *nandims = [max_val2 + 1]             # <<<<<<<<<<<<<<
  *         np.ndarray[np.float_t, ndim=1] nans = PyArray_ZEROS(1, nandims, NPY_float64, 0)
  *         int ai
  */
   __pyx_v_nandims = __pyx_t_8;
 
   /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":232
- *         np.ndarray[np.float64_t, ndim=1] y = PyArray_ZEROS(1, dims, NPY_float64, 0)
- *         np.npy_intp *nandims = [max_val2+1]
+ *         np.ndarray[np.float64_t, ndim=2] y = PyArray_ZEROS(2, dims, NPY_float64, 0)
+ *         np.npy_intp *nandims = [max_val2 + 1]
  *         np.ndarray[np.float_t, ndim=1] nans = PyArray_ZEROS(1, nandims, NPY_float64, 0)             # <<<<<<<<<<<<<<
  *         int ai
  *         char bin
  *     else:
  *         for i0 in range(n0):
  */
-      __pyx_t_14 = PyInt_FromLong(__pyx_v_ai); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_14);
-      __pyx_t_5 = PyInt_FromLong(__pyx_v_bin); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_14);
-      __Pyx_GIVEREF(__pyx_t_14);
-      PyTuple_SET_ITEM(__pyx_t_13, 1, __pyx_t_5);
-      __Pyx_GIVEREF(__pyx_t_5);
-      __pyx_t_14 = 0;
-      __pyx_t_5 = 0;
-      __pyx_t_5 = PyObject_GetItem(((PyObject *)__pyx_v_y), ((PyObject *)__pyx_t_13)); if (!__pyx_t_5) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_14 = PyNumber_InPlaceAdd(__pyx_t_5, __pyx_int_1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_14);
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      if (PyObject_SetItem(((PyObject *)__pyx_v_y), ((PyObject *)__pyx_t_13), __pyx_t_14) < 0) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-      __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
+      __pyx_t_16 = __pyx_v_ai;
+      __pyx_t_17 = __pyx_v_bin;
+      *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_y.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_y.diminfo[0].strides, __pyx_t_17, __pyx_pybuffernd_y.diminfo[1].strides) += 1.0;
     }
     goto __pyx_L5;
   }
  *             if ai < 0:
  *                 raise ValueError("negative value in contingency")
  */
-      __pyx_t_16 = __pyx_v_i0;
-      __pyx_v_ai = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_a.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_a.diminfo[0].strides));
+      __pyx_t_18 = __pyx_v_i0;
+      __pyx_v_ai = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_a.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_a.diminfo[0].strides));
 
       /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":253
  *         for i0 in range(n0):
  *             if ai > max_val:
  *                 raise ValueError("value %i is greater than max_val (%i)"
  */
-        __pyx_t_13 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_118), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_13);
-        __Pyx_Raise(__pyx_t_13, 0, 0, 0);
-        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+        __pyx_t_14 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_118), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_14);
+        __Pyx_Raise(__pyx_t_14, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
         {__pyx_filename = __pyx_f[22]; __pyx_lineno = 254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         goto __pyx_L13;
       }
  *             bin = b[i0]
  *             if bin > max_val2:
  */
-        __pyx_t_13 = PyInt_FromLong(__pyx_v_ai); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_13);
-        __pyx_t_14 = PyInt_FromLong(__pyx_v_max_val); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_14 = PyInt_FromLong(__pyx_v_ai); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_14);
-        __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyInt_FromLong(__pyx_v_max_val); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
-        PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_13);
-        __Pyx_GIVEREF(__pyx_t_13);
-        PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_14);
-        __Pyx_GIVEREF(__pyx_t_14);
-        __pyx_t_13 = 0;
-        __pyx_t_14 = 0;
-        __pyx_t_14 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_51), ((PyObject *)__pyx_t_5)); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(((PyObject *)__pyx_t_14));
-        __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
-        __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_5);
-        PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_t_14));
-        __Pyx_GIVEREF(((PyObject *)__pyx_t_14));
-        __pyx_t_14 = 0;
-        __pyx_t_14 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_14);
-        __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
-        __Pyx_Raise(__pyx_t_14, 0, 0, 0);
-        __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-        {__pyx_filename = __pyx_f[22]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        goto __pyx_L14;
-      }
-      __pyx_L14:;
-
-      /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":258
- *                 raise ValueError("value %i is greater than max_val (%i)"
- *                                  % (ai, max_val))
- *             bin = b[i0]             # <<<<<<<<<<<<<<
- *             if bin > max_val2:
- *                 raise ValueError("value %i is greater than max_val2 (%i)" %
- */
-      __pyx_t_17 = __pyx_v_i0;
-      __pyx_v_bin = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int8_t *, __pyx_pybuffernd_b.rcbuffer->pybuffer.buf, __pyx_t_17, __pyx_pybuffernd_b.diminfo[0].strides));
-
-      /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":259
- *                                  % (ai, max_val))
- *             bin = b[i0]
- *             if bin > max_val2:             # <<<<<<<<<<<<<<
- *                 raise ValueError("value %i is greater than max_val2 (%i)" %
- *                                  (bin, max_val2))
- */
-      __pyx_t_3 = (__pyx_v_bin > __pyx_v_max_val2);
-      if (__pyx_t_3) {
-
-        /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":261
- *             if bin > max_val2:
- *                 raise ValueError("value %i is greater than max_val2 (%i)" %
- *                                  (bin, max_val2))             # <<<<<<<<<<<<<<
- *             y[ai, bin] += w[i0]
- *     return y, nans
- */
-        __pyx_t_14 = PyInt_FromLong(__pyx_v_bin); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_14);
-        __pyx_t_5 = PyInt_FromLong(__pyx_v_max_val2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_5);
-        __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_13);
         PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_14);
         __Pyx_GIVEREF(__pyx_t_14);
         __Pyx_GIVEREF(__pyx_t_5);
         __pyx_t_14 = 0;
         __pyx_t_5 = 0;
-        __pyx_t_5 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_111), ((PyObject *)__pyx_t_13)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_51), ((PyObject *)__pyx_t_13)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(((PyObject *)__pyx_t_5));
         __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
-        __pyx_t_13 = PyTuple_New(1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_13 = PyTuple_New(1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_13);
         PyTuple_SET_ITEM(__pyx_t_13, 0, ((PyObject *)__pyx_t_5));
         __Pyx_GIVEREF(((PyObject *)__pyx_t_5));
         __pyx_t_5 = 0;
-        __pyx_t_5 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_13), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_13), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
         __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
         __Pyx_Raise(__pyx_t_5, 0, 0, 0);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        {__pyx_filename = __pyx_f[22]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        goto __pyx_L14;
+      }
+      __pyx_L14:;
+
+      /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":258
+ *                 raise ValueError("value %i is greater than max_val (%i)"
+ *                                  % (ai, max_val))
+ *             bin = b[i0]             # <<<<<<<<<<<<<<
+ *             if bin > max_val2:
+ *                 raise ValueError("value %i is greater than max_val2 (%i)" %
+ */
+      __pyx_t_19 = __pyx_v_i0;
+      __pyx_v_bin = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int8_t *, __pyx_pybuffernd_b.rcbuffer->pybuffer.buf, __pyx_t_19, __pyx_pybuffernd_b.diminfo[0].strides));
+
+      /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":259
+ *                                  % (ai, max_val))
+ *             bin = b[i0]
+ *             if bin > max_val2:             # <<<<<<<<<<<<<<
+ *                 raise ValueError("value %i is greater than max_val2 (%i)" %
+ *                                  (bin, max_val2))
+ */
+      __pyx_t_3 = (__pyx_v_bin > __pyx_v_max_val2);
+      if (__pyx_t_3) {
+
+        /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/32bit/contingency.pyx":261
+ *             if bin > max_val2:
+ *                 raise ValueError("value %i is greater than max_val2 (%i)" %
+ *                                  (bin, max_val2))             # <<<<<<<<<<<<<<
+ *             y[ai, bin] += w[i0]
+ *     return y, nans
+ */
+        __pyx_t_5 = PyInt_FromLong(__pyx_v_bin); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        __pyx_t_13 = PyInt_FromLong(__pyx_v_max_val2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_13);
+        __pyx_t_14 = PyTuple_New(2); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_14);
+        PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_5);
+        __Pyx_GIVEREF(__pyx_t_5);
+        PyTuple_SET_ITEM(__pyx_t_14, 1, __pyx_t_13);
+        __Pyx_GIVEREF(__pyx_t_13);
+        __pyx_t_5 = 0;
+        __pyx_t_13 = 0;
+        __pyx_t_13 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_111), ((PyObject *)__pyx_t_14)); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(((PyObject *)__pyx_t_13));
+        __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
+        __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_14);
+        PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_t_13));
+        __Pyx_GIVEREF(((PyObject *)__pyx_t_13));
+        __pyx_t_13 = 0;
+        __pyx_t_13 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_13);
+        __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
+        __Pyx_Raise(__pyx_t_13, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
         {__pyx_filename = __pyx_f[22]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         goto __pyx_L15;
       }
  *     return y, nans
  * 
  */
-      __pyx_t_5 = PyInt_FromLong(__pyx_v_ai); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_13 = PyInt_FromLong(__pyx_v_bin); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      __pyx_t_14 = PyTuple_New(2); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_14);
-      PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_5);
-      __Pyx_GIVEREF(__pyx_t_5);
-      PyTuple_SET_ITEM(__pyx_t_14, 1, __pyx_t_13);
-      __Pyx_GIVEREF(__pyx_t_13);
-      __pyx_t_5 = 0;
-      __pyx_t_13 = 0;
-      __pyx_t_13 = PyObject_GetItem(((PyObject *)__pyx_v_y), ((PyObject *)__pyx_t_14)); if (!__pyx_t_13) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      __pyx_t_18 = __pyx_v_i0;
-      __pyx_t_5 = PyFloat_FromDouble((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float_t *, __pyx_pybuffernd_w.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_w.diminfo[0].strides))); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_19 = PyNumber_InPlaceAdd(__pyx_t_13, __pyx_t_5); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_19);
-      __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      if (PyObject_SetItem(((PyObject *)__pyx_v_y), ((PyObject *)__pyx_t_14), __pyx_t_19) < 0) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
-      __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
+      __pyx_t_20 = __pyx_v_i0;
+      __pyx_t_21 = __pyx_v_ai;
+      __pyx_t_22 = __pyx_v_bin;
+      *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_y.rcbuffer->pybuffer.buf, __pyx_t_21, __pyx_pybuffernd_y.diminfo[0].strides, __pyx_t_22, __pyx_pybuffernd_y.diminfo[1].strides) += (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float_t *, __pyx_pybuffernd_w.rcbuffer->pybuffer.buf, __pyx_t_20, __pyx_pybuffernd_w.diminfo[0].strides));
     }
   }
   __pyx_L5:;
  * @cython.boundscheck(False)
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_14 = PyTuple_New(2); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_14);
+  __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_13);
   __Pyx_INCREF(((PyObject *)__pyx_v_y));
-  PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_v_y));
+  PyTuple_SET_ITEM(__pyx_t_13, 0, ((PyObject *)__pyx_v_y));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_y));
   __Pyx_INCREF(((PyObject *)__pyx_v_nans));
-  PyTuple_SET_ITEM(__pyx_t_14, 1, ((PyObject *)__pyx_v_nans));
+  PyTuple_SET_ITEM(__pyx_t_13, 1, ((PyObject *)__pyx_v_nans));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_nans));
-  __pyx_r = ((PyObject *)__pyx_t_14);
-  __pyx_t_14 = 0;
+  __pyx_r = ((PyObject *)__pyx_t_13);
+  __pyx_t_13 = 0;
   goto __pyx_L0;
 
   __pyx_r = Py_None; __Pyx_INCREF(Py_None);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_13);
   __Pyx_XDECREF(__pyx_t_14);
-  __Pyx_XDECREF(__pyx_t_19);
   { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
     __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
     __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_a.rcbuffer->pybuffer);

File bottleneck/src/func/64bit/func.c

-/* Generated by Cython 0.17.2 on Mon Dec 31 00:56:39 2012 */
+/* Generated by Cython 0.17.2 on Tue Jan  1 17:14:09 2013 */
 
 #define PY_SSIZE_T_CLEAN
 #include "Python.h"
   int __pyx_t_3;
   int __pyx_t_4;
   PyObject *__pyx_t_5 = NULL;
-  npy_intp __pyx_t_6[1];
+  npy_intp __pyx_t_6[2];
   PyArrayObject *__pyx_t_7 = NULL;
   npy_intp __pyx_t_8[1];
   PyArrayObject *__pyx_t_9 = NULL;
   PyObject *__pyx_t_13 = NULL;
   PyObject *__pyx_t_14 = NULL;
   Py_ssize_t __pyx_t_15;
-  Py_ssize_t __pyx_t_16;
-  Py_ssize_t __pyx_t_17;
+  int __pyx_t_16;
+  char __pyx_t_17;
   Py_ssize_t __pyx_t_18;
-  PyObject *__pyx_t_19 = NULL;
+  Py_ssize_t __pyx_t_19;
+  Py_ssize_t __pyx_t_20;
+  int __pyx_t_21;
+  char __pyx_t_22;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
   /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":123
  * 
  *     cdef:
- *         np.npy_intp *dims = [max_val+1]             # <<<<<<<<<<<<<<
- *         np.ndarray[np.float64_t, ndim=1] y = PyArray_ZEROS(1, dims, NPY_float64, 0)
- *         np.npy_intp *nandims = [max_val2+1]
+ *         np.npy_intp *dims = [max_val + 1, max_val2 + 1]             # <<<<<<<<<<<<<<
+ *         np.ndarray[np.float64_t, ndim=2] y = PyArray_ZEROS(2, dims, NPY_float64, 0)
+ *         np.npy_intp *nandims = [max_val2 + 1]
  */
   __pyx_t_6[0] = (__pyx_v_max_val + 1);
+  __pyx_t_6[1] = (__pyx_v_max_val2 + 1);
   __pyx_v_dims = __pyx_t_6;
 
   /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":124
  *     cdef:
- *         np.npy_intp *dims = [max_val+1]
- *         np.ndarray[np.float64_t, ndim=1] y = PyArray_ZEROS(1, dims, NPY_float64, 0)             # <<<<<<<<<<<<<<
- *         np.npy_intp *nandims = [max_val2+1]
+ *         np.npy_intp *dims = [max_val + 1, max_val2 + 1]
+ *         np.ndarray[np.float64_t, ndim=2] y = PyArray_ZEROS(2, dims, NPY_float64, 0)             # <<<<<<<<<<<<<<
+ *         np.npy_intp *nandims = [max_val2 + 1]
  *         np.ndarray[np.float_t, ndim=1] nans = PyArray_ZEROS(1, nandims, NPY_float64, 0)
  */
-  __pyx_t_5 = PyArray_ZEROS(1, __pyx_v_dims, NPY_FLOAT64, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyArray_ZEROS(2, __pyx_v_dims, NPY_FLOAT64, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
   if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_t_7 = ((PyArrayObject *)__pyx_t_5);
   {
     __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0, __pyx_stack) == -1)) {
       __pyx_v_y = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_y.rcbuffer->pybuffer.buf = NULL;
       {__pyx_filename = __pyx_f[22]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_y.diminfo[0].strides = __pyx_pybuffernd_y.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_y.diminfo[0].shape = __pyx_pybuffernd_y.rcbuffer->pybuffer.shape[0];
+    } else {__pyx_pybuffernd_y.diminfo[0].strides = __pyx_pybuffernd_y.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_y.diminfo[0].shape = __pyx_pybuffernd_y.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_y.diminfo[1].strides = __pyx_pybuffernd_y.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_y.diminfo[1].shape = __pyx_pybuffernd_y.rcbuffer->pybuffer.shape[1];
     }
   }
   __pyx_t_7 = 0;
   __pyx_t_5 = 0;
 
   /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":125
- *         np.npy_intp *dims = [max_val+1]
- *         np.ndarray[np.float64_t, ndim=1] y = PyArray_ZEROS(1, dims, NPY_float64, 0)
- *         np.npy_intp *nandims = [max_val2+1]             # <<<<<<<<<<<<<<
+ *         np.npy_intp *dims = [max_val + 1, max_val2 + 1]
+ *         np.ndarray[np.float64_t, ndim=2] y = PyArray_ZEROS(2, dims, NPY_float64, 0)
+ *         np.npy_intp *nandims = [max_val2 + 1]             # <<<<<<<<<<<<<<
  *         np.ndarray[np.float_t, ndim=1] nans = PyArray_ZEROS(1, nandims, NPY_float64, 0)
  *         int ai
  */
   __pyx_v_nandims = __pyx_t_8;
 
   /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":126
- *         np.ndarray[np.float64_t, ndim=1] y = PyArray_ZEROS(1, dims, NPY_float64, 0)
- *         np.npy_intp *nandims = [max_val2+1]
+ *         np.ndarray[np.float64_t, ndim=2] y = PyArray_ZEROS(2, dims, NPY_float64, 0)
+ *         np.npy_intp *nandims = [max_val2 + 1]
  *         np.ndarray[np.float_t, ndim=1] nans = PyArray_ZEROS(1, nandims, NPY_float64, 0)             # <<<<<<<<<<<<<<
  *         int ai
  *         char bin
  *     else:
  *         for i0 in range(n0):
  */
-      __pyx_t_14 = PyInt_FromLong(__pyx_v_ai); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_14);
-      __pyx_t_5 = PyInt_FromLong(__pyx_v_bin); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_14);
-      __Pyx_GIVEREF(__pyx_t_14);
-      PyTuple_SET_ITEM(__pyx_t_13, 1, __pyx_t_5);
-      __Pyx_GIVEREF(__pyx_t_5);
-      __pyx_t_14 = 0;
-      __pyx_t_5 = 0;
-      __pyx_t_5 = PyObject_GetItem(((PyObject *)__pyx_v_y), ((PyObject *)__pyx_t_13)); if (!__pyx_t_5) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_14 = PyNumber_InPlaceAdd(__pyx_t_5, __pyx_int_1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_14);
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      if (PyObject_SetItem(((PyObject *)__pyx_v_y), ((PyObject *)__pyx_t_13), __pyx_t_14) < 0) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-      __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
+      __pyx_t_16 = __pyx_v_ai;
+      __pyx_t_17 = __pyx_v_bin;
+      *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_y.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_y.diminfo[0].strides, __pyx_t_17, __pyx_pybuffernd_y.diminfo[1].strides) += 1.0;
     }
     goto __pyx_L5;
   }
  *             if ai < 0:
  *                 raise ValueError("negative value in contingency")
  */
-      __pyx_t_16 = __pyx_v_i0;
-      __pyx_v_ai = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int8_t *, __pyx_pybuffernd_a.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_a.diminfo[0].strides));
+      __pyx_t_18 = __pyx_v_i0;
+      __pyx_v_ai = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int8_t *, __pyx_pybuffernd_a.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_a.diminfo[0].strides));
 
       /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":147
  *         for i0 in range(n0):
  *             if ai > max_val:
  *                 raise ValueError("value %i is greater than max_val (%i)"
  */
-        __pyx_t_13 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_112), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_13);
-        __Pyx_Raise(__pyx_t_13, 0, 0, 0);
-        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+        __pyx_t_14 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_112), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_14);
+        __Pyx_Raise(__pyx_t_14, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
         {__pyx_filename = __pyx_f[22]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         goto __pyx_L13;
       }
  *             bin = b[i0]
  *             if bin > max_val2:
  */
-        __pyx_t_13 = PyInt_FromLong(__pyx_v_ai); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_13);
-        __pyx_t_14 = PyInt_FromLong(__pyx_v_max_val); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_14 = PyInt_FromLong(__pyx_v_ai); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_14);
-        __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyInt_FromLong(__pyx_v_max_val); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
-        PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_13);
-        __Pyx_GIVEREF(__pyx_t_13);
-        PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_14);
-        __Pyx_GIVEREF(__pyx_t_14);
-        __pyx_t_13 = 0;
-        __pyx_t_14 = 0;
-        __pyx_t_14 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_51), ((PyObject *)__pyx_t_5)); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(((PyObject *)__pyx_t_14));
-        __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
-        __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_5);
-        PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_t_14));
-        __Pyx_GIVEREF(((PyObject *)__pyx_t_14));
-        __pyx_t_14 = 0;
-        __pyx_t_14 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_14);
-        __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
-        __Pyx_Raise(__pyx_t_14, 0, 0, 0);
-        __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-        {__pyx_filename = __pyx_f[22]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        goto __pyx_L14;
-      }
-      __pyx_L14:;
-
-      /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":152
- *                 raise ValueError("value %i is greater than max_val (%i)"
- *                                  % (ai, max_val))
- *             bin = b[i0]             # <<<<<<<<<<<<<<
- *             if bin > max_val2:
- *                 raise ValueError("value %i is greater than max_val2 (%i)" %
- */
-      __pyx_t_17 = __pyx_v_i0;
-      __pyx_v_bin = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int8_t *, __pyx_pybuffernd_b.rcbuffer->pybuffer.buf, __pyx_t_17, __pyx_pybuffernd_b.diminfo[0].strides));
-
-      /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":153
- *                                  % (ai, max_val))
- *             bin = b[i0]
- *             if bin > max_val2:             # <<<<<<<<<<<<<<
- *                 raise ValueError("value %i is greater than max_val2 (%i)" %
- *                                  (bin, max_val2))
- */
-      __pyx_t_3 = (__pyx_v_bin > __pyx_v_max_val2);
-      if (__pyx_t_3) {
-
-        /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":155
- *             if bin > max_val2:
- *                 raise ValueError("value %i is greater than max_val2 (%i)" %
- *                                  (bin, max_val2))             # <<<<<<<<<<<<<<
- *             y[ai, bin] += w[i0]
- *     return y, nans
- */
-        __pyx_t_14 = PyInt_FromLong(__pyx_v_bin); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_14);
-        __pyx_t_5 = PyInt_FromLong(__pyx_v_max_val2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_5);
-        __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_13);
         PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_14);
         __Pyx_GIVEREF(__pyx_t_14);
         __Pyx_GIVEREF(__pyx_t_5);
         __pyx_t_14 = 0;
         __pyx_t_5 = 0;
-        __pyx_t_5 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_111), ((PyObject *)__pyx_t_13)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_51), ((PyObject *)__pyx_t_13)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(((PyObject *)__pyx_t_5));
         __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
-        __pyx_t_13 = PyTuple_New(1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_13 = PyTuple_New(1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_13);
         PyTuple_SET_ITEM(__pyx_t_13, 0, ((PyObject *)__pyx_t_5));
         __Pyx_GIVEREF(((PyObject *)__pyx_t_5));
         __pyx_t_5 = 0;
-        __pyx_t_5 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_13), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_13), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
         __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
         __Pyx_Raise(__pyx_t_5, 0, 0, 0);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        {__pyx_filename = __pyx_f[22]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        goto __pyx_L14;
+      }
+      __pyx_L14:;
+
+      /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":152
+ *                 raise ValueError("value %i is greater than max_val (%i)"
+ *                                  % (ai, max_val))
+ *             bin = b[i0]             # <<<<<<<<<<<<<<
+ *             if bin > max_val2:
+ *                 raise ValueError("value %i is greater than max_val2 (%i)" %
+ */
+      __pyx_t_19 = __pyx_v_i0;
+      __pyx_v_bin = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int8_t *, __pyx_pybuffernd_b.rcbuffer->pybuffer.buf, __pyx_t_19, __pyx_pybuffernd_b.diminfo[0].strides));
+
+      /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":153
+ *                                  % (ai, max_val))
+ *             bin = b[i0]
+ *             if bin > max_val2:             # <<<<<<<<<<<<<<
+ *                 raise ValueError("value %i is greater than max_val2 (%i)" %
+ *                                  (bin, max_val2))
+ */
+      __pyx_t_3 = (__pyx_v_bin > __pyx_v_max_val2);
+      if (__pyx_t_3) {
+
+        /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":155
+ *             if bin > max_val2:
+ *                 raise ValueError("value %i is greater than max_val2 (%i)" %
+ *                                  (bin, max_val2))             # <<<<<<<<<<<<<<
+ *             y[ai, bin] += w[i0]
+ *     return y, nans
+ */
+        __pyx_t_5 = PyInt_FromLong(__pyx_v_bin); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        __pyx_t_13 = PyInt_FromLong(__pyx_v_max_val2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_13);
+        __pyx_t_14 = PyTuple_New(2); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_14);
+        PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_5);
+        __Pyx_GIVEREF(__pyx_t_5);
+        PyTuple_SET_ITEM(__pyx_t_14, 1, __pyx_t_13);
+        __Pyx_GIVEREF(__pyx_t_13);
+        __pyx_t_5 = 0;
+        __pyx_t_13 = 0;
+        __pyx_t_13 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_111), ((PyObject *)__pyx_t_14)); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(((PyObject *)__pyx_t_13));
+        __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
+        __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_14);
+        PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_t_13));
+        __Pyx_GIVEREF(((PyObject *)__pyx_t_13));
+        __pyx_t_13 = 0;
+        __pyx_t_13 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_13);
+        __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
+        __Pyx_Raise(__pyx_t_13, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
         {__pyx_filename = __pyx_f[22]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         goto __pyx_L15;
       }
  *     return y, nans
  * 
  */
-      __pyx_t_5 = PyInt_FromLong(__pyx_v_ai); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_13 = PyInt_FromLong(__pyx_v_bin); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      __pyx_t_14 = PyTuple_New(2); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_14);
-      PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_5);
-      __Pyx_GIVEREF(__pyx_t_5);
-      PyTuple_SET_ITEM(__pyx_t_14, 1, __pyx_t_13);
-      __Pyx_GIVEREF(__pyx_t_13);
-      __pyx_t_5 = 0;
-      __pyx_t_13 = 0;
-      __pyx_t_13 = PyObject_GetItem(((PyObject *)__pyx_v_y), ((PyObject *)__pyx_t_14)); if (!__pyx_t_13) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      __pyx_t_18 = __pyx_v_i0;
-      __pyx_t_5 = PyFloat_FromDouble((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float_t *, __pyx_pybuffernd_w.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_w.diminfo[0].strides))); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_19 = PyNumber_InPlaceAdd(__pyx_t_13, __pyx_t_5); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_19);
-      __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      if (PyObject_SetItem(((PyObject *)__pyx_v_y), ((PyObject *)__pyx_t_14), __pyx_t_19) < 0) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
-      __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
+      __pyx_t_20 = __pyx_v_i0;
+      __pyx_t_21 = __pyx_v_ai;
+      __pyx_t_22 = __pyx_v_bin;
+      *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_y.rcbuffer->pybuffer.buf, __pyx_t_21, __pyx_pybuffernd_y.diminfo[0].strides, __pyx_t_22, __pyx_pybuffernd_y.diminfo[1].strides) += (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float_t *, __pyx_pybuffernd_w.rcbuffer->pybuffer.buf, __pyx_t_20, __pyx_pybuffernd_w.diminfo[0].strides));
     }
   }
   __pyx_L5:;
  * @cython.boundscheck(False)
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_14 = PyTuple_New(2); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_14);
+  __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_13);
   __Pyx_INCREF(((PyObject *)__pyx_v_y));
-  PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_v_y));
+  PyTuple_SET_ITEM(__pyx_t_13, 0, ((PyObject *)__pyx_v_y));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_y));
   __Pyx_INCREF(((PyObject *)__pyx_v_nans));
-  PyTuple_SET_ITEM(__pyx_t_14, 1, ((PyObject *)__pyx_v_nans));
+  PyTuple_SET_ITEM(__pyx_t_13, 1, ((PyObject *)__pyx_v_nans));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_nans));
-  __pyx_r = ((PyObject *)__pyx_t_14);
-  __pyx_t_14 = 0;
+  __pyx_r = ((PyObject *)__pyx_t_13);
+  __pyx_t_13 = 0;
   goto __pyx_L0;
 
   __pyx_r = Py_None; __Pyx_INCREF(Py_None);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_13);
   __Pyx_XDECREF(__pyx_t_14);
-  __Pyx_XDECREF(__pyx_t_19);
   { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
     __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
     __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_a.rcbuffer->pybuffer);
   int __pyx_t_3;
   int __pyx_t_4;
   PyObject *__pyx_t_5 = NULL;
-  npy_intp __pyx_t_6[1];
+  npy_intp __pyx_t_6[2];
   PyArrayObject *__pyx_t_7 = NULL;
   npy_intp __pyx_t_8[1];
   PyArrayObject *__pyx_t_9 = NULL;
   PyObject *__pyx_t_13 = NULL;
   PyObject *__pyx_t_14 = NULL;
   Py_ssize_t __pyx_t_15;
-  Py_ssize_t __pyx_t_16;
-  Py_ssize_t __pyx_t_17;
+  int __pyx_t_16;
+  char __pyx_t_17;
   Py_ssize_t __pyx_t_18;
-  PyObject *__pyx_t_19 = NULL;
+  Py_ssize_t __pyx_t_19;
+  Py_ssize_t __pyx_t_20;
+  int __pyx_t_21;
+  char __pyx_t_22;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
   /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":176
  * 
  *     cdef:
- *         np.npy_intp *dims = [max_val+1]             # <<<<<<<<<<<<<<
- *         np.ndarray[np.float64_t, ndim=1] y = PyArray_ZEROS(1, dims, NPY_float64, 0)
- *         np.npy_intp *nandims = [max_val2+1]
+ *         np.npy_intp *dims = [max_val + 1, max_val2 + 1]             # <<<<<<<<<<<<<<
+ *         np.ndarray[np.float64_t, ndim=2] y = PyArray_ZEROS(2, dims, NPY_float64, 0)
+ *         np.npy_intp *nandims = [max_val2 + 1]
  */
   __pyx_t_6[0] = (__pyx_v_max_val + 1);
+  __pyx_t_6[1] = (__pyx_v_max_val2 + 1);
   __pyx_v_dims = __pyx_t_6;
 
   /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":177
  *     cdef:
- *         np.npy_intp *dims = [max_val+1]
- *         np.ndarray[np.float64_t, ndim=1] y = PyArray_ZEROS(1, dims, NPY_float64, 0)             # <<<<<<<<<<<<<<
- *         np.npy_intp *nandims = [max_val2+1]
+ *         np.npy_intp *dims = [max_val + 1, max_val2 + 1]
+ *         np.ndarray[np.float64_t, ndim=2] y = PyArray_ZEROS(2, dims, NPY_float64, 0)             # <<<<<<<<<<<<<<
+ *         np.npy_intp *nandims = [max_val2 + 1]
  *         np.ndarray[np.float_t, ndim=1] nans = PyArray_ZEROS(1, nandims, NPY_float64, 0)
  */
-  __pyx_t_5 = PyArray_ZEROS(1, __pyx_v_dims, NPY_FLOAT64, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyArray_ZEROS(2, __pyx_v_dims, NPY_FLOAT64, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
   if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_t_7 = ((PyArrayObject *)__pyx_t_5);
   {
     __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0, __pyx_stack) == -1)) {
       __pyx_v_y = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_y.rcbuffer->pybuffer.buf = NULL;
       {__pyx_filename = __pyx_f[22]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else {__pyx_pybuffernd_y.diminfo[0].strides = __pyx_pybuffernd_y.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_y.diminfo[0].shape = __pyx_pybuffernd_y.rcbuffer->pybuffer.shape[0];
+    } else {__pyx_pybuffernd_y.diminfo[0].strides = __pyx_pybuffernd_y.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_y.diminfo[0].shape = __pyx_pybuffernd_y.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_y.diminfo[1].strides = __pyx_pybuffernd_y.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_y.diminfo[1].shape = __pyx_pybuffernd_y.rcbuffer->pybuffer.shape[1];
     }
   }
   __pyx_t_7 = 0;
   __pyx_t_5 = 0;
 
   /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":178
- *         np.npy_intp *dims = [max_val+1]
- *         np.ndarray[np.float64_t, ndim=1] y = PyArray_ZEROS(1, dims, NPY_float64, 0)
- *         np.npy_intp *nandims = [max_val2+1]             # <<<<<<<<<<<<<<
+ *         np.npy_intp *dims = [max_val + 1, max_val2 + 1]
+ *         np.ndarray[np.float64_t, ndim=2] y = PyArray_ZEROS(2, dims, NPY_float64, 0)
+ *         np.npy_intp *nandims = [max_val2 + 1]             # <<<<<<<<<<<<<<
  *         np.ndarray[np.float_t, ndim=1] nans = PyArray_ZEROS(1, nandims, NPY_float64, 0)
  *         int ai
  */
   __pyx_v_nandims = __pyx_t_8;
 
   /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":179
- *         np.ndarray[np.float64_t, ndim=1] y = PyArray_ZEROS(1, dims, NPY_float64, 0)
- *         np.npy_intp *nandims = [max_val2+1]
+ *         np.ndarray[np.float64_t, ndim=2] y = PyArray_ZEROS(2, dims, NPY_float64, 0)
+ *         np.npy_intp *nandims = [max_val2 + 1]
  *         np.ndarray[np.float_t, ndim=1] nans = PyArray_ZEROS(1, nandims, NPY_float64, 0)             # <<<<<<<<<<<<<<
  *         int ai
  *         char bin
  *     else:
  *         for i0 in range(n0):
  */
-      __pyx_t_14 = PyInt_FromLong(__pyx_v_ai); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_14);
-      __pyx_t_5 = PyInt_FromLong(__pyx_v_bin); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_14);
-      __Pyx_GIVEREF(__pyx_t_14);
-      PyTuple_SET_ITEM(__pyx_t_13, 1, __pyx_t_5);
-      __Pyx_GIVEREF(__pyx_t_5);
-      __pyx_t_14 = 0;
-      __pyx_t_5 = 0;
-      __pyx_t_5 = PyObject_GetItem(((PyObject *)__pyx_v_y), ((PyObject *)__pyx_t_13)); if (!__pyx_t_5) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_14 = PyNumber_InPlaceAdd(__pyx_t_5, __pyx_int_1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_14);
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      if (PyObject_SetItem(((PyObject *)__pyx_v_y), ((PyObject *)__pyx_t_13), __pyx_t_14) < 0) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-      __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
+      __pyx_t_16 = __pyx_v_ai;
+      __pyx_t_17 = __pyx_v_bin;
+      *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_y.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_y.diminfo[0].strides, __pyx_t_17, __pyx_pybuffernd_y.diminfo[1].strides) += 1.0;
     }
     goto __pyx_L5;
   }
  *             if ai < 0:
  *                 raise ValueError("negative value in contingency")
  */
-      __pyx_t_16 = __pyx_v_i0;
-      __pyx_v_ai = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int32_t *, __pyx_pybuffernd_a.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_a.diminfo[0].strides));
+      __pyx_t_18 = __pyx_v_i0;
+      __pyx_v_ai = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int32_t *, __pyx_pybuffernd_a.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_a.diminfo[0].strides));
 
       /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":200
  *         for i0 in range(n0):
  *             if ai > max_val:
  *                 raise ValueError("value %i is greater than max_val (%i)"
  */
-        __pyx_t_13 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_115), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_13);
-        __Pyx_Raise(__pyx_t_13, 0, 0, 0);
-        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+        __pyx_t_14 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_115), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_14);
+        __Pyx_Raise(__pyx_t_14, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
         {__pyx_filename = __pyx_f[22]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         goto __pyx_L13;
       }
  *             bin = b[i0]
  *             if bin > max_val2:
  */
-        __pyx_t_13 = PyInt_FromLong(__pyx_v_ai); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_13);
-        __pyx_t_14 = PyInt_FromLong(__pyx_v_max_val); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_14 = PyInt_FromLong(__pyx_v_ai); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_14);
-        __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyInt_FromLong(__pyx_v_max_val); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
-        PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_13);
-        __Pyx_GIVEREF(__pyx_t_13);
-        PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_14);
-        __Pyx_GIVEREF(__pyx_t_14);
-        __pyx_t_13 = 0;
-        __pyx_t_14 = 0;
-        __pyx_t_14 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_51), ((PyObject *)__pyx_t_5)); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(((PyObject *)__pyx_t_14));
-        __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
-        __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_5);
-        PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_t_14));
-        __Pyx_GIVEREF(((PyObject *)__pyx_t_14));
-        __pyx_t_14 = 0;
-        __pyx_t_14 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_14);
-        __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
-        __Pyx_Raise(__pyx_t_14, 0, 0, 0);
-        __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-        {__pyx_filename = __pyx_f[22]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        goto __pyx_L14;
-      }
-      __pyx_L14:;
-
-      /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":205
- *                 raise ValueError("value %i is greater than max_val (%i)"
- *                                  % (ai, max_val))
- *             bin = b[i0]             # <<<<<<<<<<<<<<
- *             if bin > max_val2:
- *                 raise ValueError("value %i is greater than max_val2 (%i)" %
- */
-      __pyx_t_17 = __pyx_v_i0;
-      __pyx_v_bin = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int8_t *, __pyx_pybuffernd_b.rcbuffer->pybuffer.buf, __pyx_t_17, __pyx_pybuffernd_b.diminfo[0].strides));
-
-      /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":206
- *                                  % (ai, max_val))
- *             bin = b[i0]
- *             if bin > max_val2:             # <<<<<<<<<<<<<<
- *                 raise ValueError("value %i is greater than max_val2 (%i)" %
- *                                  (bin, max_val2))
- */
-      __pyx_t_3 = (__pyx_v_bin > __pyx_v_max_val2);
-      if (__pyx_t_3) {
-
-        /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":208
- *             if bin > max_val2:
- *                 raise ValueError("value %i is greater than max_val2 (%i)" %
- *                                  (bin, max_val2))             # <<<<<<<<<<<<<<
- *             y[ai, bin] += w[i0]
- *     return y, nans
- */
-        __pyx_t_14 = PyInt_FromLong(__pyx_v_bin); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_14);
-        __pyx_t_5 = PyInt_FromLong(__pyx_v_max_val2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_5);
-        __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_13);
         PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_14);
         __Pyx_GIVEREF(__pyx_t_14);
         __Pyx_GIVEREF(__pyx_t_5);
         __pyx_t_14 = 0;
         __pyx_t_5 = 0;
-        __pyx_t_5 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_111), ((PyObject *)__pyx_t_13)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_51), ((PyObject *)__pyx_t_13)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(((PyObject *)__pyx_t_5));
         __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
-        __pyx_t_13 = PyTuple_New(1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_13 = PyTuple_New(1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_13);
         PyTuple_SET_ITEM(__pyx_t_13, 0, ((PyObject *)__pyx_t_5));
         __Pyx_GIVEREF(((PyObject *)__pyx_t_5));
         __pyx_t_5 = 0;
-        __pyx_t_5 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_13), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_t_5 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_13), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         __Pyx_GOTREF(__pyx_t_5);
         __Pyx_DECREF(((PyObject *)__pyx_t_13)); __pyx_t_13 = 0;
         __Pyx_Raise(__pyx_t_5, 0, 0, 0);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        {__pyx_filename = __pyx_f[22]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        goto __pyx_L14;
+      }
+      __pyx_L14:;
+
+      /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":205
+ *                 raise ValueError("value %i is greater than max_val (%i)"
+ *                                  % (ai, max_val))
+ *             bin = b[i0]             # <<<<<<<<<<<<<<
+ *             if bin > max_val2:
+ *                 raise ValueError("value %i is greater than max_val2 (%i)" %
+ */
+      __pyx_t_19 = __pyx_v_i0;
+      __pyx_v_bin = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int8_t *, __pyx_pybuffernd_b.rcbuffer->pybuffer.buf, __pyx_t_19, __pyx_pybuffernd_b.diminfo[0].strides));
+
+      /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":206
+ *                                  % (ai, max_val))
+ *             bin = b[i0]
+ *             if bin > max_val2:             # <<<<<<<<<<<<<<
+ *                 raise ValueError("value %i is greater than max_val2 (%i)" %
+ *                                  (bin, max_val2))
+ */
+      __pyx_t_3 = (__pyx_v_bin > __pyx_v_max_val2);
+      if (__pyx_t_3) {
+
+        /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":208
+ *             if bin > max_val2:
+ *                 raise ValueError("value %i is greater than max_val2 (%i)" %
+ *                                  (bin, max_val2))             # <<<<<<<<<<<<<<
+ *             y[ai, bin] += w[i0]
+ *     return y, nans
+ */
+        __pyx_t_5 = PyInt_FromLong(__pyx_v_bin); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_5);
+        __pyx_t_13 = PyInt_FromLong(__pyx_v_max_val2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_13);
+        __pyx_t_14 = PyTuple_New(2); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_14);
+        PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_5);
+        __Pyx_GIVEREF(__pyx_t_5);
+        PyTuple_SET_ITEM(__pyx_t_14, 1, __pyx_t_13);
+        __Pyx_GIVEREF(__pyx_t_13);
+        __pyx_t_5 = 0;
+        __pyx_t_13 = 0;
+        __pyx_t_13 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_111), ((PyObject *)__pyx_t_14)); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(((PyObject *)__pyx_t_13));
+        __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
+        __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_14);
+        PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_t_13));
+        __Pyx_GIVEREF(((PyObject *)__pyx_t_13));
+        __pyx_t_13 = 0;
+        __pyx_t_13 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_14), NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_13);
+        __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
+        __Pyx_Raise(__pyx_t_13, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
         {__pyx_filename = __pyx_f[22]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         goto __pyx_L15;
       }
  *     return y, nans
  * 
  */
-      __pyx_t_5 = PyInt_FromLong(__pyx_v_ai); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_13 = PyInt_FromLong(__pyx_v_bin); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      __pyx_t_14 = PyTuple_New(2); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_14);
-      PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_5);
-      __Pyx_GIVEREF(__pyx_t_5);
-      PyTuple_SET_ITEM(__pyx_t_14, 1, __pyx_t_13);
-      __Pyx_GIVEREF(__pyx_t_13);
-      __pyx_t_5 = 0;
-      __pyx_t_13 = 0;
-      __pyx_t_13 = PyObject_GetItem(((PyObject *)__pyx_v_y), ((PyObject *)__pyx_t_14)); if (!__pyx_t_13) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_13);
-      __pyx_t_18 = __pyx_v_i0;
-      __pyx_t_5 = PyFloat_FromDouble((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float_t *, __pyx_pybuffernd_w.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_w.diminfo[0].strides))); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_19 = PyNumber_InPlaceAdd(__pyx_t_13, __pyx_t_5); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_19);
-      __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      if (PyObject_SetItem(((PyObject *)__pyx_v_y), ((PyObject *)__pyx_t_14), __pyx_t_19) < 0) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
-      __Pyx_DECREF(((PyObject *)__pyx_t_14)); __pyx_t_14 = 0;
+      __pyx_t_20 = __pyx_v_i0;
+      __pyx_t_21 = __pyx_v_ai;
+      __pyx_t_22 = __pyx_v_bin;
+      *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_y.rcbuffer->pybuffer.buf, __pyx_t_21, __pyx_pybuffernd_y.diminfo[0].strides, __pyx_t_22, __pyx_pybuffernd_y.diminfo[1].strides) += (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float_t *, __pyx_pybuffernd_w.rcbuffer->pybuffer.buf, __pyx_t_20, __pyx_pybuffernd_w.diminfo[0].strides));
     }
   }
   __pyx_L5:;
  * @cython.boundscheck(False)
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_14 = PyTuple_New(2); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_14);
+  __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_13);
   __Pyx_INCREF(((PyObject *)__pyx_v_y));
-  PyTuple_SET_ITEM(__pyx_t_14, 0, ((PyObject *)__pyx_v_y));
+  PyTuple_SET_ITEM(__pyx_t_13, 0, ((PyObject *)__pyx_v_y));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_y));
   __Pyx_INCREF(((PyObject *)__pyx_v_nans));
-  PyTuple_SET_ITEM(__pyx_t_14, 1, ((PyObject *)__pyx_v_nans));
+  PyTuple_SET_ITEM(__pyx_t_13, 1, ((PyObject *)__pyx_v_nans));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_nans));
-  __pyx_r = ((PyObject *)__pyx_t_14);
-  __pyx_t_14 = 0;
+  __pyx_r = ((PyObject *)__pyx_t_13);
+  __pyx_t_13 = 0;
   goto __pyx_L0;
 
   __pyx_r = Py_None; __Pyx_INCREF(Py_None);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_13);
   __Pyx_XDECREF(__pyx_t_14);
-  __Pyx_XDECREF(__pyx_t_19);
   { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
     __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
     __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_a.rcbuffer->pybuffer);
   int __pyx_t_3;
   int __pyx_t_4;
   PyObject *__pyx_t_5 = NULL;
-  npy_intp __pyx_t_6[1];
+  npy_intp __pyx_t_6[2];
   PyArrayObject *__pyx_t_7 = NULL;
   npy_intp __pyx_t_8[1];
   PyArrayObject *__pyx_t_9 = NULL;
   PyObject *__pyx_t_13 = NULL;
   PyObject *__pyx_t_14 = NULL;
   Py_ssize_t __pyx_t_15;
-  Py_ssize_t __pyx_t_16;
-  Py_ssize_t __pyx_t_17;
+  int __pyx_t_16;
+  char __pyx_t_17;
   Py_ssize_t __pyx_t_18;
-  PyObject *__pyx_t_19 = NULL;
+  Py_ssize_t __pyx_t_19;
+  Py_ssize_t __pyx_t_20;
+  int __pyx_t_21;
+  char __pyx_t_22;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
   /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":229
  * 
  *     cdef:
- *         np.npy_intp *dims = [max_val+1]             # <<<<<<<<<<<<<<
- *         np.ndarray[np.float64_t, ndim=1] y = PyArray_ZEROS(1, dims, NPY_float64, 0)
- *         np.npy_intp *nandims = [max_val2+1]
+ *         np.npy_intp *dims = [max_val + 1, max_val2 + 1]             # <<<<<<<<<<<<<<
+ *         np.ndarray[np.float64_t, ndim=2] y = PyArray_ZEROS(2, dims, NPY_float64, 0)
+ *         np.npy_intp *nandims = [max_val2 + 1]
  */
   __pyx_t_6[0] = (__pyx_v_max_val + 1);
+  __pyx_t_6[1] = (__pyx_v_max_val2 + 1);
   __pyx_v_dims = __pyx_t_6;
 
   /* "/Users/janezdemsar/bottleneck/bottleneck/src/func/64bit/contingency.pyx":230
  *     cdef:
- *         np.npy_intp *dims = [max_val+1]
- *         np.ndarray[np.float64_t, ndim=1] y = PyArray_ZEROS(1, dims, NPY_float64, 0)             # <<<<<<<<<<<<<<
- *         np.npy_intp *nandims = [max_val2+1]
+ *         np.npy_intp *dims = [max_val + 1, max_val2 + 1]
+ *         np.ndarray[np.float64_t, ndim=2] y = PyArray_ZEROS(2, dims, NPY_float64, 0)             # <<<<<<<<<<<<<<
+ *         np.npy_intp *nandims = [max_val2 + 1]
  *         np.ndarray[np.float_t, ndim=1] nans = PyArray_ZEROS(1, nandims, NPY_float64, 0)
  */
-  __pyx_t_5 = PyArray_ZEROS(1, __pyx_v_dims, NPY_FLOAT64, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyArray_ZEROS(2, __pyx_v_dims, NPY_FLOAT64, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
   if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[22]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_t_7 = ((PyArrayObject *)__pyx_t_5);
   {
     __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {
+    i