Generated by Cython 3.0.10
Yellow lines hint at Python interaction.
Click on a line that starts with a "+
" to see the C code that Cython generated for it.
Raw output: ecc_sigmoid.c
+001: cimport cython
__pyx_t_4 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_4) < 0) __PYX_ERR(0, 1, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
002: from libc.stdlib cimport malloc, free
003: from libc.math cimport ceil, exp
+004: import gudhi as gd
__pyx_t_7 = __Pyx_ImportDottedModule(__pyx_n_s_gudhi, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); if (PyDict_SetItem(__pyx_d, __pyx_n_s_gd, __pyx_t_7) < 0) __PYX_ERR(0, 4, __pyx_L1_error) __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+005: import numpy as np
__pyx_t_7 = __Pyx_ImportDottedModule(__pyx_n_s_numpy, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 5, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_7) < 0) __PYX_ERR(0, 5, __pyx_L1_error) __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
006: cimport numpy as cnp
+007: cnp.import_array()
__pyx_t_9 = __pyx_f_5numpy_import_array(); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(0, 7, __pyx_L1_error)
008:
009:
+010: dtype_float = np.float32
__Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_np); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 10, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_float32); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 10, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; if (PyDict_SetItem(__pyx_d, __pyx_n_s_dtype_float, __pyx_t_4) < 0) __PYX_ERR(0, 10, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
011:
012:
013: @cython.cdivision(True) # turn off checking for division by zero
+014: cdef inline float sigmoid(float x, float lam) except -1:
static CYTHON_INLINE float __pyx_f_11ecc_sigmoid_sigmoid(float __pyx_v_x, float __pyx_v_lam) { float __pyx_r; /* … */ /* function exit code */ __pyx_L0:; return __pyx_r; }
+015: return 1 / (1 + exp(-lam * x))
__pyx_r = (1.0 / (1.0 + exp(((-__pyx_v_lam) * __pyx_v_x)))); goto __pyx_L0;
016:
+017: cdef class SigEccBackbone:
struct __pyx_obj_11ecc_sigmoid_SigEccBackbone { PyObject_HEAD struct __pyx_vtabstruct_11ecc_sigmoid_SigEccBackbone *__pyx_vtab; Py_ssize_t w; Py_ssize_t grid_h; Py_ssize_t grid_w; Py_ssize_t num_cells; Py_ssize_t steps; float t_min; float t_max; float resolution; float lower_bound; float lam; __Pyx_memviewslice tseq; __Pyx_memviewslice dimension; }; /* … */ struct __pyx_vtabstruct_11ecc_sigmoid_SigEccBackbone { Py_ssize_t (*_sq2pix)(struct __pyx_obj_11ecc_sigmoid_SigEccBackbone *, Py_ssize_t); Py_ssize_t *(*_find_neighbor_sq)(struct __pyx_obj_11ecc_sigmoid_SigEccBackbone *, Py_ssize_t, float, Py_ssize_t *); Py_ssize_t *(*_find_min_sq)(struct __pyx_obj_11ecc_sigmoid_SigEccBackbone *, float *, Py_ssize_t *, Py_ssize_t, Py_ssize_t *); PyObject *(*_set_dimension)(struct __pyx_obj_11ecc_sigmoid_SigEccBackbone *); }; static struct __pyx_vtabstruct_11ecc_sigmoid_SigEccBackbone *__pyx_vtabptr_11ecc_sigmoid_SigEccBackbone; static CYTHON_INLINE Py_ssize_t __pyx_f_11ecc_sigmoid_14SigEccBackbone__sq2pix(struct __pyx_obj_11ecc_sigmoid_SigEccBackbone *, Py_ssize_t); static CYTHON_INLINE Py_ssize_t *__pyx_f_11ecc_sigmoid_14SigEccBackbone__find_neighbor_sq(struct __pyx_obj_11ecc_sigmoid_SigEccBackbone *, Py_ssize_t, float, Py_ssize_t *); static CYTHON_INLINE Py_ssize_t *__pyx_f_11ecc_sigmoid_14SigEccBackbone__find_min_sq(struct __pyx_obj_11ecc_sigmoid_SigEccBackbone *, float *, Py_ssize_t *, Py_ssize_t, Py_ssize_t *);
018: cdef Py_ssize_t w, grid_h, grid_w, num_cells, steps
019: cdef float t_min, t_max, resolution, lower_bound, lam
020: cdef float[:] tseq
021: cdef const float[:] dimension
022:
+023: def __init__(self, t_const=True, size=[28, 28], interval=[0.02, 0.28], steps=32, lam=200.):
/* Python wrapper */ static int __pyx_pw_11ecc_sigmoid_14SigEccBackbone_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ PyDoc_STRVAR(__pyx_doc_11ecc_sigmoid_14SigEccBackbone___init__, "\n Args:\n t_const (bool, optional): Use T-construction. If False, V-construction will be used. Defaults to True.\n size (list, optional): [Height, Width] of image. Defaults to [28, 28].\n interval (list, optional): Minimum and maximum value of interval to consider. Defaults to [0.02, 0.28].\n steps (int, optional): Number of discretized points. Defaults to 32.\n lamda (float, optional): Controls the tightness of sigmoid approximation. Defaults to 200.\n "); #if CYTHON_UPDATE_DESCRIPTOR_DOC struct wrapperbase __pyx_wrapperbase_11ecc_sigmoid_14SigEccBackbone___init__; #endif static int __pyx_pw_11ecc_sigmoid_14SigEccBackbone_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_t_const = 0; PyObject *__pyx_v_size = 0; PyObject *__pyx_v_interval = 0; PyObject *__pyx_v_steps = 0; PyObject *__pyx_v_lam = 0; CYTHON_UNUSED Py_ssize_t __pyx_nargs; CYTHON_UNUSED PyObject *const *__pyx_kwvalues; int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); #if CYTHON_ASSUME_SAFE_MACROS __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); #else __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return -1; #endif __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); { PyObject **__pyx_pyargnames[] = {&__pyx_n_s_t_const,&__pyx_n_s_size,&__pyx_n_s_interval,&__pyx_n_s_steps,&__pyx_n_s_lam,0}; PyObject* values[5] = {0,0,0,0,0}; values[0] = __Pyx_Arg_NewRef_VARARGS(((PyObject *)Py_True)); values[1] = __Pyx_Arg_NewRef_VARARGS(__pyx_k__11); values[2] = __Pyx_Arg_NewRef_VARARGS(__pyx_k__12); values[3] = __Pyx_Arg_NewRef_VARARGS(((PyObject *)__pyx_int_32)); values[4] = __Pyx_Arg_NewRef_VARARGS(((PyObject *)__pyx_float_200_)); if (__pyx_kwds) { Py_ssize_t kw_args; switch (__pyx_nargs) { case 5: values[4] = __Pyx_Arg_VARARGS(__pyx_args, 4); CYTHON_FALLTHROUGH; case 4: values[3] = __Pyx_Arg_VARARGS(__pyx_args, 3); CYTHON_FALLTHROUGH; case 3: values[2] = __Pyx_Arg_VARARGS(__pyx_args, 2); CYTHON_FALLTHROUGH; case 2: values[1] = __Pyx_Arg_VARARGS(__pyx_args, 1); CYTHON_FALLTHROUGH; case 1: values[0] = __Pyx_Arg_VARARGS(__pyx_args, 0); CYTHON_FALLTHROUGH; case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = __Pyx_NumKwargs_VARARGS(__pyx_kwds); switch (__pyx_nargs) { case 0: if (kw_args > 0) { PyObject* value = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_t_const); if (value) { values[0] = __Pyx_Arg_NewRef_VARARGS(value); kw_args--; } else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 23, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 1: if (kw_args > 0) { PyObject* value = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_size); if (value) { values[1] = __Pyx_Arg_NewRef_VARARGS(value); kw_args--; } else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 23, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 2: if (kw_args > 0) { PyObject* value = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_interval); if (value) { values[2] = __Pyx_Arg_NewRef_VARARGS(value); kw_args--; } else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 23, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 3: if (kw_args > 0) { PyObject* value = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_steps); if (value) { values[3] = __Pyx_Arg_NewRef_VARARGS(value); kw_args--; } else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 23, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 4: if (kw_args > 0) { PyObject* value = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_lam); if (value) { values[4] = __Pyx_Arg_NewRef_VARARGS(value); kw_args--; } else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 23, __pyx_L3_error) } } if (unlikely(kw_args > 0)) { const Py_ssize_t kwd_pos_args = __pyx_nargs; if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "__init__") < 0)) __PYX_ERR(0, 23, __pyx_L3_error) } } else { switch (__pyx_nargs) { case 5: values[4] = __Pyx_Arg_VARARGS(__pyx_args, 4); CYTHON_FALLTHROUGH; case 4: values[3] = __Pyx_Arg_VARARGS(__pyx_args, 3); CYTHON_FALLTHROUGH; case 3: values[2] = __Pyx_Arg_VARARGS(__pyx_args, 2); CYTHON_FALLTHROUGH; case 2: values[1] = __Pyx_Arg_VARARGS(__pyx_args, 1); CYTHON_FALLTHROUGH; case 1: values[0] = __Pyx_Arg_VARARGS(__pyx_args, 0); CYTHON_FALLTHROUGH; case 0: break; default: goto __pyx_L5_argtuple_error; } } __pyx_v_t_const = values[0]; __pyx_v_size = values[1]; __pyx_v_interval = values[2]; __pyx_v_steps = values[3]; __pyx_v_lam = values[4]; } goto __pyx_L6_skip; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 5, __pyx_nargs); __PYX_ERR(0, 23, __pyx_L3_error) __pyx_L6_skip:; goto __pyx_L4_argument_unpacking_done; __pyx_L3_error:; { Py_ssize_t __pyx_temp; for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { __Pyx_Arg_XDECREF_VARARGS(values[__pyx_temp]); } } __Pyx_AddTraceback("ecc_sigmoid.SigEccBackbone.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return -1; __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_pf_11ecc_sigmoid_14SigEccBackbone___init__(((struct __pyx_obj_11ecc_sigmoid_SigEccBackbone *)__pyx_v_self), __pyx_v_t_const, __pyx_v_size, __pyx_v_interval, __pyx_v_steps, __pyx_v_lam); /* function exit code */ { Py_ssize_t __pyx_temp; for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { __Pyx_Arg_XDECREF_VARARGS(values[__pyx_temp]); } } __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_pf_11ecc_sigmoid_14SigEccBackbone___init__(struct __pyx_obj_11ecc_sigmoid_SigEccBackbone *__pyx_v_self, PyObject *__pyx_v_t_const, PyObject *__pyx_v_size, PyObject *__pyx_v_interval, PyObject *__pyx_v_steps, PyObject *__pyx_v_lam) { PyObject *__pyx_7genexpr__pyx_v_i = NULL; int __pyx_r; /* … */ /* function exit code */ __pyx_r = 0; goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_5); __Pyx_XDECREF(__pyx_t_8); __Pyx_XDECREF(__pyx_t_9); __PYX_XCLEAR_MEMVIEW(&__pyx_t_11, 1); __PYX_XCLEAR_MEMVIEW(&__pyx_t_15, 1); __Pyx_AddTraceback("ecc_sigmoid.SigEccBackbone.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __pyx_L0:; __Pyx_XDECREF(__pyx_7genexpr__pyx_v_i); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* … */ __pyx_t_4 = PyList_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 23, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_INCREF(__pyx_int_28); __Pyx_GIVEREF(__pyx_int_28); if (__Pyx_PyList_SET_ITEM(__pyx_t_4, 0, __pyx_int_28)) __PYX_ERR(0, 23, __pyx_L1_error); __Pyx_INCREF(__pyx_int_28); __Pyx_GIVEREF(__pyx_int_28); if (__Pyx_PyList_SET_ITEM(__pyx_t_4, 1, __pyx_int_28)) __PYX_ERR(0, 23, __pyx_L1_error); __pyx_k__11 = __pyx_t_4; __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_4 = PyList_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 23, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_INCREF(__pyx_float_0_02); __Pyx_GIVEREF(__pyx_float_0_02); if (__Pyx_PyList_SET_ITEM(__pyx_t_4, 0, __pyx_float_0_02)) __PYX_ERR(0, 23, __pyx_L1_error); __Pyx_INCREF(__pyx_float_0_28); __Pyx_GIVEREF(__pyx_float_0_28); if (__Pyx_PyList_SET_ITEM(__pyx_t_4, 1, __pyx_float_0_28)) __PYX_ERR(0, 23, __pyx_L1_error); __pyx_k__12 = __pyx_t_4; __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = 0;
024: """
025: Args:
026: t_const (bool, optional): Use T-construction. If False, V-construction will be used. Defaults to True.
027: size (list, optional): [Height, Width] of image. Defaults to [28, 28].
028: interval (list, optional): Minimum and maximum value of interval to consider. Defaults to [0.02, 0.28].
029: steps (int, optional): Number of discretized points. Defaults to 32.
030: lamda (float, optional): Controls the tightness of sigmoid approximation. Defaults to 200.
031: """
+032: assert size[0] > 1 and size[1] > 1, "Size of image should be larger than [1, 1]"
#ifndef CYTHON_WITHOUT_ASSERTIONS if (unlikely(__pyx_assertions_enabled())) { __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_size, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 32, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = PyObject_RichCompare(__pyx_t_2, __pyx_int_1, Py_GT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 32, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 32, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; if (__pyx_t_4) { } else { __pyx_t_1 = __pyx_t_4; goto __pyx_L3_bool_binop_done; } __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_size, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 32, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_2 = PyObject_RichCompare(__pyx_t_3, __pyx_int_1, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 32, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 32, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_t_1 = __pyx_t_4; __pyx_L3_bool_binop_done:; if (unlikely(!__pyx_t_1)) { __Pyx_Raise(__pyx_builtin_AssertionError, __pyx_kp_s_Size_of_image_should_be_larger_t, 0, 0); __PYX_ERR(0, 32, __pyx_L1_error) } } #else if ((1)); else __PYX_ERR(0, 32, __pyx_L1_error) #endif
+033: assert interval[1] > interval[0], "End point of interval must be larger than starting point of interval"
#ifndef CYTHON_WITHOUT_ASSERTIONS if (unlikely(__pyx_assertions_enabled())) { __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_interval, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 33, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_interval, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 33, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_5 = PyObject_RichCompare(__pyx_t_2, __pyx_t_3, Py_GT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 33, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 33, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; if (unlikely(!__pyx_t_1)) { __Pyx_Raise(__pyx_builtin_AssertionError, __pyx_kp_s_End_point_of_interval_must_be_la, 0, 0); __PYX_ERR(0, 33, __pyx_L1_error) } } #else if ((1)); else __PYX_ERR(0, 33, __pyx_L1_error) #endif
+034: assert steps > 1, "Number of steps should be larger than 1"
#ifndef CYTHON_WITHOUT_ASSERTIONS if (unlikely(__pyx_assertions_enabled())) { __pyx_t_5 = PyObject_RichCompare(__pyx_v_steps, __pyx_int_1, Py_GT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 34, __pyx_L1_error) __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 34, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; if (unlikely(!__pyx_t_1)) { __Pyx_Raise(__pyx_builtin_AssertionError, __pyx_kp_s_Number_of_steps_should_be_larger, 0, 0); __PYX_ERR(0, 34, __pyx_L1_error) } } #else if ((1)); else __PYX_ERR(0, 34, __pyx_L1_error) #endif
+035: self.w = size[1]
__pyx_t_5 = __Pyx_GetItemInt(__pyx_v_size, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 35, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_t_5); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 35, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __pyx_v_self->w = __pyx_t_6;
+036: self.grid_h, self.grid_w = [2*i + 1 if t_const else 2*i - 1 for i in size] # size of the cubical complex
{ /* enter inner scope */ __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 36, __pyx_L7_error) __Pyx_GOTREF(__pyx_t_5); if (likely(PyList_CheckExact(__pyx_v_size)) || PyTuple_CheckExact(__pyx_v_size)) { __pyx_t_3 = __pyx_v_size; __Pyx_INCREF(__pyx_t_3); __pyx_t_6 = 0; __pyx_t_7 = NULL; } else { __pyx_t_6 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_size); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 36, __pyx_L7_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_7 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 36, __pyx_L7_error) } for (;;) { if (likely(!__pyx_t_7)) { if (likely(PyList_CheckExact(__pyx_t_3))) { { Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_3); #if !CYTHON_ASSUME_SAFE_MACROS if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 36, __pyx_L7_error) #endif if (__pyx_t_6 >= __pyx_temp) break; } #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS __pyx_t_2 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_6); __Pyx_INCREF(__pyx_t_2); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(0, 36, __pyx_L7_error) #else __pyx_t_2 = __Pyx_PySequence_ITEM(__pyx_t_3, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 36, __pyx_L7_error) __Pyx_GOTREF(__pyx_t_2); #endif } else { { Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_3); #if !CYTHON_ASSUME_SAFE_MACROS if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 36, __pyx_L7_error) #endif if (__pyx_t_6 >= __pyx_temp) break; } #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_6); __Pyx_INCREF(__pyx_t_2); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(0, 36, __pyx_L7_error) #else __pyx_t_2 = __Pyx_PySequence_ITEM(__pyx_t_3, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 36, __pyx_L7_error) __Pyx_GOTREF(__pyx_t_2); #endif } } else { __pyx_t_2 = __pyx_t_7(__pyx_t_3); if (unlikely(!__pyx_t_2)) { PyObject* exc_type = PyErr_Occurred(); if (exc_type) { if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); else __PYX_ERR(0, 36, __pyx_L7_error) } break; } __Pyx_GOTREF(__pyx_t_2); } __Pyx_XDECREF_SET(__pyx_7genexpr__pyx_v_i, __pyx_t_2); __pyx_t_2 = 0; __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_t_const); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 36, __pyx_L7_error) if (__pyx_t_1) { __pyx_t_8 = __Pyx_PyInt_MultiplyCObj(__pyx_int_2, __pyx_7genexpr__pyx_v_i, 2, 0, 0); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 36, __pyx_L7_error) __Pyx_GOTREF(__pyx_t_8); __pyx_t_9 = __Pyx_PyInt_AddObjC(__pyx_t_8, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 36, __pyx_L7_error) __Pyx_GOTREF(__pyx_t_9); __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; __pyx_t_2 = __pyx_t_9; __pyx_t_9 = 0; } else { __pyx_t_9 = __Pyx_PyInt_MultiplyCObj(__pyx_int_2, __pyx_7genexpr__pyx_v_i, 2, 0, 0); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 36, __pyx_L7_error) __Pyx_GOTREF(__pyx_t_9); __pyx_t_8 = __Pyx_PyInt_SubtractObjC(__pyx_t_9, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 36, __pyx_L7_error) __Pyx_GOTREF(__pyx_t_8); __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; __pyx_t_2 = __pyx_t_8; __pyx_t_8 = 0; } if (unlikely(__Pyx_ListComp_Append(__pyx_t_5, (PyObject*)__pyx_t_2))) __PYX_ERR(0, 36, __pyx_L7_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; } __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_XDECREF(__pyx_7genexpr__pyx_v_i); __pyx_7genexpr__pyx_v_i = 0; goto __pyx_L11_exit_scope; __pyx_L7_error:; __Pyx_XDECREF(__pyx_7genexpr__pyx_v_i); __pyx_7genexpr__pyx_v_i = 0; goto __pyx_L1_error; __pyx_L11_exit_scope:; } /* exit inner scope */ if (1) { PyObject* sequence = __pyx_t_5; Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); if (unlikely(size != 2)) { if (size > 2) __Pyx_RaiseTooManyValuesError(2); else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); __PYX_ERR(0, 36, __pyx_L1_error) } #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS __pyx_t_3 = PyList_GET_ITEM(sequence, 0); __pyx_t_2 = PyList_GET_ITEM(sequence, 1); __Pyx_INCREF(__pyx_t_3); __Pyx_INCREF(__pyx_t_2); #else __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 36, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 36, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); #endif __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; } __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_t_3); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 36, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_2); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 36, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_v_self->grid_h = __pyx_t_6; __pyx_v_self->grid_w = __pyx_t_10;
+037: self.num_cells = self.grid_h * self.grid_w
__pyx_v_self->num_cells = (__pyx_v_self->grid_h * __pyx_v_self->grid_w);
+038: self.dimension = self._set_dimension()
__pyx_t_5 = ((struct __pyx_vtabstruct_11ecc_sigmoid_SigEccBackbone *)__pyx_v_self->__pyx_vtab)->_set_dimension(__pyx_v_self); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 38, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_t_11 = __Pyx_PyObject_to_MemoryviewSlice_ds_float__const__(__pyx_t_5, 0); if (unlikely(!__pyx_t_11.memview)) __PYX_ERR(0, 38, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __PYX_XCLEAR_MEMVIEW(&__pyx_v_self->dimension, 0); __pyx_v_self->dimension = __pyx_t_11; __pyx_t_11.memview = NULL; __pyx_t_11.data = NULL;
+039: self.t_min, self.t_max = interval
if ((likely(PyTuple_CheckExact(__pyx_v_interval))) || (PyList_CheckExact(__pyx_v_interval))) { PyObject* sequence = __pyx_v_interval; Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); if (unlikely(size != 2)) { if (size > 2) __Pyx_RaiseTooManyValuesError(2); else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); __PYX_ERR(0, 39, __pyx_L1_error) } #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS if (likely(PyTuple_CheckExact(sequence))) { __pyx_t_5 = PyTuple_GET_ITEM(sequence, 0); __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); } else { __pyx_t_5 = PyList_GET_ITEM(sequence, 0); __pyx_t_2 = PyList_GET_ITEM(sequence, 1); } __Pyx_INCREF(__pyx_t_5); __Pyx_INCREF(__pyx_t_2); #else __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 39, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 39, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); #endif } else { Py_ssize_t index = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_interval); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 39, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_12 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); index = 0; __pyx_t_5 = __pyx_t_12(__pyx_t_3); if (unlikely(!__pyx_t_5)) goto __pyx_L12_unpacking_failed; __Pyx_GOTREF(__pyx_t_5); index = 1; __pyx_t_2 = __pyx_t_12(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L12_unpacking_failed; __Pyx_GOTREF(__pyx_t_2); if (__Pyx_IternextUnpackEndCheck(__pyx_t_12(__pyx_t_3), 2) < 0) __PYX_ERR(0, 39, __pyx_L1_error) __pyx_t_12 = NULL; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; goto __pyx_L13_unpacking_done; __pyx_L12_unpacking_failed:; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_12 = NULL; if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); __PYX_ERR(0, 39, __pyx_L1_error) __pyx_L13_unpacking_done:; } __pyx_t_13 = __pyx_PyFloat_AsFloat(__pyx_t_5); if (unlikely((__pyx_t_13 == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 39, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __pyx_t_14 = __pyx_PyFloat_AsFloat(__pyx_t_2); if (unlikely((__pyx_t_14 == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 39, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_v_self->t_min = __pyx_t_13; __pyx_v_self->t_max = __pyx_t_14;
+040: self.steps = steps
__pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_v_steps); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 40, __pyx_L1_error) __pyx_v_self->steps = __pyx_t_10;
+041: self.resolution = (self.t_max - self.t_min) / (self.steps - 1)
__pyx_t_14 = (__pyx_v_self->t_max - __pyx_v_self->t_min); __pyx_t_10 = (__pyx_v_self->steps - 1); if (unlikely(__pyx_t_10 == 0)) { PyErr_SetString(PyExc_ZeroDivisionError, "float division"); __PYX_ERR(0, 41, __pyx_L1_error) } __pyx_v_self->resolution = (__pyx_t_14 / ((float)__pyx_t_10));
+042: self.lower_bound = self.t_min - self.resolution # lower bound for skipping gradient calculation in backpropagation step
__pyx_v_self->lower_bound = (__pyx_v_self->t_min - __pyx_v_self->resolution);
+043: self.lam = lam
__pyx_t_14 = __pyx_PyFloat_AsFloat(__pyx_v_lam); if (unlikely((__pyx_t_14 == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 43, __pyx_L1_error) __pyx_v_self->lam = __pyx_t_14;
+044: self.tseq = np.linspace(*interval, steps, dtype=dtype_float)
__Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 44, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_linspace); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 44, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_t_2 = __Pyx_PySequence_Tuple(__pyx_v_interval); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 44, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 44, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_INCREF(__pyx_v_steps); __Pyx_GIVEREF(__pyx_v_steps); if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_steps)) __PYX_ERR(0, 44, __pyx_L1_error); __pyx_t_8 = PyNumber_Add(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 44, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_8); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 44, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_dtype_float); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 44, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_2) < 0) __PYX_ERR(0, 44, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 44, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_15 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_t_2, PyBUF_WRITABLE); if (unlikely(!__pyx_t_15.memview)) __PYX_ERR(0, 44, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __PYX_XCLEAR_MEMVIEW(&__pyx_v_self->tseq, 0); __pyx_v_self->tseq = __pyx_t_15; __pyx_t_15.memview = NULL; __pyx_t_15.data = NULL;
045:
046:
047: # T-construction
+048: @cython.boundscheck(False) # turn off bounds-checking for entire function
/* Python wrapper */ static PyObject *__pyx_pw_11ecc_sigmoid_14SigEccBackbone_3cal_ecc_topdim(PyObject *__pyx_v_self, #if CYTHON_METH_FASTCALL PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds #else PyObject *__pyx_args, PyObject *__pyx_kwds #endif ); /*proto*/ PyDoc_STRVAR(__pyx_doc_11ecc_sigmoid_14SigEccBackbone_2cal_ecc_topdim, "_summary_\n\n Args:\n x (anything convertible to a numpy.ndarray): Array of shape [B, C, H, W].\n backprop (bint): Whether or not the input requires gradient calculation\n\n Returns:\n _type_: _description_\n "); static PyMethodDef __pyx_mdef_11ecc_sigmoid_14SigEccBackbone_3cal_ecc_topdim = {"cal_ecc_topdim", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_11ecc_sigmoid_14SigEccBackbone_3cal_ecc_topdim, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_11ecc_sigmoid_14SigEccBackbone_2cal_ecc_topdim}; static PyObject *__pyx_pw_11ecc_sigmoid_14SigEccBackbone_3cal_ecc_topdim(PyObject *__pyx_v_self, #if CYTHON_METH_FASTCALL PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds #else PyObject *__pyx_args, PyObject *__pyx_kwds #endif ) { PyObject *__pyx_v_x = 0; int __pyx_v_backprop; #if !CYTHON_METH_FASTCALL CYTHON_UNUSED Py_ssize_t __pyx_nargs; #endif CYTHON_UNUSED PyObject *const *__pyx_kwvalues; PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("cal_ecc_topdim (wrapper)", 0); #if !CYTHON_METH_FASTCALL #if CYTHON_ASSUME_SAFE_MACROS __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); #else __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; #endif #endif __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); { PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,&__pyx_n_s_backprop,0}; PyObject* values[2] = {0,0}; if (__pyx_kwds) { Py_ssize_t kw_args; switch (__pyx_nargs) { case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); CYTHON_FALLTHROUGH; case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); CYTHON_FALLTHROUGH; case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); switch (__pyx_nargs) { case 0: if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_x)) != 0)) { (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); kw_args--; } else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 48, __pyx_L3_error) else goto __pyx_L5_argtuple_error; CYTHON_FALLTHROUGH; case 1: if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_backprop)) != 0)) { (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); kw_args--; } else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 48, __pyx_L3_error) else { __Pyx_RaiseArgtupleInvalid("cal_ecc_topdim", 1, 2, 2, 1); __PYX_ERR(0, 48, __pyx_L3_error) } } if (unlikely(kw_args > 0)) { const Py_ssize_t kwd_pos_args = __pyx_nargs; if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "cal_ecc_topdim") < 0)) __PYX_ERR(0, 48, __pyx_L3_error) } } else if (unlikely(__pyx_nargs != 2)) { goto __pyx_L5_argtuple_error; } else { values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); } __pyx_v_x = values[0]; __pyx_v_backprop = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_backprop == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 52, __pyx_L3_error) } goto __pyx_L6_skip; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("cal_ecc_topdim", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 48, __pyx_L3_error) __pyx_L6_skip:; goto __pyx_L4_argument_unpacking_done; __pyx_L3_error:; { Py_ssize_t __pyx_temp; for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); } } __Pyx_AddTraceback("ecc_sigmoid.SigEccBackbone.cal_ecc_topdim", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_pf_11ecc_sigmoid_14SigEccBackbone_2cal_ecc_topdim(((struct __pyx_obj_11ecc_sigmoid_SigEccBackbone *)__pyx_v_self), __pyx_v_x, __pyx_v_backprop); int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; /* function exit code */ { Py_ssize_t __pyx_temp; for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); } } __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_11ecc_sigmoid_14SigEccBackbone_2cal_ecc_topdim(struct __pyx_obj_11ecc_sigmoid_SigEccBackbone *__pyx_v_self, PyObject *__pyx_v_x, int __pyx_v_backprop) { Py_ssize_t __pyx_v_batch_size; Py_ssize_t __pyx_v_num_channels; Py_ssize_t __pyx_v_b; Py_ssize_t __pyx_v_c; Py_ssize_t __pyx_v_cell; Py_ssize_t __pyx_v_pix; Py_ssize_t __pyx_v_i; Py_ssize_t __pyx_v_num_neighbors; Py_ssize_t __pyx_v_num_min; float __pyx_v_filt; float __pyx_v_dim; float __pyx_v_t; float __pyx_v_sig; Py_ssize_t *__pyx_v_neighbor_sq; Py_ssize_t *__pyx_v_sq; float __pyx_v_sq_filt[4]; PyObject *__pyx_v_h = NULL; PyObject *__pyx_v_w = NULL; PyObject *__pyx_v_ecc = NULL; __Pyx_memviewslice __pyx_v_ecc_view = { 0, 0, { 0 }, { 0 }, { 0 } }; PyObject *__pyx_v_grad_local = NULL; __Pyx_memviewslice __pyx_v_grad_local_view = { 0, 0, { 0 }, { 0 }, { 0 } }; __Pyx_memviewslice __pyx_v_filtration = { 0, 0, { 0 }, { 0 }, { 0 } }; PyObject *__pyx_v_cub_cpx = NULL; PyObject *__pyx_r = NULL; /* … */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __Pyx_XDECREF(__pyx_t_6); __PYX_XCLEAR_MEMVIEW(&__pyx_t_10, 1); __Pyx_XDECREF(__pyx_t_11); __PYX_XCLEAR_MEMVIEW(&__pyx_t_12, 1); __PYX_XCLEAR_MEMVIEW(&__pyx_t_18, 1); __Pyx_AddTraceback("ecc_sigmoid.SigEccBackbone.cal_ecc_topdim", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF(__pyx_v_h); __Pyx_XDECREF(__pyx_v_w); __Pyx_XDECREF(__pyx_v_ecc); __PYX_XCLEAR_MEMVIEW(&__pyx_v_ecc_view, 1); __Pyx_XDECREF(__pyx_v_grad_local); __PYX_XCLEAR_MEMVIEW(&__pyx_v_grad_local_view, 1); __PYX_XCLEAR_MEMVIEW(&__pyx_v_filtration, 1); __Pyx_XDECREF(__pyx_v_cub_cpx); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* … */ __pyx_tuple__25 = PyTuple_Pack(27, __pyx_n_s_self, __pyx_n_s_x, __pyx_n_s_backprop, __pyx_n_s_batch_size, __pyx_n_s_num_channels, __pyx_n_s_b, __pyx_n_s_c, __pyx_n_s_cell, __pyx_n_s_pix, __pyx_n_s_i, __pyx_n_s_num_neighbors, __pyx_n_s_num_min, __pyx_n_s_filt, __pyx_n_s_dim, __pyx_n_s_t, __pyx_n_s_sig, __pyx_n_s_neighbor_sq, __pyx_n_s_sq, __pyx_n_s_sq_filt, __pyx_n_s_h, __pyx_n_s_w, __pyx_n_s_ecc, __pyx_n_s_ecc_view, __pyx_n_s_grad_local, __pyx_n_s_grad_local_view, __pyx_n_s_filtration, __pyx_n_s_cub_cpx); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(0, 48, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__25); __Pyx_GIVEREF(__pyx_tuple__25); /* … */ __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_11ecc_sigmoid_14SigEccBackbone_3cal_ecc_topdim, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_SigEccBackbone_cal_ecc_topdim, NULL, __pyx_n_s_ecc_sigmoid, __pyx_d, ((PyObject *)__pyx_codeobj__26)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 48, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); if (__Pyx_SetItemOnTypeDict((PyObject *)__pyx_ptype_11ecc_sigmoid_SigEccBackbone, __pyx_n_s_cal_ecc_topdim, __pyx_t_4) < 0) __PYX_ERR(0, 48, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; PyType_Modified(__pyx_ptype_11ecc_sigmoid_SigEccBackbone); __pyx_codeobj__26 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 27, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__25, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_ecc_sigmoid_pyx, __pyx_n_s_cal_ecc_topdim, 48, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__26)) __PYX_ERR(0, 48, __pyx_L1_error)
049: @cython.wraparound(False) # turn off negative index wrapping for entire function
050: @cython.cdivision(True) # turn off checking for division by zero
051: @cython.initializedcheck(False) # turn off initialization check
052: def cal_ecc_topdim(self, object x, bint backprop):
053: """_summary_
054:
055: Args:
056: x (anything convertible to a numpy.ndarray): Array of shape [B, C, H, W].
057: backprop (bint): Whether or not the input requires gradient calculation
058:
059: Returns:
060: _type_: _description_
061: """
062: cdef Py_ssize_t batch_size, num_channels, b, c, cell, pix, i, num_neighbors, num_min
063: cdef float filt, dim, t, sig
064: cdef Py_ssize_t *neighbor_sq
065: cdef Py_ssize_t *sq
066: cdef float[4] sq_filt
067:
+068: batch_size, num_channels, h, w = x.shape
__pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 68, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { PyObject* sequence = __pyx_t_1; Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); if (unlikely(size != 4)) { if (size > 4) __Pyx_RaiseTooManyValuesError(4); else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); __PYX_ERR(0, 68, __pyx_L1_error) } #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS if (likely(PyTuple_CheckExact(sequence))) { __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); __pyx_t_4 = PyTuple_GET_ITEM(sequence, 2); __pyx_t_5 = PyTuple_GET_ITEM(sequence, 3); } else { __pyx_t_2 = PyList_GET_ITEM(sequence, 0); __pyx_t_3 = PyList_GET_ITEM(sequence, 1); __pyx_t_4 = PyList_GET_ITEM(sequence, 2); __pyx_t_5 = PyList_GET_ITEM(sequence, 3); } __Pyx_INCREF(__pyx_t_2); __Pyx_INCREF(__pyx_t_3); __Pyx_INCREF(__pyx_t_4); __Pyx_INCREF(__pyx_t_5); #else { Py_ssize_t i; PyObject** temps[4] = {&__pyx_t_2,&__pyx_t_3,&__pyx_t_4,&__pyx_t_5}; for (i=0; i < 4; i++) { PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) __PYX_ERR(0, 68, __pyx_L1_error) __Pyx_GOTREF(item); *(temps[i]) = item; } } #endif __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; } else { Py_ssize_t index = -1; PyObject** temps[4] = {&__pyx_t_2,&__pyx_t_3,&__pyx_t_4,&__pyx_t_5}; __pyx_t_6 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 68, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_7 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_6); for (index=0; index < 4; index++) { PyObject* item = __pyx_t_7(__pyx_t_6); if (unlikely(!item)) goto __pyx_L3_unpacking_failed; __Pyx_GOTREF(item); *(temps[index]) = item; } if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_6), 4) < 0) __PYX_ERR(0, 68, __pyx_L1_error) __pyx_t_7 = NULL; __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; goto __pyx_L4_unpacking_done; __pyx_L3_unpacking_failed:; __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; __pyx_t_7 = NULL; if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); __PYX_ERR(0, 68, __pyx_L1_error) __pyx_L4_unpacking_done:; } __pyx_t_8 = __Pyx_PyIndex_AsSsize_t(__pyx_t_2); if (unlikely((__pyx_t_8 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 68, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_t_9 = __Pyx_PyIndex_AsSsize_t(__pyx_t_3); if (unlikely((__pyx_t_9 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 68, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_v_batch_size = __pyx_t_8; __pyx_v_num_channels = __pyx_t_9; __pyx_v_h = __pyx_t_4; __pyx_t_4 = 0; __pyx_v_w = __pyx_t_5; __pyx_t_5 = 0;
069:
+070: ecc = np.zeros((batch_size, num_channels, self.steps), dtype=dtype_float)
__Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 70, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_zeros); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 70, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_batch_size); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 70, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_num_channels); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 70, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_self->steps); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 70, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 70, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_GIVEREF(__pyx_t_1); if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1)) __PYX_ERR(0, 70, __pyx_L1_error); __Pyx_GIVEREF(__pyx_t_4); if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4)) __PYX_ERR(0, 70, __pyx_L1_error); __Pyx_GIVEREF(__pyx_t_3); if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_3)) __PYX_ERR(0, 70, __pyx_L1_error); __pyx_t_1 = 0; __pyx_t_4 = 0; __pyx_t_3 = 0; __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 70, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_GIVEREF(__pyx_t_2); if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2)) __PYX_ERR(0, 70, __pyx_L1_error); __pyx_t_2 = 0; __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 70, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_dtype_float); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 70, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_4) < 0) __PYX_ERR(0, 70, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 70, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_v_ecc = __pyx_t_4; __pyx_t_4 = 0;
+071: cdef float[:, :, :] ecc_view = ecc
__pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dsdsds_float(__pyx_v_ecc, PyBUF_WRITABLE); if (unlikely(!__pyx_t_10.memview)) __PYX_ERR(0, 71, __pyx_L1_error) __pyx_v_ecc_view = __pyx_t_10; __pyx_t_10.memview = NULL; __pyx_t_10.data = NULL;
072:
+073: grad_local = np.zeros((batch_size, num_channels, h*w, self.steps), dtype=dtype_float) if backprop else None
if (__pyx_v_backprop) { __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 73, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_zeros); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 73, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_batch_size); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 73, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_5 = PyInt_FromSsize_t(__pyx_v_num_channels); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 73, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_t_1 = PyNumber_Multiply(__pyx_v_h, __pyx_v_w); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 73, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_6 = PyInt_FromSsize_t(__pyx_v_self->steps); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 73, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __pyx_t_11 = PyTuple_New(4); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 73, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_11); __Pyx_GIVEREF(__pyx_t_2); if (__Pyx_PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_2)) __PYX_ERR(0, 73, __pyx_L1_error); __Pyx_GIVEREF(__pyx_t_5); if (__Pyx_PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_t_5)) __PYX_ERR(0, 73, __pyx_L1_error); __Pyx_GIVEREF(__pyx_t_1); if (__Pyx_PyTuple_SET_ITEM(__pyx_t_11, 2, __pyx_t_1)) __PYX_ERR(0, 73, __pyx_L1_error); __Pyx_GIVEREF(__pyx_t_6); if (__Pyx_PyTuple_SET_ITEM(__pyx_t_11, 3, __pyx_t_6)) __PYX_ERR(0, 73, __pyx_L1_error); __pyx_t_2 = 0; __pyx_t_5 = 0; __pyx_t_1 = 0; __pyx_t_6 = 0; __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 73, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_GIVEREF(__pyx_t_11); if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_11)) __PYX_ERR(0, 73, __pyx_L1_error); __pyx_t_11 = 0; __pyx_t_11 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 73, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_11); __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_dtype_float); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 73, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); if (PyDict_SetItem(__pyx_t_11, __pyx_n_s_dtype, __pyx_t_1) < 0) __PYX_ERR(0, 73, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, __pyx_t_11); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 73, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; __pyx_t_4 = __pyx_t_1; __pyx_t_1 = 0; } else { __Pyx_INCREF(Py_None); __pyx_t_4 = Py_None; } __pyx_v_grad_local = __pyx_t_4; __pyx_t_4 = 0;
+074: cdef float[:, :, :, :] grad_local_view = grad_local
__pyx_t_12 = __Pyx_PyObject_to_MemoryviewSlice_dsdsdsds_float(__pyx_v_grad_local, PyBUF_WRITABLE); if (unlikely(!__pyx_t_12.memview)) __PYX_ERR(0, 74, __pyx_L1_error) __pyx_v_grad_local_view = __pyx_t_12; __pyx_t_12.memview = NULL; __pyx_t_12.data = NULL;
075:
076: cdef float[:] filtration
077:
+078: for b in range(batch_size): # iterate over batch
__pyx_t_9 = __pyx_v_batch_size; __pyx_t_8 = __pyx_t_9; for (__pyx_t_13 = 0; __pyx_t_13 < __pyx_t_8; __pyx_t_13+=1) { __pyx_v_b = __pyx_t_13;
+079: for c in range(num_channels): # iterate over channel
__pyx_t_14 = __pyx_v_num_channels; __pyx_t_15 = __pyx_t_14; for (__pyx_t_16 = 0; __pyx_t_16 < __pyx_t_15; __pyx_t_16+=1) { __pyx_v_c = __pyx_t_16;
+080: cub_cpx = gd.CubicalComplex(top_dimensional_cells=x[b, c]) # T-construction
__Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_gd); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 80, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_CubicalComplex); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 80, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 80, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_11 = PyInt_FromSsize_t(__pyx_v_b); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 80, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_11); __pyx_t_6 = PyInt_FromSsize_t(__pyx_v_c); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 80, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 80, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_GIVEREF(__pyx_t_11); if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_11)) __PYX_ERR(0, 80, __pyx_L1_error); __Pyx_GIVEREF(__pyx_t_6); if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_6)) __PYX_ERR(0, 80, __pyx_L1_error); __pyx_t_11 = 0; __pyx_t_6 = 0; __pyx_t_6 = __Pyx_PyObject_GetItem(__pyx_v_x, __pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 80, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_top_dimensional_cells, __pyx_t_6) < 0) __PYX_ERR(0, 80, __pyx_L1_error) __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_empty_tuple, __pyx_t_4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 80, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_XDECREF_SET(__pyx_v_cub_cpx, __pyx_t_6); __pyx_t_6 = 0;
+081: filtration = cub_cpx.all_cells().astype(dtype_float).flatten()
__pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_cub_cpx, __pyx_n_s_all_cells); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 81, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_11 = NULL; __pyx_t_17 = 0; #if CYTHON_UNPACK_METHODS if (likely(PyMethod_Check(__pyx_t_3))) { __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_3); if (likely(__pyx_t_11)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); __Pyx_INCREF(__pyx_t_11); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_3, function); __pyx_t_17 = 1; } } #endif { PyObject *__pyx_callargs[2] = {__pyx_t_11, NULL}; __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_17, 0+__pyx_t_17); __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 81, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; } __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_astype); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 81, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_dtype_float); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 81, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_11 = NULL; __pyx_t_17 = 0; #if CYTHON_UNPACK_METHODS if (likely(PyMethod_Check(__pyx_t_3))) { __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_3); if (likely(__pyx_t_11)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); __Pyx_INCREF(__pyx_t_11); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_3, function); __pyx_t_17 = 1; } } #endif { PyObject *__pyx_callargs[2] = {__pyx_t_11, __pyx_t_1}; __pyx_t_4 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_17, 1+__pyx_t_17); __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 81, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; } __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_flatten); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 81, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_4 = NULL; __pyx_t_17 = 0; #if CYTHON_UNPACK_METHODS if (likely(PyMethod_Check(__pyx_t_3))) { __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3); if (likely(__pyx_t_4)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); __Pyx_INCREF(__pyx_t_4); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_3, function); __pyx_t_17 = 1; } } #endif { PyObject *__pyx_callargs[2] = {__pyx_t_4, NULL}; __pyx_t_6 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_17, 0+__pyx_t_17); __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 81, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; } __pyx_t_18 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_t_6, PyBUF_WRITABLE); if (unlikely(!__pyx_t_18.memview)) __PYX_ERR(0, 81, __pyx_L1_error) __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; __PYX_XCLEAR_MEMVIEW(&__pyx_v_filtration, 1); __pyx_v_filtration = __pyx_t_18; __pyx_t_18.memview = NULL; __pyx_t_18.data = NULL;
+082: for cell in range(self.num_cells): # iterate over all cells in cubical complex
__pyx_t_19 = __pyx_v_self->num_cells; __pyx_t_20 = __pyx_t_19; for (__pyx_t_21 = 0; __pyx_t_21 < __pyx_t_20; __pyx_t_21+=1) { __pyx_v_cell = __pyx_t_21;
+083: filt = filtration[cell]
__pyx_t_22 = __pyx_v_cell; __pyx_v_filt = (*((float *) ( /* dim=0 */ (__pyx_v_filtration.data + __pyx_t_22 * __pyx_v_filtration.strides[0]) )));
+084: if filt > self.t_max:
__pyx_t_23 = (__pyx_v_filt > __pyx_v_self->t_max); if (__pyx_t_23) { /* … */ }
+085: continue
goto __pyx_L9_continue;
+086: dim = self.dimension[cell]
__pyx_t_22 = __pyx_v_cell; __pyx_v_dim = (*((float const *) ( /* dim=0 */ (__pyx_v_self->dimension.data + __pyx_t_22 * __pyx_v_self->dimension.strides[0]) )));
087:
+088: for i in range(self.steps):
__pyx_t_24 = __pyx_v_self->steps; __pyx_t_25 = __pyx_t_24; for (__pyx_t_26 = 0; __pyx_t_26 < __pyx_t_25; __pyx_t_26+=1) { __pyx_v_i = __pyx_t_26;
+089: t = self.tseq[i]
__pyx_t_22 = __pyx_v_i; __pyx_v_t = (*((float *) ( /* dim=0 */ (__pyx_v_self->tseq.data + __pyx_t_22 * __pyx_v_self->tseq.strides[0]) )));
+090: sig = (-1.)**dim
__pyx_v_sig = pow(-1., ((double)__pyx_v_dim));
+091: ecc_view[b, c, i] += sig * (sigmoid(t-filt, self.lam))
__pyx_t_27 = __pyx_f_11ecc_sigmoid_sigmoid((__pyx_v_t - __pyx_v_filt), __pyx_v_self->lam); if (unlikely(__pyx_t_27 == ((float)-1.0))) __PYX_ERR(0, 91, __pyx_L1_error)
__pyx_t_22 = __pyx_v_b;
__pyx_t_28 = __pyx_v_c;
__pyx_t_29 = __pyx_v_i;
*((float *) ( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_ecc_view.data + __pyx_t_22 * __pyx_v_ecc_view.strides[0]) ) + __pyx_t_28 * __pyx_v_ecc_view.strides[1]) ) + __pyx_t_29 * __pyx_v_ecc_view.strides[2]) )) += (__pyx_v_sig * __pyx_t_27);
}
092:
093: # calculation of gradient only for inputs that require gradient
+094: if backprop:
if (__pyx_v_backprop) { /* … */ } __pyx_L9_continue:; } } }
+095: if filt < self.lower_bound: # skip bc. gradient is 0 for simplices with filtration value under lower bound
__pyx_t_23 = (__pyx_v_filt < __pyx_v_self->lower_bound); if (__pyx_t_23) { /* … */ }
+096: continue
goto __pyx_L9_continue;
097: # square
+098: if dim == 2:
__pyx_t_23 = (__pyx_v_dim == 2.0); if (__pyx_t_23) { /* … */ goto __pyx_L16; }
+099: pix = self._sq2pix(cell) # index of the corresponding pixel in flattened original image
__pyx_t_24 = __pyx_f_11ecc_sigmoid_14SigEccBackbone__sq2pix(__pyx_v_self, __pyx_v_cell); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 99, __pyx_L1_error)
__pyx_v_pix = __pyx_t_24;
+100: for i in range(self.steps):
__pyx_t_24 = __pyx_v_self->steps; __pyx_t_25 = __pyx_t_24; for (__pyx_t_26 = 0; __pyx_t_26 < __pyx_t_25; __pyx_t_26+=1) { __pyx_v_i = __pyx_t_26;
+101: t = self.tseq[i]
__pyx_t_29 = __pyx_v_i; __pyx_v_t = (*((float *) ( /* dim=0 */ (__pyx_v_self->tseq.data + __pyx_t_29 * __pyx_v_self->tseq.strides[0]) )));
+102: grad_local_view[b, c, pix, i] -= self.lam * sigmoid(t-filt, self.lam) * (1 - sigmoid(t-filt, self.lam))
__pyx_t_27 = __pyx_f_11ecc_sigmoid_sigmoid((__pyx_v_t - __pyx_v_filt), __pyx_v_self->lam); if (unlikely(__pyx_t_27 == ((float)-1.0))) __PYX_ERR(0, 102, __pyx_L1_error) __pyx_t_30 = __pyx_f_11ecc_sigmoid_sigmoid((__pyx_v_t - __pyx_v_filt), __pyx_v_self->lam); if (unlikely(__pyx_t_30 == ((float)-1.0))) __PYX_ERR(0, 102, __pyx_L1_error) __pyx_t_29 = __pyx_v_b; __pyx_t_28 = __pyx_v_c; __pyx_t_22 = __pyx_v_pix; __pyx_t_31 = __pyx_v_i; *((float *) ( /* dim=3 */ (( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_grad_local_view.data + __pyx_t_29 * __pyx_v_grad_local_view.strides[0]) ) + __pyx_t_28 * __pyx_v_grad_local_view.strides[1]) ) + __pyx_t_22 * __pyx_v_grad_local_view.strides[2]) ) + __pyx_t_31 * __pyx_v_grad_local_view.strides[3]) )) -= ((__pyx_v_self->lam * __pyx_t_27) * (1.0 - __pyx_t_30)); }
103:
104: # edge
+105: elif dim == 1:
__pyx_t_23 = (__pyx_v_dim == 1.0); if (__pyx_t_23) { /* … */ goto __pyx_L16; }
+106: neighbor_sq = self._find_neighbor_sq(cell, dim, &num_neighbors) # neighbor_sq points at a C array containing index of neighbor squares
__pyx_t_32 = __pyx_f_11ecc_sigmoid_14SigEccBackbone__find_neighbor_sq(__pyx_v_self, __pyx_v_cell, __pyx_v_dim, (&__pyx_v_num_neighbors)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 106, __pyx_L1_error)
__pyx_v_neighbor_sq = __pyx_t_32;
+107: if num_neighbors == 1: # there is 1 neighbor square
__pyx_t_23 = (__pyx_v_num_neighbors == 1); if (__pyx_t_23) { /* … */ goto __pyx_L19; }
+108: pix = self._sq2pix(neighbor_sq[0])
__pyx_t_24 = __pyx_f_11ecc_sigmoid_14SigEccBackbone__sq2pix(__pyx_v_self, (__pyx_v_neighbor_sq[0])); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 108, __pyx_L1_error)
__pyx_v_pix = __pyx_t_24;
+109: for i in range(self.steps):
__pyx_t_24 = __pyx_v_self->steps; __pyx_t_25 = __pyx_t_24; for (__pyx_t_26 = 0; __pyx_t_26 < __pyx_t_25; __pyx_t_26+=1) { __pyx_v_i = __pyx_t_26;
+110: t = self.tseq[i]
__pyx_t_31 = __pyx_v_i; __pyx_v_t = (*((float *) ( /* dim=0 */ (__pyx_v_self->tseq.data + __pyx_t_31 * __pyx_v_self->tseq.strides[0]) )));
+111: grad_local_view[b, c, pix, i] += self.lam * sigmoid(t-filt, self.lam) * (1 - sigmoid(t-filt, self.lam))
__pyx_t_30 = __pyx_f_11ecc_sigmoid_sigmoid((__pyx_v_t - __pyx_v_filt), __pyx_v_self->lam); if (unlikely(__pyx_t_30 == ((float)-1.0))) __PYX_ERR(0, 111, __pyx_L1_error) __pyx_t_27 = __pyx_f_11ecc_sigmoid_sigmoid((__pyx_v_t - __pyx_v_filt), __pyx_v_self->lam); if (unlikely(__pyx_t_27 == ((float)-1.0))) __PYX_ERR(0, 111, __pyx_L1_error) __pyx_t_31 = __pyx_v_b; __pyx_t_22 = __pyx_v_c; __pyx_t_28 = __pyx_v_pix; __pyx_t_29 = __pyx_v_i; *((float *) ( /* dim=3 */ (( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_grad_local_view.data + __pyx_t_31 * __pyx_v_grad_local_view.strides[0]) ) + __pyx_t_22 * __pyx_v_grad_local_view.strides[1]) ) + __pyx_t_28 * __pyx_v_grad_local_view.strides[2]) ) + __pyx_t_29 * __pyx_v_grad_local_view.strides[3]) )) += ((__pyx_v_self->lam * __pyx_t_30) * (1.0 - __pyx_t_27)); }
112: else: # there are 2 neighbor squares
+113: for i in range(2):
/*else*/ { for (__pyx_t_24 = 0; __pyx_t_24 < 2; __pyx_t_24+=1) { __pyx_v_i = __pyx_t_24;
+114: sq_filt[i] = filtration[neighbor_sq[i]] # filtration value of neighbor squares
__pyx_t_29 = (__pyx_v_neighbor_sq[__pyx_v_i]); (__pyx_v_sq_filt[__pyx_v_i]) = (*((float *) ( /* dim=0 */ (__pyx_v_filtration.data + __pyx_t_29 * __pyx_v_filtration.strides[0]) ))); }
115:
+116: if sq_filt[0] > sq_filt[1]:
__pyx_t_23 = ((__pyx_v_sq_filt[0]) > (__pyx_v_sq_filt[1])); if (__pyx_t_23) { /* … */ goto __pyx_L24; }
+117: pix = self._sq2pix(neighbor_sq[1])
__pyx_t_24 = __pyx_f_11ecc_sigmoid_14SigEccBackbone__sq2pix(__pyx_v_self, (__pyx_v_neighbor_sq[1])); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 117, __pyx_L1_error)
__pyx_v_pix = __pyx_t_24;
+118: for i in range(self.steps):
__pyx_t_24 = __pyx_v_self->steps; __pyx_t_25 = __pyx_t_24; for (__pyx_t_26 = 0; __pyx_t_26 < __pyx_t_25; __pyx_t_26+=1) { __pyx_v_i = __pyx_t_26;
+119: t = self.tseq[i]
__pyx_t_29 = __pyx_v_i; __pyx_v_t = (*((float *) ( /* dim=0 */ (__pyx_v_self->tseq.data + __pyx_t_29 * __pyx_v_self->tseq.strides[0]) )));
+120: grad_local_view[b, c, pix, i] += self.lam * sigmoid(t-filt, self.lam) * (1 - sigmoid(t-filt, self.lam))
__pyx_t_27 = __pyx_f_11ecc_sigmoid_sigmoid((__pyx_v_t - __pyx_v_filt), __pyx_v_self->lam); if (unlikely(__pyx_t_27 == ((float)-1.0))) __PYX_ERR(0, 120, __pyx_L1_error) __pyx_t_30 = __pyx_f_11ecc_sigmoid_sigmoid((__pyx_v_t - __pyx_v_filt), __pyx_v_self->lam); if (unlikely(__pyx_t_30 == ((float)-1.0))) __PYX_ERR(0, 120, __pyx_L1_error) __pyx_t_29 = __pyx_v_b; __pyx_t_28 = __pyx_v_c; __pyx_t_22 = __pyx_v_pix; __pyx_t_31 = __pyx_v_i; *((float *) ( /* dim=3 */ (( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_grad_local_view.data + __pyx_t_29 * __pyx_v_grad_local_view.strides[0]) ) + __pyx_t_28 * __pyx_v_grad_local_view.strides[1]) ) + __pyx_t_22 * __pyx_v_grad_local_view.strides[2]) ) + __pyx_t_31 * __pyx_v_grad_local_view.strides[3]) )) += ((__pyx_v_self->lam * __pyx_t_27) * (1.0 - __pyx_t_30)); }
+121: elif sq_filt[0] < sq_filt[1]:
__pyx_t_23 = ((__pyx_v_sq_filt[0]) < (__pyx_v_sq_filt[1])); if (__pyx_t_23) { /* … */ goto __pyx_L24; }
+122: pix = self._sq2pix(neighbor_sq[0])
__pyx_t_24 = __pyx_f_11ecc_sigmoid_14SigEccBackbone__sq2pix(__pyx_v_self, (__pyx_v_neighbor_sq[0])); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 122, __pyx_L1_error)
__pyx_v_pix = __pyx_t_24;
+123: for i in range(self.steps):
__pyx_t_24 = __pyx_v_self->steps; __pyx_t_25 = __pyx_t_24; for (__pyx_t_26 = 0; __pyx_t_26 < __pyx_t_25; __pyx_t_26+=1) { __pyx_v_i = __pyx_t_26;
+124: t = self.tseq[i]
__pyx_t_31 = __pyx_v_i; __pyx_v_t = (*((float *) ( /* dim=0 */ (__pyx_v_self->tseq.data + __pyx_t_31 * __pyx_v_self->tseq.strides[0]) )));
+125: grad_local_view[b, c, pix, i] += self.lam * sigmoid(t-filt, self.lam) * (1 - sigmoid(t-filt, self.lam))
__pyx_t_30 = __pyx_f_11ecc_sigmoid_sigmoid((__pyx_v_t - __pyx_v_filt), __pyx_v_self->lam); if (unlikely(__pyx_t_30 == ((float)-1.0))) __PYX_ERR(0, 125, __pyx_L1_error) __pyx_t_27 = __pyx_f_11ecc_sigmoid_sigmoid((__pyx_v_t - __pyx_v_filt), __pyx_v_self->lam); if (unlikely(__pyx_t_27 == ((float)-1.0))) __PYX_ERR(0, 125, __pyx_L1_error) __pyx_t_31 = __pyx_v_b; __pyx_t_22 = __pyx_v_c; __pyx_t_28 = __pyx_v_pix; __pyx_t_29 = __pyx_v_i; *((float *) ( /* dim=3 */ (( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_grad_local_view.data + __pyx_t_31 * __pyx_v_grad_local_view.strides[0]) ) + __pyx_t_22 * __pyx_v_grad_local_view.strides[1]) ) + __pyx_t_28 * __pyx_v_grad_local_view.strides[2]) ) + __pyx_t_29 * __pyx_v_grad_local_view.strides[3]) )) += ((__pyx_v_self->lam * __pyx_t_30) * (1.0 - __pyx_t_27)); }
126: else: # split gradient when the neighboring squares have the same filtration value
+127: for i in range(2):
/*else*/ { for (__pyx_t_24 = 0; __pyx_t_24 < 2; __pyx_t_24+=1) { __pyx_v_i = __pyx_t_24;
+128: pix = self._sq2pix(neighbor_sq[i])
__pyx_t_25 = __pyx_f_11ecc_sigmoid_14SigEccBackbone__sq2pix(__pyx_v_self, (__pyx_v_neighbor_sq[__pyx_v_i])); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 128, __pyx_L1_error)
__pyx_v_pix = __pyx_t_25;
+129: for i in range(self.steps):
__pyx_t_25 = __pyx_v_self->steps; __pyx_t_26 = __pyx_t_25; for (__pyx_t_33 = 0; __pyx_t_33 < __pyx_t_26; __pyx_t_33+=1) { __pyx_v_i = __pyx_t_33;
+130: t = self.tseq[i]
__pyx_t_29 = __pyx_v_i; __pyx_v_t = (*((float *) ( /* dim=0 */ (__pyx_v_self->tseq.data + __pyx_t_29 * __pyx_v_self->tseq.strides[0]) )));
+131: grad_local_view[b, c, pix, i] += 0.5 * self.lam * sigmoid(t-filt, self.lam) * (1 - sigmoid(t-filt, self.lam))
__pyx_t_27 = __pyx_f_11ecc_sigmoid_sigmoid((__pyx_v_t - __pyx_v_filt), __pyx_v_self->lam); if (unlikely(__pyx_t_27 == ((float)-1.0))) __PYX_ERR(0, 131, __pyx_L1_error) __pyx_t_30 = __pyx_f_11ecc_sigmoid_sigmoid((__pyx_v_t - __pyx_v_filt), __pyx_v_self->lam); if (unlikely(__pyx_t_30 == ((float)-1.0))) __PYX_ERR(0, 131, __pyx_L1_error) __pyx_t_29 = __pyx_v_b; __pyx_t_28 = __pyx_v_c; __pyx_t_22 = __pyx_v_pix; __pyx_t_31 = __pyx_v_i; *((float *) ( /* dim=3 */ (( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_grad_local_view.data + __pyx_t_29 * __pyx_v_grad_local_view.strides[0]) ) + __pyx_t_28 * __pyx_v_grad_local_view.strides[1]) ) + __pyx_t_22 * __pyx_v_grad_local_view.strides[2]) ) + __pyx_t_31 * __pyx_v_grad_local_view.strides[3]) )) += (((0.5 * __pyx_v_self->lam) * __pyx_t_27) * (1.0 - __pyx_t_30)); } } } __pyx_L24:; } __pyx_L19:;
+132: free(neighbor_sq)
free(__pyx_v_neighbor_sq);
133: # vertex
134: else:
+135: neighbor_sq = self._find_neighbor_sq(cell, dim, &num_neighbors) # neighbor_sq points at a C array containing index of neighbor squares
/*else*/ {
__pyx_t_32 = __pyx_f_11ecc_sigmoid_14SigEccBackbone__find_neighbor_sq(__pyx_v_self, __pyx_v_cell, __pyx_v_dim, (&__pyx_v_num_neighbors)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 135, __pyx_L1_error)
__pyx_v_neighbor_sq = __pyx_t_32;
+136: if num_neighbors == 1: # there is 1 neighbor square
switch (__pyx_v_num_neighbors) { case 1: /* … */ break; case 2:
+137: pix = self._sq2pix(neighbor_sq[0])
__pyx_t_24 = __pyx_f_11ecc_sigmoid_14SigEccBackbone__sq2pix(__pyx_v_self, (__pyx_v_neighbor_sq[0])); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 137, __pyx_L1_error)
__pyx_v_pix = __pyx_t_24;
+138: for i in range(self.steps):
__pyx_t_24 = __pyx_v_self->steps; __pyx_t_25 = __pyx_t_24; for (__pyx_t_26 = 0; __pyx_t_26 < __pyx_t_25; __pyx_t_26+=1) { __pyx_v_i = __pyx_t_26;
+139: t = self.tseq[i]
__pyx_t_31 = __pyx_v_i; __pyx_v_t = (*((float *) ( /* dim=0 */ (__pyx_v_self->tseq.data + __pyx_t_31 * __pyx_v_self->tseq.strides[0]) )));
+140: grad_local_view[b, c, pix, i] -= self.lam * sigmoid(t-filt, self.lam) * (1 - sigmoid(t-filt, self.lam))
__pyx_t_30 = __pyx_f_11ecc_sigmoid_sigmoid((__pyx_v_t - __pyx_v_filt), __pyx_v_self->lam); if (unlikely(__pyx_t_30 == ((float)-1.0))) __PYX_ERR(0, 140, __pyx_L1_error) __pyx_t_27 = __pyx_f_11ecc_sigmoid_sigmoid((__pyx_v_t - __pyx_v_filt), __pyx_v_self->lam); if (unlikely(__pyx_t_27 == ((float)-1.0))) __PYX_ERR(0, 140, __pyx_L1_error) __pyx_t_31 = __pyx_v_b; __pyx_t_22 = __pyx_v_c; __pyx_t_28 = __pyx_v_pix; __pyx_t_29 = __pyx_v_i; *((float *) ( /* dim=3 */ (( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_grad_local_view.data + __pyx_t_31 * __pyx_v_grad_local_view.strides[0]) ) + __pyx_t_22 * __pyx_v_grad_local_view.strides[1]) ) + __pyx_t_28 * __pyx_v_grad_local_view.strides[2]) ) + __pyx_t_29 * __pyx_v_grad_local_view.strides[3]) )) -= ((__pyx_v_self->lam * __pyx_t_30) * (1.0 - __pyx_t_27)); }
+141: elif num_neighbors == 2: # there are 2 neighbor squares
break; default:
+142: for i in range(2):
for (__pyx_t_24 = 0; __pyx_t_24 < 2; __pyx_t_24+=1) { __pyx_v_i = __pyx_t_24;
+143: sq_filt[i] = filtration[neighbor_sq[i]] # filtration value of neighbor squares
__pyx_t_29 = (__pyx_v_neighbor_sq[__pyx_v_i]); (__pyx_v_sq_filt[__pyx_v_i]) = (*((float *) ( /* dim=0 */ (__pyx_v_filtration.data + __pyx_t_29 * __pyx_v_filtration.strides[0]) ))); }
144:
+145: if sq_filt[0] > sq_filt[1]:
__pyx_t_23 = ((__pyx_v_sq_filt[0]) > (__pyx_v_sq_filt[1])); if (__pyx_t_23) { /* … */ goto __pyx_L37; }
+146: pix = self._sq2pix(neighbor_sq[1])
__pyx_t_24 = __pyx_f_11ecc_sigmoid_14SigEccBackbone__sq2pix(__pyx_v_self, (__pyx_v_neighbor_sq[1])); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 146, __pyx_L1_error)
__pyx_v_pix = __pyx_t_24;
+147: for i in range(self.steps):
__pyx_t_24 = __pyx_v_self->steps; __pyx_t_25 = __pyx_t_24; for (__pyx_t_26 = 0; __pyx_t_26 < __pyx_t_25; __pyx_t_26+=1) { __pyx_v_i = __pyx_t_26;
+148: t = self.tseq[i]
__pyx_t_29 = __pyx_v_i; __pyx_v_t = (*((float *) ( /* dim=0 */ (__pyx_v_self->tseq.data + __pyx_t_29 * __pyx_v_self->tseq.strides[0]) )));
+149: grad_local_view[b, c, pix, i] -= self.lam * sigmoid(t-filt, self.lam) * (1 - sigmoid(t-filt, self.lam))
__pyx_t_27 = __pyx_f_11ecc_sigmoid_sigmoid((__pyx_v_t - __pyx_v_filt), __pyx_v_self->lam); if (unlikely(__pyx_t_27 == ((float)-1.0))) __PYX_ERR(0, 149, __pyx_L1_error) __pyx_t_30 = __pyx_f_11ecc_sigmoid_sigmoid((__pyx_v_t - __pyx_v_filt), __pyx_v_self->lam); if (unlikely(__pyx_t_30 == ((float)-1.0))) __PYX_ERR(0, 149, __pyx_L1_error) __pyx_t_29 = __pyx_v_b; __pyx_t_28 = __pyx_v_c; __pyx_t_22 = __pyx_v_pix; __pyx_t_31 = __pyx_v_i; *((float *) ( /* dim=3 */ (( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_grad_local_view.data + __pyx_t_29 * __pyx_v_grad_local_view.strides[0]) ) + __pyx_t_28 * __pyx_v_grad_local_view.strides[1]) ) + __pyx_t_22 * __pyx_v_grad_local_view.strides[2]) ) + __pyx_t_31 * __pyx_v_grad_local_view.strides[3]) )) -= ((__pyx_v_self->lam * __pyx_t_27) * (1.0 - __pyx_t_30)); }
+150: elif sq_filt[0] < sq_filt[1]:
__pyx_t_23 = ((__pyx_v_sq_filt[0]) < (__pyx_v_sq_filt[1])); if (__pyx_t_23) { /* … */ goto __pyx_L37; }
+151: pix = self._sq2pix(neighbor_sq[0])
__pyx_t_24 = __pyx_f_11ecc_sigmoid_14SigEccBackbone__sq2pix(__pyx_v_self, (__pyx_v_neighbor_sq[0])); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 151, __pyx_L1_error)
__pyx_v_pix = __pyx_t_24;
+152: for i in range(self.steps):
__pyx_t_24 = __pyx_v_self->steps; __pyx_t_25 = __pyx_t_24; for (__pyx_t_26 = 0; __pyx_t_26 < __pyx_t_25; __pyx_t_26+=1) { __pyx_v_i = __pyx_t_26;
+153: t = self.tseq[i]
__pyx_t_31 = __pyx_v_i; __pyx_v_t = (*((float *) ( /* dim=0 */ (__pyx_v_self->tseq.data + __pyx_t_31 * __pyx_v_self->tseq.strides[0]) )));
+154: grad_local_view[b, c, pix, i] -= self.lam * sigmoid(t-filt, self.lam) * (1 - sigmoid(t-filt, self.lam))
__pyx_t_30 = __pyx_f_11ecc_sigmoid_sigmoid((__pyx_v_t - __pyx_v_filt), __pyx_v_self->lam); if (unlikely(__pyx_t_30 == ((float)-1.0))) __PYX_ERR(0, 154, __pyx_L1_error) __pyx_t_27 = __pyx_f_11ecc_sigmoid_sigmoid((__pyx_v_t - __pyx_v_filt), __pyx_v_self->lam); if (unlikely(__pyx_t_27 == ((float)-1.0))) __PYX_ERR(0, 154, __pyx_L1_error) __pyx_t_31 = __pyx_v_b; __pyx_t_22 = __pyx_v_c; __pyx_t_28 = __pyx_v_pix; __pyx_t_29 = __pyx_v_i; *((float *) ( /* dim=3 */ (( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_grad_local_view.data + __pyx_t_31 * __pyx_v_grad_local_view.strides[0]) ) + __pyx_t_22 * __pyx_v_grad_local_view.strides[1]) ) + __pyx_t_28 * __pyx_v_grad_local_view.strides[2]) ) + __pyx_t_29 * __pyx_v_grad_local_view.strides[3]) )) -= ((__pyx_v_self->lam * __pyx_t_30) * (1.0 - __pyx_t_27)); }
155: else: # split gradient when the neighboring squares have the same filtration value
+156: for i in range(2):
/*else*/ { for (__pyx_t_24 = 0; __pyx_t_24 < 2; __pyx_t_24+=1) { __pyx_v_i = __pyx_t_24;
+157: pix = self._sq2pix(neighbor_sq[i])
__pyx_t_25 = __pyx_f_11ecc_sigmoid_14SigEccBackbone__sq2pix(__pyx_v_self, (__pyx_v_neighbor_sq[__pyx_v_i])); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 157, __pyx_L1_error)
__pyx_v_pix = __pyx_t_25;
+158: for i in range(self.steps):
__pyx_t_25 = __pyx_v_self->steps; __pyx_t_26 = __pyx_t_25; for (__pyx_t_33 = 0; __pyx_t_33 < __pyx_t_26; __pyx_t_33+=1) { __pyx_v_i = __pyx_t_33;
+159: t = self.tseq[i]
__pyx_t_29 = __pyx_v_i; __pyx_v_t = (*((float *) ( /* dim=0 */ (__pyx_v_self->tseq.data + __pyx_t_29 * __pyx_v_self->tseq.strides[0]) )));
+160: grad_local_view[b, c, pix, i] -= 0.5 * self.lam * sigmoid(t-filt, self.lam) * (1 - sigmoid(t-filt, self.lam))
__pyx_t_27 = __pyx_f_11ecc_sigmoid_sigmoid((__pyx_v_t - __pyx_v_filt), __pyx_v_self->lam); if (unlikely(__pyx_t_27 == ((float)-1.0))) __PYX_ERR(0, 160, __pyx_L1_error) __pyx_t_30 = __pyx_f_11ecc_sigmoid_sigmoid((__pyx_v_t - __pyx_v_filt), __pyx_v_self->lam); if (unlikely(__pyx_t_30 == ((float)-1.0))) __PYX_ERR(0, 160, __pyx_L1_error) __pyx_t_29 = __pyx_v_b; __pyx_t_28 = __pyx_v_c; __pyx_t_22 = __pyx_v_pix; __pyx_t_31 = __pyx_v_i; *((float *) ( /* dim=3 */ (( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_grad_local_view.data + __pyx_t_29 * __pyx_v_grad_local_view.strides[0]) ) + __pyx_t_28 * __pyx_v_grad_local_view.strides[1]) ) + __pyx_t_22 * __pyx_v_grad_local_view.strides[2]) ) + __pyx_t_31 * __pyx_v_grad_local_view.strides[3]) )) -= (((0.5 * __pyx_v_self->lam) * __pyx_t_27) * (1.0 - __pyx_t_30)); } } } __pyx_L37:;
161: else: # there are 4 neighbor squares
+162: for i in range(4):
for (__pyx_t_24 = 0; __pyx_t_24 < 4; __pyx_t_24+=1) { __pyx_v_i = __pyx_t_24;
+163: sq_filt[i] = filtration[neighbor_sq[i]] # filtration value of neighbor squares
__pyx_t_31 = (__pyx_v_neighbor_sq[__pyx_v_i]); (__pyx_v_sq_filt[__pyx_v_i]) = (*((float *) ( /* dim=0 */ (__pyx_v_filtration.data + __pyx_t_31 * __pyx_v_filtration.strides[0]) ))); }
164:
+165: sq = self._find_min_sq(sq_filt, neighbor_sq, 4, &num_min)
__pyx_t_32 = __pyx_f_11ecc_sigmoid_14SigEccBackbone__find_min_sq(__pyx_v_self, __pyx_v_sq_filt, __pyx_v_neighbor_sq, 4, (&__pyx_v_num_min)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 165, __pyx_L1_error)
__pyx_v_sq = __pyx_t_32;
+166: for i in range(num_min):
__pyx_t_24 = __pyx_v_num_min; __pyx_t_25 = __pyx_t_24; for (__pyx_t_26 = 0; __pyx_t_26 < __pyx_t_25; __pyx_t_26+=1) { __pyx_v_i = __pyx_t_26;
+167: pix = self._sq2pix(sq[i])
__pyx_t_33 = __pyx_f_11ecc_sigmoid_14SigEccBackbone__sq2pix(__pyx_v_self, (__pyx_v_sq[__pyx_v_i])); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 167, __pyx_L1_error)
__pyx_v_pix = __pyx_t_33;
+168: for i in range(self.steps):
__pyx_t_33 = __pyx_v_self->steps; __pyx_t_34 = __pyx_t_33; for (__pyx_t_35 = 0; __pyx_t_35 < __pyx_t_34; __pyx_t_35+=1) { __pyx_v_i = __pyx_t_35;
+169: t = self.tseq[i]
__pyx_t_31 = __pyx_v_i; __pyx_v_t = (*((float *) ( /* dim=0 */ (__pyx_v_self->tseq.data + __pyx_t_31 * __pyx_v_self->tseq.strides[0]) )));
+170: grad_local_view[b, c, pix, i] -= 1./num_min * self.lam * sigmoid(t-filt, self.lam) * (1 - sigmoid(t-filt, self.lam))
__pyx_t_30 = __pyx_f_11ecc_sigmoid_sigmoid((__pyx_v_t - __pyx_v_filt), __pyx_v_self->lam); if (unlikely(__pyx_t_30 == ((float)-1.0))) __PYX_ERR(0, 170, __pyx_L1_error) __pyx_t_27 = __pyx_f_11ecc_sigmoid_sigmoid((__pyx_v_t - __pyx_v_filt), __pyx_v_self->lam); if (unlikely(__pyx_t_27 == ((float)-1.0))) __PYX_ERR(0, 170, __pyx_L1_error) __pyx_t_31 = __pyx_v_b; __pyx_t_22 = __pyx_v_c; __pyx_t_28 = __pyx_v_pix; __pyx_t_29 = __pyx_v_i; *((float *) ( /* dim=3 */ (( /* dim=2 */ (( /* dim=1 */ (( /* dim=0 */ (__pyx_v_grad_local_view.data + __pyx_t_31 * __pyx_v_grad_local_view.strides[0]) ) + __pyx_t_22 * __pyx_v_grad_local_view.strides[1]) ) + __pyx_t_28 * __pyx_v_grad_local_view.strides[2]) ) + __pyx_t_29 * __pyx_v_grad_local_view.strides[3]) )) -= ((((1. / ((double)__pyx_v_num_min)) * __pyx_v_self->lam) * __pyx_t_30) * (1.0 - __pyx_t_27)); } }
+171: free(sq)
free(__pyx_v_sq); break; }
+172: free(neighbor_sq)
free(__pyx_v_neighbor_sq); } __pyx_L16:;
173: # cumsum
174: # for i in range(self.steps - 1):
175: # ecc_view[b, c, i+1] += ecc_view[b, c, i]
+176: return ecc, grad_local
__Pyx_XDECREF(__pyx_r); __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 176, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_INCREF(__pyx_v_ecc); __Pyx_GIVEREF(__pyx_v_ecc); if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_v_ecc)) __PYX_ERR(0, 176, __pyx_L1_error); __Pyx_INCREF(__pyx_v_grad_local); __Pyx_GIVEREF(__pyx_v_grad_local); if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_v_grad_local)) __PYX_ERR(0, 176, __pyx_L1_error); __pyx_r = __pyx_t_6; __pyx_t_6 = 0; goto __pyx_L0;
177:
178: @cython.cdivision(True) # turn off checking for division by zero
+179: cdef inline Py_ssize_t _sq2pix(self, Py_ssize_t sq):
static CYTHON_INLINE Py_ssize_t __pyx_f_11ecc_sigmoid_14SigEccBackbone__sq2pix(struct __pyx_obj_11ecc_sigmoid_SigEccBackbone *__pyx_v_self, Py_ssize_t __pyx_v_sq) { Py_ssize_t __pyx_r; /* … */ /* function exit code */ __pyx_L0:; return __pyx_r; }
180: """Given the index of a square, this function returns the index of the corresponding pixel.
181: Used for T-constructed cubical complexes.
182:
183: Args:
184: vtx (Py_ssize_t): Index of square.
185:
186: Returns:
187: Py_ssize_t: Index of corresponding pixel.
188: """
+189: return (sq // (2*self.grid_w))*self.w + (sq % self.grid_w)/2
__pyx_r = (((__pyx_v_sq / (2 * __pyx_v_self->grid_w)) * __pyx_v_self->w) + ((__pyx_v_sq % __pyx_v_self->grid_w) / 2)); goto __pyx_L0;
190:
191: @cython.cdivision(True) # turn off checking for division by zero
+192: cdef inline Py_ssize_t* _find_neighbor_sq(self, Py_ssize_t cell, float dim, Py_ssize_t* num_neighbors):
static CYTHON_INLINE Py_ssize_t *__pyx_f_11ecc_sigmoid_14SigEccBackbone__find_neighbor_sq(struct __pyx_obj_11ecc_sigmoid_SigEccBackbone *__pyx_v_self, Py_ssize_t __pyx_v_cell, float __pyx_v_dim, Py_ssize_t *__pyx_v_num_neighbors) { Py_ssize_t __pyx_v_row_num; Py_ssize_t *__pyx_v_neighbor_sq; Py_ssize_t __pyx_v_col_num; Py_ssize_t *__pyx_r; /* … */ /* function exit code */ __pyx_L0:; return __pyx_r; }
193: """Returns the indices of a cell's neighboring squares.
194: Used for T-constructed cubical complexes.
195: Do not use for cells that are already squares.
196:
197: Args:
198: cell (Py_ssize_t): Index of cell.
199: dim (float): Dimension of cell.
200: num_neighors(Py_ssize_t pointer): Number of neighboring squares of cell.
201:
202: Returns:
203: Py_ssize_t pointer: C array containing index of neighboring squares.
204: """
205: cdef Py_ssize_t row_num
+206: cdef Py_ssize_t *neighbor_sq = <Py_ssize_t *> malloc(<Py_ssize_t>(dim -2) * -2 * sizeof(Py_ssize_t)) # assign size 2 array for edges and size 4 array for vertices
__pyx_v_neighbor_sq = ((Py_ssize_t *)malloc(((((Py_ssize_t)(__pyx_v_dim - 2.0)) * -2L) * (sizeof(Py_ssize_t)))));
207: # edge
+208: if dim == 1:
__pyx_t_1 = (__pyx_v_dim == 1.0); if (__pyx_t_1) { /* … */ goto __pyx_L3; }
+209: row_num = cell // self.grid_w
__pyx_v_row_num = (__pyx_v_cell / __pyx_v_self->grid_w);
210: # even row
+211: if row_num % 2 == 0:
__pyx_t_1 = ((__pyx_v_row_num % 2) == 0); if (__pyx_t_1) { /* … */ goto __pyx_L4; }
+212: if row_num == 0: # top row
__pyx_t_1 = (__pyx_v_row_num == 0); if (__pyx_t_1) { /* … */ goto __pyx_L5; }
+213: neighbor_sq[0] = cell + self.grid_w
(__pyx_v_neighbor_sq[0]) = (__pyx_v_cell + __pyx_v_self->grid_w);
+214: num_neighbors[0] = 1
(__pyx_v_num_neighbors[0]) = 1;
+215: elif row_num == self.grid_h - 1: # bottom row
__pyx_t_1 = (__pyx_v_row_num == (__pyx_v_self->grid_h - 1)); if (__pyx_t_1) { /* … */ goto __pyx_L5; }
+216: neighbor_sq[0] = cell - self.grid_w
(__pyx_v_neighbor_sq[0]) = (__pyx_v_cell - __pyx_v_self->grid_w);
+217: num_neighbors[0] = 1
(__pyx_v_num_neighbors[0]) = 1;
218: else:
+219: neighbor_sq[:] = [cell-self.grid_w, cell+self.grid_w]
/*else*/ { __pyx_t_2[0] = (__pyx_v_cell - __pyx_v_self->grid_w); __pyx_t_2[1] = (__pyx_v_cell + __pyx_v_self->grid_w); memcpy(&(__pyx_v_neighbor_sq[0]), __pyx_t_2, sizeof(__pyx_v_neighbor_sq[0]) * (2));
+220: num_neighbors[0] = 2
(__pyx_v_num_neighbors[0]) = 2; } __pyx_L5:;
221: # odd row
222: else:
+223: col_num = cell % self.grid_w
/*else*/ { __pyx_v_col_num = (__pyx_v_cell % __pyx_v_self->grid_w);
+224: if col_num == 0: # left-most column
__pyx_t_1 = (__pyx_v_col_num == 0); if (__pyx_t_1) { /* … */ goto __pyx_L6; }
+225: neighbor_sq[0] = cell + 1
(__pyx_v_neighbor_sq[0]) = (__pyx_v_cell + 1);
+226: num_neighbors[0] = 1
(__pyx_v_num_neighbors[0]) = 1;
+227: elif col_num == self.grid_w - 1: # right-most column
__pyx_t_1 = (__pyx_v_col_num == (__pyx_v_self->grid_w - 1)); if (__pyx_t_1) { /* … */ goto __pyx_L6; }
+228: neighbor_sq[0] = cell - 1
(__pyx_v_neighbor_sq[0]) = (__pyx_v_cell - 1);
+229: num_neighbors[0] = 1
(__pyx_v_num_neighbors[0]) = 1;
230: else:
+231: neighbor_sq[:] = [cell-1, cell+1]
/*else*/ { __pyx_t_3[0] = (__pyx_v_cell - 1); __pyx_t_3[1] = (__pyx_v_cell + 1); memcpy(&(__pyx_v_neighbor_sq[0]), __pyx_t_3, sizeof(__pyx_v_neighbor_sq[0]) * (2));
+232: num_neighbors[0] = 2
(__pyx_v_num_neighbors[0]) = 2; } __pyx_L6:; } __pyx_L4:;
233: # vertex
234: else:
+235: row_num = cell // self.grid_w
/*else*/ { __pyx_v_row_num = (__pyx_v_cell / __pyx_v_self->grid_w);
+236: col_num = cell % self.grid_w
__pyx_v_col_num = (__pyx_v_cell % __pyx_v_self->grid_w);
237: # top row
+238: if row_num == 0:
__pyx_t_1 = (__pyx_v_row_num == 0); if (__pyx_t_1) { /* … */ goto __pyx_L7; }
+239: if cell == 0: # top left corner
__pyx_t_1 = (__pyx_v_cell == 0); if (__pyx_t_1) { /* … */ goto __pyx_L8; }
+240: neighbor_sq[0] = cell + self.grid_w + 1
(__pyx_v_neighbor_sq[0]) = ((__pyx_v_cell + __pyx_v_self->grid_w) + 1);
+241: num_neighbors[0] = 1
(__pyx_v_num_neighbors[0]) = 1;
+242: elif cell == self.grid_w - 1: # top right corner
__pyx_t_1 = (__pyx_v_cell == (__pyx_v_self->grid_w - 1)); if (__pyx_t_1) { /* … */ goto __pyx_L8; }
+243: neighbor_sq[0] = cell + self.grid_w - 1
(__pyx_v_neighbor_sq[0]) = ((__pyx_v_cell + __pyx_v_self->grid_w) - 1);
+244: num_neighbors[0] = 1
(__pyx_v_num_neighbors[0]) = 1;
245: else:
+246: neighbor_sq[:2] = [cell+self.grid_w-1, cell+self.grid_w+1]
/*else*/ { __pyx_t_4[0] = ((__pyx_v_cell + __pyx_v_self->grid_w) - 1); __pyx_t_4[1] = ((__pyx_v_cell + __pyx_v_self->grid_w) + 1); memcpy(&(__pyx_v_neighbor_sq[0]), __pyx_t_4, sizeof(__pyx_v_neighbor_sq[0]) * (2));
+247: num_neighbors[0] = 2
(__pyx_v_num_neighbors[0]) = 2; } __pyx_L8:;
248: # bottom row
+249: elif row_num == self.grid_h - 1:
__pyx_t_1 = (__pyx_v_row_num == (__pyx_v_self->grid_h - 1)); if (__pyx_t_1) { /* … */ goto __pyx_L7; }
+250: if cell == self.grid_w * (self.grid_h-1): # bottom left corner
__pyx_t_1 = (__pyx_v_cell == (__pyx_v_self->grid_w * (__pyx_v_self->grid_h - 1))); if (__pyx_t_1) { /* … */ goto __pyx_L9; }
+251: neighbor_sq[0] = cell - self.grid_w + 1
(__pyx_v_neighbor_sq[0]) = ((__pyx_v_cell - __pyx_v_self->grid_w) + 1);
+252: num_neighbors[0] = 1
(__pyx_v_num_neighbors[0]) = 1;
+253: elif cell == self.grid_w*self.grid_h - 1: # bottom right corner
__pyx_t_1 = (__pyx_v_cell == ((__pyx_v_self->grid_w * __pyx_v_self->grid_h) - 1)); if (__pyx_t_1) { /* … */ goto __pyx_L9; }
+254: neighbor_sq[0] = cell - self.grid_w - 1
(__pyx_v_neighbor_sq[0]) = ((__pyx_v_cell - __pyx_v_self->grid_w) - 1);
+255: num_neighbors[0] = 1
(__pyx_v_num_neighbors[0]) = 1;
256: else:
+257: neighbor_sq[:2] = [cell-self.grid_w-1, cell-self.grid_w+1]
/*else*/ { __pyx_t_5[0] = ((__pyx_v_cell - __pyx_v_self->grid_w) - 1); __pyx_t_5[1] = ((__pyx_v_cell - __pyx_v_self->grid_w) + 1); memcpy(&(__pyx_v_neighbor_sq[0]), __pyx_t_5, sizeof(__pyx_v_neighbor_sq[0]) * (2));
+258: num_neighbors[0] = 2
(__pyx_v_num_neighbors[0]) = 2; } __pyx_L9:;
259: # left-most column
+260: elif col_num == 0:
__pyx_t_1 = (__pyx_v_col_num == 0); if (__pyx_t_1) { /* … */ goto __pyx_L7; }
+261: neighbor_sq[:2] = [cell+1-self.grid_w, cell+1+self.grid_w]
__pyx_t_6[0] = ((__pyx_v_cell + 1) - __pyx_v_self->grid_w); __pyx_t_6[1] = ((__pyx_v_cell + 1) + __pyx_v_self->grid_w); memcpy(&(__pyx_v_neighbor_sq[0]), __pyx_t_6, sizeof(__pyx_v_neighbor_sq[0]) * (2));
+262: num_neighbors[0] = 2
(__pyx_v_num_neighbors[0]) = 2;
263: # right-most column
+264: elif col_num == self.grid_w - 1:
__pyx_t_1 = (__pyx_v_col_num == (__pyx_v_self->grid_w - 1)); if (__pyx_t_1) { /* … */ goto __pyx_L7; }
+265: neighbor_sq[:2] = [cell-1-self.grid_w, cell-1+self.grid_w]
__pyx_t_7[0] = ((__pyx_v_cell - 1) - __pyx_v_self->grid_w); __pyx_t_7[1] = ((__pyx_v_cell - 1) + __pyx_v_self->grid_w); memcpy(&(__pyx_v_neighbor_sq[0]), __pyx_t_7, sizeof(__pyx_v_neighbor_sq[0]) * (2));
+266: num_neighbors[0] = 2
(__pyx_v_num_neighbors[0]) = 2;
267: else:
+268: neighbor_sq[:] = [cell-self.grid_w-1, cell-self.grid_w+1, cell+self.grid_w-1, cell+self.grid_w+1]
/*else*/ { __pyx_t_8[0] = ((__pyx_v_cell - __pyx_v_self->grid_w) - 1); __pyx_t_8[1] = ((__pyx_v_cell - __pyx_v_self->grid_w) + 1); __pyx_t_8[2] = ((__pyx_v_cell + __pyx_v_self->grid_w) - 1); __pyx_t_8[3] = ((__pyx_v_cell + __pyx_v_self->grid_w) + 1); memcpy(&(__pyx_v_neighbor_sq[0]), __pyx_t_8, sizeof(__pyx_v_neighbor_sq[0]) * (4));
+269: num_neighbors[0] = 4
(__pyx_v_num_neighbors[0]) = 4; } __pyx_L7:; } __pyx_L3:;
+270: return neighbor_sq
__pyx_r = __pyx_v_neighbor_sq; goto __pyx_L0;
271:
+272: cdef inline Py_ssize_t* _find_min_sq(self, float *sq_filt, Py_ssize_t *neighbor_sq, Py_ssize_t arr_size, Py_ssize_t *num_min):
static CYTHON_INLINE Py_ssize_t *__pyx_f_11ecc_sigmoid_14SigEccBackbone__find_min_sq(CYTHON_UNUSED struct __pyx_obj_11ecc_sigmoid_SigEccBackbone *__pyx_v_self, float *__pyx_v_sq_filt, Py_ssize_t *__pyx_v_neighbor_sq, Py_ssize_t __pyx_v_arr_size, Py_ssize_t *__pyx_v_num_min) { float __pyx_v_min_val; Py_ssize_t __pyx_v_j; Py_ssize_t __pyx_v_count; Py_ssize_t __pyx_v_i; Py_ssize_t *__pyx_v_sq; Py_ssize_t *__pyx_r; /* … */ /* function exit code */ __pyx_L0:; return __pyx_r; }
273: """
274:
275: """
+276: cdef float min_val = sq_filt[0]
__pyx_v_min_val = (__pyx_v_sq_filt[0]);
+277: cdef Py_ssize_t j = 0, count = 0
__pyx_v_j = 0; __pyx_v_count = 0;
278:
279: # find minimum filtration value
+280: for i in range(1, arr_size):
__pyx_t_1 = __pyx_v_arr_size; __pyx_t_2 = __pyx_t_1; for (__pyx_t_3 = 1; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { __pyx_v_i = __pyx_t_3;
+281: if sq_filt[i] < min_val:
__pyx_t_4 = ((__pyx_v_sq_filt[__pyx_v_i]) < __pyx_v_min_val); if (__pyx_t_4) { /* … */ } }
+282: min_val = sq_filt[i]
__pyx_v_min_val = (__pyx_v_sq_filt[__pyx_v_i]);
283:
284: # count how many times min_val occurs
+285: for i in range(arr_size):
__pyx_t_1 = __pyx_v_arr_size; __pyx_t_2 = __pyx_t_1; for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { __pyx_v_i = __pyx_t_3;
+286: if sq_filt[i] == min_val:
__pyx_t_4 = ((__pyx_v_sq_filt[__pyx_v_i]) == __pyx_v_min_val); if (__pyx_t_4) { /* … */ } }
+287: count += 1
__pyx_v_count = (__pyx_v_count + 1);
288:
+289: cdef Py_ssize_t *sq = <Py_ssize_t *> malloc(count * sizeof(Py_ssize_t))
__pyx_v_sq = ((Py_ssize_t *)malloc((__pyx_v_count * (sizeof(Py_ssize_t)))));
290:
291: # store the index of squares that have minimum filtration value
+292: for i in range(arr_size):
__pyx_t_1 = __pyx_v_arr_size; __pyx_t_2 = __pyx_t_1; for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { __pyx_v_i = __pyx_t_3;
+293: if sq_filt[i] == min_val:
__pyx_t_4 = ((__pyx_v_sq_filt[__pyx_v_i]) == __pyx_v_min_val); if (__pyx_t_4) { /* … */ } }
+294: sq[j] = neighbor_sq[i]
(__pyx_v_sq[__pyx_v_j]) = (__pyx_v_neighbor_sq[__pyx_v_i]);
+295: j += 1
__pyx_v_j = (__pyx_v_j + 1);
296:
297: # number of min_val occurences
+298: num_min[0] = count
(__pyx_v_num_min[0]) = __pyx_v_count;
+299: return sq
__pyx_r = __pyx_v_sq; goto __pyx_L0;
300:
+301: cdef _set_dimension(self):
static PyObject *__pyx_f_11ecc_sigmoid_14SigEccBackbone__set_dimension(struct __pyx_obj_11ecc_sigmoid_SigEccBackbone *__pyx_v_self) { PyObject *__pyx_v_dimension = NULL; Py_ssize_t __pyx_8genexpr1__pyx_v_i; Py_ssize_t __pyx_8genexpr2__pyx_v_i; PyObject *__pyx_r = NULL; /* … */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_AddTraceback("ecc_sigmoid.SigEccBackbone._set_dimension", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XDECREF(__pyx_v_dimension); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; }
302: """
303: Sets dimension for all cubes in the cubical complex. Dimensions of vertice, edge, square are 0, 1, 2 respectively. Even rows consist of (vertice, edge, vertice, edge, ..., vertice, edge, vertice) and odd rows consist of (edge, square, edge, square, ..., edge, square, edge).
304:
305: Returns:
306: _type_: _description_
307: """
+308: dimension = np.zeros([self.grid_h, self.grid_w], dtype=dtype_float)
__Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 308, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_zeros); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 308, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_self->grid_h); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 308, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_self->grid_w); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 308, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = PyList_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 308, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_GIVEREF(__pyx_t_1); if (__Pyx_PyList_SET_ITEM(__pyx_t_4, 0, __pyx_t_1)) __PYX_ERR(0, 308, __pyx_L1_error); __Pyx_GIVEREF(__pyx_t_3); if (__Pyx_PyList_SET_ITEM(__pyx_t_4, 1, __pyx_t_3)) __PYX_ERR(0, 308, __pyx_L1_error); __pyx_t_1 = 0; __pyx_t_3 = 0; __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 308, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_GIVEREF(__pyx_t_4); if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4)) __PYX_ERR(0, 308, __pyx_L1_error); __pyx_t_4 = 0; __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 308, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_dtype_float); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 308, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_1) < 0) __PYX_ERR(0, 308, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 308, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_v_dimension = __pyx_t_1; __pyx_t_1 = 0;
+309: dimension[[i for i in range(self.grid_h) if i % 2 == 1], :] += 1
{ /* enter inner scope */ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 309, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_5 = __pyx_v_self->grid_h; __pyx_t_6 = __pyx_t_5; for (__pyx_t_7 = 0; __pyx_t_7 < __pyx_t_6; __pyx_t_7+=1) { __pyx_8genexpr1__pyx_v_i = __pyx_t_7; __pyx_t_8 = (__Pyx_mod_Py_ssize_t(__pyx_8genexpr1__pyx_v_i, 2) == 1); if (__pyx_t_8) { __pyx_t_4 = PyInt_FromSsize_t(__pyx_8genexpr1__pyx_v_i); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 309, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) __PYX_ERR(0, 309, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; } } } /* exit inner scope */ __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 309, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_GIVEREF(__pyx_t_1); if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1)) __PYX_ERR(0, 309, __pyx_L1_error); __Pyx_INCREF(__pyx_slice__5); __Pyx_GIVEREF(__pyx_slice__5); if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_slice__5)) __PYX_ERR(0, 309, __pyx_L1_error); __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_dimension, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 309, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = __Pyx_PyInt_AddObjC(__pyx_t_1, __pyx_int_1, 1, 1, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 309, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; if (unlikely((PyObject_SetItem(__pyx_v_dimension, __pyx_t_4, __pyx_t_3) < 0))) __PYX_ERR(0, 309, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+310: dimension[:, [i for i in range(self.grid_w) if i % 2 == 1]] += 1
{ /* enter inner scope */ __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 310, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = __pyx_v_self->grid_w; __pyx_t_6 = __pyx_t_5; for (__pyx_t_7 = 0; __pyx_t_7 < __pyx_t_6; __pyx_t_7+=1) { __pyx_8genexpr2__pyx_v_i = __pyx_t_7; __pyx_t_8 = (__Pyx_mod_Py_ssize_t(__pyx_8genexpr2__pyx_v_i, 2) == 1); if (__pyx_t_8) { __pyx_t_3 = PyInt_FromSsize_t(__pyx_8genexpr2__pyx_v_i); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 310, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); if (unlikely(__Pyx_ListComp_Append(__pyx_t_4, (PyObject*)__pyx_t_3))) __PYX_ERR(0, 310, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; } } } /* exit inner scope */ __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 310, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_INCREF(__pyx_slice__5); __Pyx_GIVEREF(__pyx_slice__5); if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_slice__5)) __PYX_ERR(0, 310, __pyx_L1_error); __Pyx_GIVEREF(__pyx_t_4); if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_4)) __PYX_ERR(0, 310, __pyx_L1_error); __pyx_t_4 = 0; __pyx_t_4 = __Pyx_PyObject_GetItem(__pyx_v_dimension, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 310, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_1 = __Pyx_PyInt_AddObjC(__pyx_t_4, __pyx_int_1, 1, 1, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 310, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; if (unlikely((PyObject_SetItem(__pyx_v_dimension, __pyx_t_3, __pyx_t_1) < 0))) __PYX_ERR(0, 310, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+311: dimension.setflags(write=False)
__pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_dimension, __pyx_n_s_setflags); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 311, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 311, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_write, Py_False) < 0) __PYX_ERR(0, 311, __pyx_L1_error) __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 311, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+312: return dimension.flatten()
__Pyx_XDECREF(__pyx_r); __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_dimension, __pyx_n_s_flatten); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 312, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = NULL; __pyx_t_9 = 0; #if CYTHON_UNPACK_METHODS if (likely(PyMethod_Check(__pyx_t_1))) { __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1); if (likely(__pyx_t_3)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1); __Pyx_INCREF(__pyx_t_3); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_1, function); __pyx_t_9 = 1; } } #endif { PyObject *__pyx_callargs[2] = {__pyx_t_3, NULL}; __pyx_t_4 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_9, 0+__pyx_t_9); __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 312, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; } __pyx_r = __pyx_t_4; __pyx_t_4 = 0; goto __pyx_L0;
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327: # V-construction
328: # @cython.boundscheck(False) # turn off bounds-checking for entire function
329: # @cython.wraparound(False) # turn off negative index wrapping for entire function
330: # @cython.cdivision(True) # turn off checking for division by zero
331: # @cython.initializedcheck(False) # turn off initialization check
332: # def cal_ecc_vtx(self, object x, bint backprop):
333: # """_summary_
334:
335: # Args:
336: # x (anything convertible to a numpy.ndarray): Array of shape [B, C, H, W].
337: # backprop (bint): Whether or not the input requires gradient calculation.
338:
339: # Returns:
340: # _type_: _description_
341: # """
342: # cdef Py_ssize_t batch_size, num_channels, b, c, cell, t, pix, i, num_max
343: # cdef float filt, dim
344: # cdef Py_ssize_t *neighbor_vtx
345: # cdef Py_ssize_t *vtx
346: # cdef float[4] vtx_filt
347:
348: # batch_size, num_channels, h, w = x.shape
349:
350: # ecc = np.zeros((batch_size, num_channels, self.steps), dtype=dtype_float)
351: # cdef float[:, :, :] ecc_view = ecc
352:
353: # tseq = np.linspace(self.t_min, self.t_max, self.steps, dtype=dtype_float)
354: # cdef float[:] tseq_view = tseq
355:
356: # grad_local = np.zeros((batch_size, num_channels, h*w, self.steps), dtype=dtype_float) if backprop else None
357: # cdef float[:, :, :, :] grad_local_view = grad_local
358:
359: # cdef float[:] filtration
360:
361: # for b in range(batch_size): # iterate over batch
362: # for c in range(num_channels): # iterate over channel
363: # cub_cpx = gd.CubicalComplex(vertices=x[b, c]) # V-contruction
364: # filtration = cub_cpx.all_cells().astype(dtype_float).flatten()
365: # for cell in range(self.num_cells): # iterate over all cells in cubical complex
366: # filt = filtration[cell]
367: # if filt > self.t_max:
368: # continue
369: # dim = self.dimension[cell]
370:
371: # for i in range(self.steps):
372: # ecc_view[b, c, i] += (-1)**dim * sigmoid(tseq[i] - filt, self.lamda)
373:
374: # # calculation of gradient only for inputs that require gradient
375: # if backprop:
376: # if filt < self.lower_bound: # skip bc. gradient is 0 for simplices with filtration value under lower bound
377: # continue
378: # # vertex
379: # if dim == 0:
380: # pix = self._vtx2pix(cell) # index of the corresponding pixel in flattened original image
381: # for i in range(self.steps):
382: # grad_local_view[b, c, pix, i] += sigmoid_grad(tseq[i] - filt, self.lamda)
383: # # edge
384: # elif dim == 1:
385: # neighbor_vtx = self._find_neighbor_vtx(cell, dim) # neighbor_vtx points at a C array containing index of 2 neighbor vertices
386: # for i in range(2):
387: # vtx_filt[i] = filtration[neighbor_vtx[i]] # filtration value of neighbor vertices
388:
389: # if vtx_filt[0] > vtx_filt[1]:
390: # pix = self._vtx2pix(neighbor_vtx[0])
391: # grad_local_view[b, c, pix, t] -= 1.
392: # elif vtx_filt[0] < vtx_filt[1]:
393: # pix = self._vtx2pix(neighbor_vtx[1])
394: # grad_local_view[b, c, pix, t] -= 1.
395: # else: # split gradient when the neighboring vertices have the same filtration value
396: # for i in range(2):
397: # pix = self._vtx2pix(neighbor_vtx[i])
398: # grad_local_view[b, c, pix, t] -= 0.5
399: # free(neighbor_vtx)
400: # # square
401: # else:
402: # neighbor_vtx = self._find_neighbor_vtx(cell, dim) # neighbor_vtx points at a C array containing index of 4 neighbor vertices
403: # for i in range(4):
404: # vtx_filt[i] = filtration[neighbor_vtx[i]] # filtration value of neighbor vertices
405:
406: # vtx = self._find_max_vtx(vtx_filt, neighbor_vtx, 4, &num_max) # vtx points at a C array containing index of vertices that contribute to constructing the cell
407: # for i in range(num_max):
408: # pix = self._vtx2pix(vtx[i])
409: # grad_local_view[b, c, pix, t] += 1./num_max
410: # free(vtx)
411: # free(neighbor_vtx)
412: # # cumsum
413: # for i in range(self.steps - 1):
414: # ecc_view[b, c, i+1] += ecc_view[b, c, i]
415: # return ecc, grad_local
416:
417: # @cython.cdivision(True) # turn off checking for division by zero
418: # cdef inline Py_ssize_t _vtx2pix(self, Py_ssize_t vtx):
419: # """Given the index of a vertex, this function returns the index of the corresponding pixel.
420: # Used for V-constructed cubical complexes.
421:
422: # Args:
423: # vtx (Py_ssize_t): Index of vertex.
424:
425: # Returns:
426: # Py_ssize_t: Index of corresponding pixel.
427: # """
428: # return (vtx // (2*self.grid_w))*self.w + (vtx % self.grid_w)/2
429:
430: # @cython.cdivision(True) # turn off checking for division by zero
431: # cdef inline Py_ssize_t* _find_neighbor_vtx(self, Py_ssize_t cell, float dim):
432: # """Returns the indices of a cell's neighboring vertices.
433: # Used for V-constructed cubical complexes.
434: # Do not use for cells that are already vertices.
435:
436: # Args:
437: # cell (Py_ssize_t): Index of cell.
438: # dim (float): Dimension of cell.
439:
440: # Returns:
441: # Py_ssize_t pointer: C array containing index of neighboring squares.
442: # """
443: # cdef Py_ssize_t row_num
444: # cdef Py_ssize_t *neighbor_vtx = <Py_ssize_t *> malloc(<Py_ssize_t>dim * 2 * sizeof(Py_ssize_t)) # assign size 2 array for edges and size 4 array for squares
445: # # edge
446: # if dim == 1:
447: # row_num = cell // self.grid_w
448: # if row_num % 2 == 0: # even row
449: # neighbor_vtx[:] = [cell-1, cell+1]
450: # else: # odd row
451: # neighbor_vtx[:] = [cell-self.grid_w, cell+self.grid_w]
452: # # square
453: # else:
454: # neighbor_vtx[:] = [cell-self.grid_w-1, cell-self.grid_w+1, cell+self.grid_w-1, cell+self.grid_w+1]
455: # return neighbor_vtx
456:
457: # cdef inline Py_ssize_t* _find_max_vtx(self, float *vtx_filt, Py_ssize_t *neighbor_vtx, Py_ssize_t arr_size, Py_ssize_t *num_max):
458: # """
459:
460: # """
461: # cdef float max_val = vtx_filt[0]
462: # cdef Py_ssize_t j = 0, count = 0
463:
464: # # find maximum filtration value
465: # for i in range(1, arr_size):
466: # if vtx_filt[i] > max_val:
467: # max_val = vtx_filt[i]
468:
469: # # count how many times max_val occurs
470: # for i in range(arr_size):
471: # if vtx_filt[i] == max_val:
472: # count += 1
473:
474: # cdef Py_ssize_t *vtx = <Py_ssize_t *> malloc(count * sizeof(Py_ssize_t))
475:
476: # # store the index of vertices that have maximum filtration value
477: # for i in range(arr_size):
478: # if vtx_filt[i] == max_val:
479: # vtx[j] = neighbor_vtx[i]
480: # j += 1
481:
482: # # number of max_val occurences
483: # num_max[0] = count
484: # return vtx